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