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