1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.rules;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.config.property.ConfigurationService;
20 import org.kuali.rice.core.api.util.RiceKeyConstants;
21 import org.kuali.rice.coreservice.framework.parameter.ParameterConstants;
22 import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
23 import org.kuali.rice.kim.api.KimConstants;
24 import org.kuali.rice.kim.api.group.Group;
25 import org.kuali.rice.kim.api.group.GroupService;
26 import org.kuali.rice.kim.api.identity.Person;
27 import org.kuali.rice.kim.api.identity.PersonService;
28 import org.kuali.rice.kim.api.permission.PermissionService;
29 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
30 import org.kuali.rice.krad.bo.AdHocRoutePerson;
31 import org.kuali.rice.krad.bo.AdHocRouteWorkgroup;
32 import org.kuali.rice.krad.bo.DocumentHeader;
33 import org.kuali.rice.krad.bo.Note;
34 import org.kuali.rice.krad.document.Document;
35 import org.kuali.rice.krad.maintenance.MaintenanceDocument;
36 import org.kuali.rice.krad.document.TransactionalDocument;
37 import org.kuali.rice.krad.rules.rule.AddAdHocRoutePersonRule;
38 import org.kuali.rice.krad.rules.rule.AddAdHocRouteWorkgroupRule;
39 import org.kuali.rice.krad.rules.rule.AddNoteRule;
40 import org.kuali.rice.krad.rules.rule.ApproveDocumentRule;
41 import org.kuali.rice.krad.rules.rule.RouteDocumentRule;
42 import org.kuali.rice.krad.rules.rule.SaveDocumentRule;
43 import org.kuali.rice.krad.rules.rule.SendAdHocRequestsRule;
44 import org.kuali.rice.krad.rules.rule.event.ApproveDocumentEvent;
45 import org.kuali.rice.krad.service.DataDictionaryService;
46 import org.kuali.rice.krad.service.DictionaryValidationService;
47 import org.kuali.rice.krad.service.DocumentDictionaryService;
48 import org.kuali.rice.krad.service.KRADServiceLocator;
49 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
50 import org.kuali.rice.krad.util.GlobalVariables;
51 import org.kuali.rice.krad.util.KRADConstants;
52 import org.kuali.rice.krad.util.KRADPropertyConstants;
53 import org.kuali.rice.krad.util.KRADUtils;
54 import org.kuali.rice.krad.util.MessageMap;
55
56
57
58
59
60
61 public abstract class DocumentRuleBase implements SaveDocumentRule, RouteDocumentRule, ApproveDocumentRule, AddNoteRule,
62 AddAdHocRoutePersonRule, AddAdHocRouteWorkgroupRule, SendAdHocRequestsRule {
63 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentRuleBase.class);
64
65 private static PersonService personService;
66 private static DictionaryValidationService dictionaryValidationService;
67 private static DocumentDictionaryService documentDictionaryService;
68 private static ConfigurationService kualiConfigurationService;
69 private static GroupService groupService;
70 private static PermissionService permissionService;
71 private static DataDictionaryService dataDictionaryService;
72
73
74 private int maxDictionaryValidationDepth = 100;
75
76
77
78
79
80
81
82 public boolean isDocumentOverviewValid(Document document) {
83
84 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
85 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_HEADER_PROPERTY_NAME);
86
87
88 getDictionaryValidationService().validateBusinessObject(document.getDocumentHeader());
89 validateSensitiveDataValue(KRADPropertyConstants.EXPLANATION, document.getDocumentHeader().getExplanation(),
90 getDataDictionaryService().getAttributeLabel(DocumentHeader.class, KRADPropertyConstants.EXPLANATION));
91
92
93 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_HEADER_PROPERTY_NAME);
94 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
95
96 return GlobalVariables.getMessageMap().hasNoErrors();
97 }
98
99
100
101
102
103
104
105
106
107
108 public boolean isDocumentAttributesValid(Document document, boolean validateRequired) {
109
110 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
111
112
113 getDictionaryValidationService().validateDocumentAndUpdatableReferencesRecursively(document,
114 getMaxDictionaryValidationDepth(), validateRequired);
115
116
117 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
118
119 return GlobalVariables.getMessageMap().hasNoErrors();
120 }
121
122
123
124
125
126
127
128
129
130
131
132
133 public boolean processSaveDocument(Document document) {
134 boolean isValid = true;
135 isValid = isDocumentOverviewValid(document);
136 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
137 getDictionaryValidationService().validateDocumentAndUpdatableReferencesRecursively(document,
138 getMaxDictionaryValidationDepth(), false);
139 getDictionaryValidationService().validateDefaultExistenceChecksForTransDoc((TransactionalDocument) document);
140 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.DOCUMENT_PROPERTY_NAME);
141 isValid &= GlobalVariables.getMessageMap().hasNoErrors();
142 isValid &= processCustomSaveDocumentBusinessRules(document);
143
144 return isValid;
145 }
146
147
148
149
150
151
152
153
154
155 protected boolean processCustomSaveDocumentBusinessRules(Document document) {
156 return true;
157 }
158
159
160
161
162
163
164
165
166
167
168 public boolean processRouteDocument(Document document) {
169 boolean isValid = true;
170
171 isValid = isDocumentAttributesValid(document, true);
172
173
174 if (isValid) {
175 isValid &= processCustomRouteDocumentBusinessRules(document);
176 }
177 return isValid;
178 }
179
180
181
182
183
184
185
186
187
188 protected boolean processCustomRouteDocumentBusinessRules(Document document) {
189 return true;
190 }
191
192
193
194
195
196
197
198
199
200
201 public boolean processApproveDocument(ApproveDocumentEvent approveEvent) {
202 boolean isValid = true;
203
204 isValid = processCustomApproveDocumentBusinessRules(approveEvent);
205
206 return isValid;
207 }
208
209
210
211
212
213
214
215
216
217 protected boolean processCustomApproveDocumentBusinessRules(ApproveDocumentEvent approveEvent) {
218 return true;
219 }
220
221
222
223
224
225 public boolean processAddNote(Document document, Note note) {
226 boolean isValid = true;
227
228 isValid &= isNoteValid(note);
229 isValid &= processCustomAddNoteBusinessRules(document, note);
230
231 return isValid;
232 }
233
234
235
236
237
238
239
240 public boolean isNoteValid(Note note) {
241
242 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.NEW_DOCUMENT_NOTE_PROPERTY_NAME);
243
244
245 getDictionaryValidationService().validateBusinessObject(note);
246
247 validateSensitiveDataValue(KRADConstants.NOTE_TEXT_PROPERTY_NAME, note.getNoteText(),
248 getDataDictionaryService().getAttributeLabel(Note.class, KRADConstants.NOTE_TEXT_PROPERTY_NAME));
249
250
251 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.NEW_DOCUMENT_NOTE_PROPERTY_NAME);
252
253 return GlobalVariables.getMessageMap().hasNoErrors();
254 }
255
256
257
258
259
260
261
262
263
264
265 protected boolean processCustomAddNoteBusinessRules(Document document, Note note) {
266 return true;
267 }
268
269
270
271
272
273 public boolean processAddAdHocRoutePerson(Document document, AdHocRoutePerson adHocRoutePerson) {
274 boolean isValid = true;
275
276 isValid &= isAddHocRoutePersonValid(document, adHocRoutePerson);
277
278 isValid &= processCustomAddAdHocRoutePersonBusinessRules(document, adHocRoutePerson);
279 return isValid;
280 }
281
282
283
284
285 public boolean processSendAdHocRequests(Document document) {
286 boolean isValid = true;
287
288 isValid &= isAdHocRouteRecipientsValid(document);
289 isValid &= processCustomSendAdHocRequests(document);
290
291 return isValid;
292 }
293
294 protected boolean processCustomSendAdHocRequests(Document document) {
295 return true;
296 }
297
298
299
300
301
302
303
304
305 protected boolean isAdHocRouteRecipientsValid(Document document) {
306 boolean isValid = true;
307 MessageMap errorMap = GlobalVariables.getMessageMap();
308
309 if (errorMap.getErrorPath().size() == 0) {
310
311 errorMap.addToErrorPath(KRADConstants.NEW_AD_HOC_ROUTE_PERSON_PROPERTY_NAME);
312 }
313
314 if ((document.getAdHocRoutePersons() == null || document.getAdHocRoutePersons().isEmpty()) && (document
315 .getAdHocRouteWorkgroups() == null || document.getAdHocRouteWorkgroups().isEmpty())) {
316
317 GlobalVariables.getMessageMap().putError(KRADPropertyConstants.ID, "error.adhoc.missing.recipients");
318 isValid = false;
319 }
320
321
322 errorMap.removeFromErrorPath(KRADConstants.NEW_AD_HOC_ROUTE_PERSON_PROPERTY_NAME);
323
324 return isValid;
325 }
326
327
328
329
330
331
332
333 public boolean isAddHocRoutePersonValid(Document document, AdHocRoutePerson person) {
334 MessageMap errorMap = GlobalVariables.getMessageMap();
335
336
337 if (errorMap.getErrorPath().size() == 0) {
338
339 errorMap.addToErrorPath(KRADConstants.NEW_AD_HOC_ROUTE_PERSON_PROPERTY_NAME);
340 }
341
342 if (StringUtils.isNotBlank(person.getId())) {
343 Person user = getPersonService().getPersonByPrincipalName(person.getId());
344
345 if (user == null) {
346 GlobalVariables.getMessageMap().putError(KRADPropertyConstants.ID,
347 RiceKeyConstants.ERROR_INVALID_ADHOC_PERSON_ID);
348 } else if (!getPermissionService().hasPermission(user.getPrincipalId(),
349 KimConstants.KIM_TYPE_DEFAULT_NAMESPACE, KimConstants.PermissionNames.LOG_IN, null)) {
350 GlobalVariables.getMessageMap().putError(KRADPropertyConstants.ID,
351 RiceKeyConstants.ERROR_INACTIVE_ADHOC_PERSON_ID);
352 } else {
353 Class docOrBoClass = null;
354 if (document instanceof MaintenanceDocument) {
355 docOrBoClass = ((MaintenanceDocument) document).getNewMaintainableObject().getDataObjectClass();
356 } else {
357 docOrBoClass = document.getClass();
358 }
359
360 if (!getDocumentDictionaryService().getDocumentAuthorizer(document).canReceiveAdHoc(document, user,
361 person.getActionRequested())) {
362 GlobalVariables.getMessageMap().putError(KRADPropertyConstants.ID,
363 RiceKeyConstants.ERROR_UNAUTHORIZED_ADHOC_PERSON_ID);
364 }
365 }
366 } else {
367 GlobalVariables.getMessageMap().putError(KRADPropertyConstants.ID,
368 RiceKeyConstants.ERROR_MISSING_ADHOC_PERSON_ID);
369 }
370
371
372 errorMap.removeFromErrorPath(KRADConstants.NEW_AD_HOC_ROUTE_PERSON_PROPERTY_NAME);
373
374 return GlobalVariables.getMessageMap().hasNoErrors();
375 }
376
377
378
379
380
381
382
383
384
385
386 protected boolean processCustomAddAdHocRoutePersonBusinessRules(Document document, AdHocRoutePerson person) {
387 return true;
388 }
389
390
391
392
393
394 public boolean processAddAdHocRouteWorkgroup(Document document, AdHocRouteWorkgroup adHocRouteWorkgroup) {
395 boolean isValid = true;
396
397 isValid &= isAddHocRouteWorkgroupValid(adHocRouteWorkgroup);
398
399 isValid &= processCustomAddAdHocRouteWorkgroupBusinessRules(document, adHocRouteWorkgroup);
400 return isValid;
401 }
402
403
404
405
406
407
408
409 public boolean isAddHocRouteWorkgroupValid(AdHocRouteWorkgroup workgroup) {
410 MessageMap errorMap = GlobalVariables.getMessageMap();
411
412
413 if (errorMap.getErrorPath().size() == 0) {
414
415 GlobalVariables.getMessageMap().addToErrorPath(KRADConstants.NEW_AD_HOC_ROUTE_WORKGROUP_PROPERTY_NAME);
416 }
417
418 if (workgroup.getRecipientName() != null && workgroup.getRecipientNamespaceCode() != null) {
419
420 try {
421 Group group = getGroupService().getGroupByNameAndNamespaceCode(workgroup.getRecipientNamespaceCode(),
422 workgroup.getRecipientName());
423 if (group == null || !group.isActive()) {
424 GlobalVariables.getMessageMap().putError(KRADPropertyConstants.ID,
425 RiceKeyConstants.ERROR_INVALID_ADHOC_WORKGROUP_ID);
426 }
427 } catch (Exception e) {
428 LOG.error("isAddHocRouteWorkgroupValid(AdHocRouteWorkgroup)", e);
429
430 GlobalVariables.getMessageMap().putError(KRADPropertyConstants.ID,
431 RiceKeyConstants.ERROR_INVALID_ADHOC_WORKGROUP_ID);
432 }
433 } else {
434 GlobalVariables.getMessageMap().putError(KRADPropertyConstants.ID,
435 RiceKeyConstants.ERROR_MISSING_ADHOC_WORKGROUP_ID);
436 }
437
438
439 GlobalVariables.getMessageMap().removeFromErrorPath(KRADConstants.NEW_AD_HOC_ROUTE_WORKGROUP_PROPERTY_NAME);
440
441 return GlobalVariables.getMessageMap().hasNoErrors();
442 }
443
444
445
446
447
448
449
450
451
452
453 protected boolean processCustomAddAdHocRouteWorkgroupBusinessRules(Document document,
454 AdHocRouteWorkgroup workgroup) {
455 return true;
456 }
457
458
459
460
461 public int getMaxDictionaryValidationDepth() {
462 return this.maxDictionaryValidationDepth;
463 }
464
465
466
467
468 public void setMaxDictionaryValidationDepth(int maxDictionaryValidationDepth) {
469 if (maxDictionaryValidationDepth < 0) {
470 LOG.error("Dictionary validation depth should be greater than or equal to 0. Value received was: "
471 + maxDictionaryValidationDepth);
472 throw new RuntimeException(
473 "Dictionary validation depth should be greater than or equal to 0. Value received was: "
474 + maxDictionaryValidationDepth);
475 }
476 this.maxDictionaryValidationDepth = maxDictionaryValidationDepth;
477 }
478
479 protected boolean validateSensitiveDataValue(String fieldName, String fieldValue, String fieldLabel) {
480 boolean dataValid = true;
481
482 if (fieldValue == null) {
483 return dataValid;
484 }
485
486 boolean patternFound = KRADUtils.containsSensitiveDataPatternMatch(fieldValue);
487 boolean warnForSensitiveData = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsBoolean(
488 KRADConstants.KNS_NAMESPACE, ParameterConstants.ALL_COMPONENT,
489 KRADConstants.SystemGroupParameterNames.SENSITIVE_DATA_PATTERNS_WARNING_IND);
490 if (patternFound && !warnForSensitiveData) {
491 dataValid = false;
492 GlobalVariables.getMessageMap().putError(fieldName,
493 RiceKeyConstants.ERROR_DOCUMENT_FIELD_CONTAINS_POSSIBLE_SENSITIVE_DATA, fieldLabel);
494 }
495
496 return dataValid;
497 }
498
499 protected DataDictionaryService getDataDictionaryService() {
500 if (dataDictionaryService == null) {
501 dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
502 }
503 return dataDictionaryService;
504 }
505
506 protected PersonService getPersonService() {
507 if (personService == null) {
508 personService = KimApiServiceLocator.getPersonService();
509 }
510 return personService;
511 }
512
513 public static GroupService getGroupService() {
514 if (groupService == null) {
515 groupService = KimApiServiceLocator.getGroupService();
516 }
517 return groupService;
518 }
519
520 public static PermissionService getPermissionService() {
521 if (permissionService == null) {
522 permissionService = KimApiServiceLocator.getPermissionService();
523 }
524 return permissionService;
525 }
526
527 protected DictionaryValidationService getDictionaryValidationService() {
528 if (dictionaryValidationService == null) {
529 dictionaryValidationService = KRADServiceLocatorWeb.getDictionaryValidationService();
530 }
531 return dictionaryValidationService;
532 }
533
534 protected ConfigurationService getKualiConfigurationService() {
535 if (kualiConfigurationService == null) {
536 kualiConfigurationService = KRADServiceLocator.getKualiConfigurationService();
537 }
538 return kualiConfigurationService;
539 }
540
541 protected static DocumentDictionaryService getDocumentDictionaryService() {
542 if (documentDictionaryService == null) {
543 documentDictionaryService = KRADServiceLocatorWeb.getDocumentDictionaryService();
544 }
545 return documentDictionaryService;
546 }
547
548 public static void setDocumentDictionaryService(DocumentDictionaryService documentDictionaryService) {
549 DocumentRuleBase.documentDictionaryService = documentDictionaryService;
550 }
551 }