1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.maintenance.rules;
17
18 import org.apache.commons.collections.CollectionUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.kuali.rice.core.api.CoreApiServiceLocator;
21 import org.kuali.rice.core.api.config.property.ConfigurationService;
22 import org.kuali.rice.core.api.datetime.DateTimeService;
23 import org.kuali.rice.core.api.mo.common.active.MutableInactivatable;
24 import org.kuali.rice.core.api.util.RiceKeyConstants;
25 import org.kuali.rice.core.web.format.Formatter;
26 import org.kuali.rice.kew.api.WorkflowDocument;
27 import org.kuali.rice.kim.api.identity.PersonService;
28 import org.kuali.rice.kim.api.role.RoleService;
29 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
30 import org.kuali.rice.kns.document.MaintenanceDocument;
31 import org.kuali.rice.kns.maintenance.Maintainable;
32 import org.kuali.rice.kns.rule.AddCollectionLineRule;
33 import org.kuali.rice.kns.rules.MaintenanceDocumentRule;
34 import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
35 import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
36 import org.kuali.rice.kns.service.DictionaryValidationService;
37 import org.kuali.rice.kns.service.KNSServiceLocator;
38 import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
39 import org.kuali.rice.krad.bo.BusinessObject;
40 import org.kuali.rice.krad.bo.GlobalBusinessObject;
41 import org.kuali.rice.krad.bo.PersistableBusinessObject;
42 import org.kuali.rice.krad.datadictionary.InactivationBlockingMetadata;
43 import org.kuali.rice.krad.document.Document;
44 import org.kuali.rice.krad.document.authorization.MaintenanceDocumentAuthorizer;
45 import org.kuali.rice.krad.exception.ValidationException;
46 import org.kuali.rice.krad.rule.event.ApproveDocumentEvent;
47 import org.kuali.rice.krad.rules.DocumentRuleBase;
48 import org.kuali.rice.krad.service.BusinessObjectDictionaryService;
49 import org.kuali.rice.krad.service.BusinessObjectService;
50 import org.kuali.rice.krad.service.DataDictionaryService;
51 import org.kuali.rice.krad.service.DataObjectMetaDataService;
52 import org.kuali.rice.krad.service.DocumentHelperService;
53 import org.kuali.rice.krad.service.InactivationBlockingDetectionService;
54 import org.kuali.rice.krad.service.KRADServiceLocator;
55 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
56 import org.kuali.rice.krad.service.PersistenceStructureService;
57 import org.kuali.rice.krad.util.ErrorMessage;
58 import org.kuali.rice.krad.util.ForeignKeyFieldsPopulationState;
59 import org.kuali.rice.krad.util.GlobalVariables;
60 import org.kuali.rice.krad.util.KRADConstants;
61 import org.kuali.rice.krad.util.KRADPropertyConstants;
62 import org.kuali.rice.krad.util.MessageMap;
63 import org.kuali.rice.krad.util.ObjectUtils;
64 import org.kuali.rice.krad.util.UrlFactory;
65 import org.kuali.rice.krad.workflow.service.WorkflowDocumentService;
66 import org.springframework.util.AutoPopulatingList;
67
68 import java.security.GeneralSecurityException;
69 import java.util.ArrayList;
70 import java.util.Collection;
71 import java.util.Iterator;
72 import java.util.List;
73 import java.util.Map;
74 import java.util.Properties;
75 import java.util.Set;
76
77
78
79
80
81
82 public class MaintenanceDocumentRuleBase extends DocumentRuleBase implements MaintenanceDocumentRule, AddCollectionLineRule {
83 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(MaintenanceDocumentRuleBase.class);
84
85
86
87 public static final String MAINTAINABLE_ERROR_PREFIX = KRADConstants.MAINTENANCE_NEW_MAINTAINABLE;
88 public static final String DOCUMENT_ERROR_PREFIX = "document.";
89 public static final String MAINTAINABLE_ERROR_PATH = DOCUMENT_ERROR_PREFIX + "newMaintainableObject";
90
91 protected PersistenceStructureService persistenceStructureService;
92 protected DataDictionaryService ddService;
93 protected DocumentHelperService documentHelperService;
94 protected BusinessObjectService boService;
95 protected DictionaryValidationService dictionaryValidationService;
96 protected ConfigurationService configService;
97 protected MaintenanceDocumentDictionaryService maintDocDictionaryService;
98 protected WorkflowDocumentService workflowDocumentService;
99 protected PersonService personService;
100 protected RoleService roleService;
101 protected DataObjectMetaDataService dataObjectMetaDataService;
102 protected BusinessObjectAuthorizationService businessObjectAuthorizationService;
103 protected BusinessObjectMetaDataService businessObjectMetaDataService;
104 protected BusinessObjectDictionaryService boDictionaryService;
105
106 private Object oldBo;
107 private Object newBo;
108 private Class boClass;
109
110 protected List priorErrorPath;
111
112
113
114
115 public MaintenanceDocumentRuleBase() {
116
117 priorErrorPath = new ArrayList();
118
119
120
121
122
123
124
125 try {
126 this.setPersistenceStructureService(KRADServiceLocator.getPersistenceStructureService());
127 this.setDdService(KRADServiceLocatorWeb.getDataDictionaryService());
128 this.setBusinessObjectMetaDataService(KNSServiceLocator.getBusinessObjectMetaDataService());
129 this.setBoService(KRADServiceLocator.getBusinessObjectService());
130 this.setBoDictionaryService(KRADServiceLocatorWeb.getBusinessObjectDictionaryService());
131 this.setDictionaryValidationService(KNSServiceLocator.getDictionaryValidationService());
132 this.setConfigService(KRADServiceLocator.getKualiConfigurationService());
133 this.setDocumentHelperService(KRADServiceLocatorWeb.getDocumentHelperService());
134 this.setMaintDocDictionaryService(KNSServiceLocator.getMaintenanceDocumentDictionaryService());
135 this.setWorkflowDocumentService(KRADServiceLocatorWeb.getWorkflowDocumentService());
136 this.setPersonService(KimApiServiceLocator.getPersonService());
137 this.setBusinessObjectAuthorizationService(KNSServiceLocator.getBusinessObjectAuthorizationService());
138 } catch (Exception ex) {
139
140 }
141 }
142
143
144
145
146 @Override
147 public boolean processSaveDocument(Document document) {
148
149 MaintenanceDocument maintenanceDocument = (MaintenanceDocument) document;
150
151
152
153 clearErrorPath();
154
155
156 setupBaseConvenienceObjects(maintenanceDocument);
157
158
159
160
161
162 if (!isDocumentValidForSave(maintenanceDocument)) {
163 resumeErrorPath();
164 return false;
165 }
166
167
168
169
170 processCustomSaveDocumentBusinessRules(maintenanceDocument);
171
172
173 resumeErrorPath();
174
175
176
177 return true;
178 }
179
180
181
182
183 @Override
184 public boolean processRouteDocument(Document document) {
185 LOG.info("processRouteDocument called");
186
187 MaintenanceDocument maintenanceDocument = (MaintenanceDocument) document;
188
189
190 MaintenanceDocumentAuthorizer documentAuthorizer =
191 (MaintenanceDocumentAuthorizer) getDocumentHelperService().getDocumentAuthorizer(document);
192
193
194
195 clearErrorPath();
196
197
198 setupBaseConvenienceObjects(maintenanceDocument);
199
200
201 processGlobalSaveDocumentBusinessRules(maintenanceDocument);
202
203
204
205 boolean success = true;
206
207 WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
208 if (workflowDocument.isInitiated() || workflowDocument.isSaved()) {
209 success &= documentAuthorizer
210 .canCreateOrMaintain((MaintenanceDocument) document, GlobalVariables.getUserSession().getPerson());
211 if (success == false) {
212 GlobalVariables.getMessageMap()
213 .putError(KRADConstants.DOCUMENT_ERRORS, RiceKeyConstants.AUTHORIZATION_ERROR_DOCUMENT,
214 new String[]{GlobalVariables.getUserSession().getPerson().getPrincipalName(),
215 "Create/Maintain",
216 this.getMaintDocDictionaryService().getDocumentTypeName(newBo.getClass())});
217 }
218 }
219
220 success &= processGlobalRouteDocumentBusinessRules(maintenanceDocument);
221
222
223
224
225 success &= processCustomRouteDocumentBusinessRules(maintenanceDocument);
226
227 success &= processInactivationBlockChecking(maintenanceDocument);
228
229
230
231 resumeErrorPath();
232
233 return success;
234 }
235
236
237
238
239
240
241
242 protected boolean isDocumentInactivatingBusinessObject(MaintenanceDocument maintenanceDocument) {
243 if (maintenanceDocument.isEdit()) {
244 Class boClass = maintenanceDocument.getNewMaintainableObject().getDataObjectClass();
245
246 if (boClass != null && MutableInactivatable.class.isAssignableFrom(boClass)) {
247 MutableInactivatable oldInactivateableBO = (MutableInactivatable) oldBo;
248 MutableInactivatable newInactivateableBO = (MutableInactivatable) newBo;
249
250 return oldInactivateableBO.isActive() && !newInactivateableBO.isActive();
251 }
252 }
253 return false;
254 }
255
256
257
258
259
260
261
262 protected boolean processInactivationBlockChecking(MaintenanceDocument maintenanceDocument) {
263 if (isDocumentInactivatingBusinessObject(maintenanceDocument)) {
264 Class boClass = maintenanceDocument.getNewMaintainableObject().getDataObjectClass();
265 Set<InactivationBlockingMetadata> inactivationBlockingMetadatas =
266 ddService.getAllInactivationBlockingDefinitions(boClass);
267
268 if (inactivationBlockingMetadatas != null) {
269 for (InactivationBlockingMetadata inactivationBlockingMetadata : inactivationBlockingMetadatas) {
270
271
272
273 if (!processInactivationBlockChecking(maintenanceDocument, inactivationBlockingMetadata)) {
274 return false;
275 }
276 }
277 }
278 }
279 return true;
280 }
281
282
283
284
285
286
287
288
289
290
291 protected boolean processInactivationBlockChecking(MaintenanceDocument maintenanceDocument,
292 InactivationBlockingMetadata inactivationBlockingMetadata) {
293 if (newBo instanceof PersistableBusinessObject) {
294 String inactivationBlockingDetectionServiceBeanName =
295 inactivationBlockingMetadata.getInactivationBlockingDetectionServiceBeanName();
296 if (StringUtils.isBlank(inactivationBlockingDetectionServiceBeanName)) {
297 inactivationBlockingDetectionServiceBeanName =
298 KRADServiceLocatorWeb.DEFAULT_INACTIVATION_BLOCKING_DETECTION_SERVICE;
299 }
300 InactivationBlockingDetectionService inactivationBlockingDetectionService = KRADServiceLocatorWeb
301 .getInactivationBlockingDetectionService(inactivationBlockingDetectionServiceBeanName);
302
303 boolean foundBlockingRecord = inactivationBlockingDetectionService
304 .hasABlockingRecord((PersistableBusinessObject) newBo, inactivationBlockingMetadata);
305
306 if (foundBlockingRecord) {
307 putInactivationBlockingErrorOnPage(maintenanceDocument, inactivationBlockingMetadata);
308 }
309
310 return !foundBlockingRecord;
311 }
312
313 return true;
314 }
315
316
317
318
319
320
321
322
323 protected void putInactivationBlockingErrorOnPage(MaintenanceDocument document,
324 InactivationBlockingMetadata inactivationBlockingMetadata) {
325 if (!persistenceStructureService.hasPrimaryKeyFieldValues(newBo)) {
326 throw new RuntimeException("Maintenance document did not have all primary key values filled in.");
327 }
328 Properties parameters = new Properties();
329 parameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE,
330 inactivationBlockingMetadata.getBlockedBusinessObjectClass().getName());
331 parameters
332 .put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.METHOD_DISPLAY_ALL_INACTIVATION_BLOCKERS);
333
334 List keys = new ArrayList();
335 if (getPersistenceStructureService().isPersistable(newBo.getClass())) {
336 keys = getPersistenceStructureService().listPrimaryKeyFieldNames(newBo.getClass());
337 }
338
339
340 String keyName = null;
341 for (Iterator iter = keys.iterator(); iter.hasNext(); ) {
342 keyName = (String) iter.next();
343
344 Object keyValue = null;
345 if (keyName != null) {
346 keyValue = ObjectUtils.getPropertyValue(newBo, keyName);
347 }
348
349 if (keyValue == null) {
350 keyValue = "";
351 } else if (keyValue instanceof java.sql.Date) {
352 if (Formatter.findFormatter(keyValue.getClass()) != null) {
353 Formatter formatter = Formatter.getFormatter(keyValue.getClass());
354 keyValue = (String) formatter.format(keyValue);
355 }
356 } else {
357 keyValue = keyValue.toString();
358 }
359
360
361 if (businessObjectAuthorizationService.attributeValueNeedsToBeEncryptedOnFormsAndLinks(
362 inactivationBlockingMetadata.getBlockedBusinessObjectClass(), keyName)) {
363 try {
364 keyValue = CoreApiServiceLocator.getEncryptionService().encrypt(keyValue);
365 } catch (GeneralSecurityException e) {
366 LOG.error("Exception while trying to encrypted value for inquiry framework.", e);
367 throw new RuntimeException(e);
368 }
369 }
370
371 parameters.put(keyName, keyValue);
372 }
373
374 String blockingUrl =
375 UrlFactory.parameterizeUrl(KRADConstants.DISPLAY_ALL_INACTIVATION_BLOCKERS_ACTION, parameters);
376
377
378 GlobalVariables.getMessageMap()
379 .putError(KRADConstants.GLOBAL_ERRORS, RiceKeyConstants.ERROR_INACTIVATION_BLOCKED, blockingUrl);
380 }
381
382
383
384
385 @Override
386 public boolean processApproveDocument(ApproveDocumentEvent approveEvent) {
387
388 MaintenanceDocument maintenanceDocument = (MaintenanceDocument) approveEvent.getDocument();
389
390
391
392 clearErrorPath();
393
394
395 setupBaseConvenienceObjects(maintenanceDocument);
396
397
398 processGlobalSaveDocumentBusinessRules(maintenanceDocument);
399
400
401
402 boolean success = true;
403
404
405 success &= processGlobalApproveDocumentBusinessRules(maintenanceDocument);
406
407
408
409
410 success &= processCustomApproveDocumentBusinessRules(maintenanceDocument);
411
412
413
414 resumeErrorPath();
415
416 return success;
417 }
418
419
420
421
422
423
424
425
426 protected void putGlobalError(String errorConstant) {
427 if (!errorAlreadyExists(KRADConstants.DOCUMENT_ERRORS, errorConstant)) {
428 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRADConstants.DOCUMENT_ERRORS, errorConstant);
429 }
430 }
431
432
433
434
435
436
437
438
439
440 protected void putGlobalError(String errorConstant, String parameter) {
441 if (!errorAlreadyExists(KRADConstants.DOCUMENT_ERRORS, errorConstant)) {
442 GlobalVariables.getMessageMap()
443 .putErrorWithoutFullErrorPath(KRADConstants.DOCUMENT_ERRORS, errorConstant, parameter);
444 }
445 }
446
447
448
449
450
451
452
453
454
455 protected void putGlobalError(String errorConstant, String[] parameters) {
456 if (!errorAlreadyExists(KRADConstants.DOCUMENT_ERRORS, errorConstant)) {
457 GlobalVariables.getMessageMap()
458 .putErrorWithoutFullErrorPath(KRADConstants.DOCUMENT_ERRORS, errorConstant, parameters);
459 }
460 }
461
462
463
464
465
466
467
468
469
470
471
472 protected void putFieldError(String propertyName, String errorConstant) {
473 if (!errorAlreadyExists(MAINTAINABLE_ERROR_PREFIX + propertyName, errorConstant)) {
474 GlobalVariables.getMessageMap()
475 .putErrorWithoutFullErrorPath(MAINTAINABLE_ERROR_PREFIX + propertyName, errorConstant);
476 }
477 }
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492 protected void putFieldError(String propertyName, String errorConstant, String parameter) {
493 if (!errorAlreadyExists(MAINTAINABLE_ERROR_PREFIX + propertyName, errorConstant)) {
494 GlobalVariables.getMessageMap()
495 .putErrorWithoutFullErrorPath(MAINTAINABLE_ERROR_PREFIX + propertyName, errorConstant, parameter);
496 }
497 }
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512 protected void putFieldError(String propertyName, String errorConstant, String[] parameters) {
513 if (!errorAlreadyExists(MAINTAINABLE_ERROR_PREFIX + propertyName, errorConstant)) {
514 GlobalVariables.getMessageMap()
515 .putErrorWithoutFullErrorPath(MAINTAINABLE_ERROR_PREFIX + propertyName, errorConstant, parameters);
516 }
517 }
518
519
520
521
522
523
524
525
526
527 protected void putFieldErrorWithShortLabel(String propertyName, String errorConstant) {
528 String shortLabel = ddService.getAttributeShortLabel(boClass, propertyName);
529 putFieldError(propertyName, errorConstant, shortLabel);
530 }
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546 protected void putDocumentError(String propertyName, String errorConstant, String parameter) {
547 if (!errorAlreadyExists(DOCUMENT_ERROR_PREFIX + propertyName, errorConstant)) {
548 GlobalVariables.getMessageMap().putError(DOCUMENT_ERROR_PREFIX + propertyName, errorConstant, parameter);
549 }
550 }
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566 protected void putDocumentError(String propertyName, String errorConstant, String[] parameters) {
567 GlobalVariables.getMessageMap().putError(DOCUMENT_ERROR_PREFIX + propertyName, errorConstant, parameters);
568 }
569
570
571
572
573
574
575
576
577
578
579 protected boolean errorAlreadyExists(String propertyName, String errorConstant) {
580
581 if (GlobalVariables.getMessageMap().fieldHasMessage(propertyName, errorConstant)) {
582 return true;
583 } else {
584 return false;
585 }
586 }
587
588
589
590
591
592
593
594
595
596 protected void putGlobalsError(String propertyName, String errorConstant) {
597 if (!errorAlreadyExists(propertyName, errorConstant)) {
598 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(propertyName, errorConstant);
599 }
600 }
601
602
603
604
605
606
607
608
609
610
611 protected void putGlobalsError(String propertyName, String errorConstant, String parameter) {
612 if (!errorAlreadyExists(propertyName, errorConstant)) {
613 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(propertyName, errorConstant, parameter);
614 }
615 }
616
617
618
619
620
621
622
623
624
625
626
627 protected void clearErrorPath() {
628
629
630 priorErrorPath.addAll(GlobalVariables.getMessageMap().getErrorPath());
631
632
633 GlobalVariables.getMessageMap().getErrorPath().clear();
634 }
635
636
637
638
639
640
641
642
643
644
645
646 protected void resumeErrorPath() {
647
648
649 GlobalVariables.getMessageMap().getErrorPath().addAll(priorErrorPath);
650 }
651
652
653
654
655
656
657
658 protected boolean dataDictionaryValidate(MaintenanceDocument document) {
659 LOG.debug("MaintenanceDocument validation beginning");
660
661
662
663 GlobalVariables.getMessageMap().addToErrorPath("document.newMaintainableObject");
664
665
666 Maintainable newMaintainable = document.getNewMaintainableObject();
667 if (newMaintainable == null) {
668 GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject");
669 throw new ValidationException(
670 "Maintainable object from Maintenance Document '" + document.getDocumentTitle() +
671 "' is null, unable to proceed.");
672 }
673
674
675 Object dataObject = newMaintainable.getDataObject();
676 if (dataObject == null) {
677 GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject.");
678 throw new ValidationException("Maintainable's component business object is null.");
679 }
680
681
682
683 if (newBo instanceof PersistableBusinessObject && CollectionUtils.isNotEmpty(maintDocDictionaryService
684 .getMaintainableSections(document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName()))) {
685
686 BusinessObject businessObject = (BusinessObject) newBo;
687
688
689 maintDocDictionaryService.validateMaintenanceRequiredFields(document);
690
691
692 maintDocDictionaryService.validateMaintainableCollectionsForDuplicateEntries(document);
693
694
695 dictionaryValidationService.validateBusinessObjectOnMaintenanceDocument(businessObject,
696 document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName());
697
698
699 dictionaryValidationService.validateDefaultExistenceChecks(businessObject);
700 } else {
701 GlobalVariables.getMessageMap().addToErrorPath("dataObject");
702
703 dictionaryValidationService.validate(newBo);
704
705 GlobalVariables.getMessageMap().removeFromErrorPath("dataObject");
706 }
707
708
709 GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject");
710
711 LOG.debug("MaintenanceDocument validation ending");
712 return true;
713 }
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731 protected boolean primaryKeyCheck(MaintenanceDocument document) {
732
733
734 boolean success = true;
735 Class<?> boClass = document.getNewMaintainableObject().getDataObjectClass();
736
737 Object oldBo = document.getOldMaintainableObject().getDataObject();
738 Object newBo = document.getNewMaintainableObject().getDataObject();
739
740
741
742
743
744
745 if (newBo instanceof GlobalBusinessObject) {
746 return success;
747 }
748
749
750
751 if (document.isEdit()) {
752 if (!getDataObjectMetaDataService().equalsByPrimaryKeys(oldBo, newBo)) {
753
754 putDocumentError(KRADConstants.DOCUMENT_ERRORS,
755 RiceKeyConstants.ERROR_DOCUMENT_MAINTENANCE_PRIMARY_KEYS_CHANGED_ON_EDIT,
756 getHumanReadablePrimaryKeyFieldNames(boClass));
757 success &= false;
758 }
759 }
760
761
762
763 else if (document.isNew()) {
764
765
766 if (newBo instanceof PersistableBusinessObject) {
767
768
769 Map<String, ?> newPkFields = getDataObjectMetaDataService().getPrimaryKeyFieldValues(newBo);
770
771
772
773
774
775
776
777 PersistableBusinessObject testBo =
778 boService.findByPrimaryKey(boClass.asSubclass(PersistableBusinessObject.class), newPkFields);
779
780
781
782 if (testBo != null) {
783 putDocumentError(KRADConstants.DOCUMENT_ERRORS,
784 RiceKeyConstants.ERROR_DOCUMENT_MAINTENANCE_KEYS_ALREADY_EXIST_ON_CREATE_NEW,
785 getHumanReadablePrimaryKeyFieldNames(boClass));
786 success &= false;
787 }
788 }
789 }
790
791 return success;
792 }
793
794
795
796
797
798
799
800
801 protected String getHumanReadablePrimaryKeyFieldNames(Class<?> boClass) {
802
803 String delim = "";
804 StringBuffer pkFieldNames = new StringBuffer();
805
806
807 List<String> pkFields = getDataObjectMetaDataService().listPrimaryKeyFieldNames(boClass);
808 for (Iterator<String> iter = pkFields.iterator(); iter.hasNext(); ) {
809 String pkFieldName = (String) iter.next();
810
811
812
813 String humanReadableFieldName = ddService.getAttributeLabel(boClass, pkFieldName);
814
815
816 pkFieldNames.append(delim + humanReadableFieldName);
817
818
819 if (delim.equalsIgnoreCase("")) {
820 delim = ", ";
821 }
822 }
823
824 return pkFieldNames.toString();
825 }
826
827
828
829
830
831
832
833
834
835
836
837
838
839 protected boolean processGlobalApproveDocumentBusinessRules(MaintenanceDocument document) {
840 return true;
841 }
842
843
844
845
846
847
848
849
850
851
852
853
854
855 protected boolean processGlobalRouteDocumentBusinessRules(MaintenanceDocument document) {
856
857 boolean success = true;
858
859
860 success &= checkEmptyDocumentField(
861 KRADPropertyConstants.DOCUMENT_HEADER + "." + KRADPropertyConstants.DOCUMENT_DESCRIPTION,
862 document.getDocumentHeader().getDocumentDescription(), "Description");
863
864 return success;
865 }
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885 protected boolean processGlobalSaveDocumentBusinessRules(MaintenanceDocument document) {
886
887
888 boolean success = true;
889
890
891 primaryKeyCheck(document);
892
893
894
895 this.dataDictionaryValidate(document);
896
897 return success;
898 }
899
900
901
902
903
904
905
906 protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) {
907 return true;
908 }
909
910
911
912
913
914
915
916 protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
917 return true;
918 }
919
920
921
922
923
924
925
926 protected boolean processCustomApproveDocumentBusinessRules(MaintenanceDocument document) {
927 return true;
928 }
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943 protected boolean isDocumentValidForSave(MaintenanceDocument maintenanceDocument) {
944
945 boolean success = true;
946
947 success &= super.isDocumentOverviewValid(maintenanceDocument);
948 success &= validateDocumentStructure((Document) maintenanceDocument);
949 success &= validateMaintenanceDocument(maintenanceDocument);
950 success &= validateGlobalBusinessObjectPersistable(maintenanceDocument);
951 return success;
952 }
953
954
955
956
957
958
959
960
961
962
963
964 protected boolean validateDocumentStructure(Document document) {
965 boolean success = true;
966
967
968 String documentHeaderId = document.getDocumentNumber();
969 if (documentHeaderId == null || StringUtils.isEmpty(documentHeaderId)) {
970 throw new ValidationException("Document has no document number, unable to proceed.");
971 }
972
973 return success;
974 }
975
976
977
978
979
980
981
982
983
984
985
986
987
988 protected boolean validateMaintenanceDocument(MaintenanceDocument maintenanceDocument) {
989 boolean success = true;
990 Maintainable newMaintainable = maintenanceDocument.getNewMaintainableObject();
991
992
993 if (newMaintainable == null) {
994 throw new ValidationException(
995 "Maintainable object from Maintenance Document '" + maintenanceDocument.getDocumentTitle() +
996 "' is null, unable to proceed.");
997 }
998
999
1000 if (newMaintainable.getDataObject() == null) {
1001 throw new ValidationException("Maintainable's component data object is null.");
1002 }
1003
1004 return success;
1005 }
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019 protected boolean validateGlobalBusinessObjectPersistable(MaintenanceDocument document) {
1020 boolean success = true;
1021
1022 if (document.getNewMaintainableObject() == null) {
1023 return success;
1024 }
1025 if (document.getNewMaintainableObject().getDataObject() == null) {
1026 return success;
1027 }
1028 if (!(document.getNewMaintainableObject().getDataObject() instanceof GlobalBusinessObject)) {
1029 return success;
1030 }
1031
1032 PersistableBusinessObject bo = (PersistableBusinessObject) document.getNewMaintainableObject().getDataObject();
1033 GlobalBusinessObject gbo = (GlobalBusinessObject) bo;
1034 return gbo.isPersistable();
1035 }
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046 protected boolean isCorrectMaintenanceClass(MaintenanceDocument document, Class clazz) {
1047
1048
1049 if (document == null || clazz == null) {
1050 throw new IllegalArgumentException("Null arguments were passed in.");
1051 }
1052
1053
1054 if (clazz.toString().equals(document.getNewMaintainableObject().getDataObjectClass().toString())) {
1055 return true;
1056 } else {
1057 return false;
1058 }
1059 }
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072 protected boolean checkEmptyBOField(String propertyName, Object valueToTest, String parameter) {
1073
1074 boolean success = true;
1075
1076 success = checkEmptyValue(valueToTest);
1077
1078
1079 if (!success) {
1080 putFieldError(propertyName, RiceKeyConstants.ERROR_REQUIRED, parameter);
1081 }
1082
1083 return success;
1084 }
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098 protected boolean checkEmptyDocumentField(String propertyName, Object valueToTest, String parameter) {
1099 boolean success = true;
1100 success = checkEmptyValue(valueToTest);
1101 if (!success) {
1102 putDocumentError(propertyName, RiceKeyConstants.ERROR_REQUIRED, parameter);
1103 }
1104 return success;
1105 }
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117 protected boolean checkEmptyValue(Object valueToTest) {
1118 boolean success = true;
1119
1120
1121 if (valueToTest == null) {
1122 success = false;
1123 } else {
1124
1125 if (valueToTest instanceof String) {
1126 if (StringUtils.isBlank((String) valueToTest)) {
1127 success = false;
1128 }
1129 }
1130 }
1131
1132 return success;
1133 }
1134
1135
1136
1137
1138
1139
1140 protected void showErrorMap() {
1141
1142 if (GlobalVariables.getMessageMap().hasNoErrors()) {
1143 return;
1144 }
1145
1146 for (Iterator i = GlobalVariables.getMessageMap().getAllPropertiesAndErrors().iterator(); i.hasNext(); ) {
1147 Map.Entry e = (Map.Entry) i.next();
1148
1149 AutoPopulatingList errorList = (AutoPopulatingList) e.getValue();
1150 for (Iterator j = errorList.iterator(); j.hasNext(); ) {
1151 ErrorMessage em = (ErrorMessage) j.next();
1152
1153 if (em.getMessageParameters() == null) {
1154 LOG.error(e.getKey().toString() + " = " + em.getErrorKey());
1155 } else {
1156 LOG.error(e.getKey().toString() + " = " + em.getErrorKey() + " : " +
1157 em.getMessageParameters().toString());
1158 }
1159 }
1160 }
1161 }
1162
1163
1164
1165
1166 public void setupBaseConvenienceObjects(MaintenanceDocument document) {
1167
1168
1169 oldBo = document.getOldMaintainableObject().getDataObject();
1170 if (oldBo != null && oldBo instanceof PersistableBusinessObject) {
1171 ((PersistableBusinessObject) oldBo).refreshNonUpdateableReferences();
1172 }
1173
1174
1175 newBo = document.getNewMaintainableObject().getDataObject();
1176 if (newBo instanceof PersistableBusinessObject) {
1177 ((PersistableBusinessObject) newBo).refreshNonUpdateableReferences();
1178 }
1179
1180 boClass = document.getNewMaintainableObject().getDataObjectClass();
1181
1182
1183 setupConvenienceObjects();
1184 }
1185
1186 public void setupConvenienceObjects() {
1187
1188 }
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201 protected boolean checkForPartiallyFilledOutReferenceForeignKeys(String referenceName) {
1202 boolean success = true;
1203
1204 if (newBo instanceof PersistableBusinessObject) {
1205 ForeignKeyFieldsPopulationState fkFieldsState;
1206 fkFieldsState = persistenceStructureService
1207 .getForeignKeyFieldsPopulationState((PersistableBusinessObject) newBo, referenceName);
1208
1209
1210 if (fkFieldsState.isAnyFieldsPopulated() && !fkFieldsState.isAllFieldsPopulated()) {
1211 success = false;
1212
1213
1214
1215
1216 List fKeys = new ArrayList(persistenceStructureService
1217 .getForeignKeysForReference(newBo.getClass().asSubclass(PersistableBusinessObject.class),
1218 referenceName).keySet());
1219 String fKeysReadable = consolidateFieldNames(fKeys, ", ").toString();
1220
1221
1222 for (Iterator iter = fkFieldsState.getUnpopulatedFieldNames().iterator(); iter.hasNext(); ) {
1223 String fieldName = (String) iter.next();
1224
1225
1226 String fieldNameReadable = ddService.getAttributeLabel(newBo.getClass(), fieldName);
1227
1228
1229 putFieldError(fieldName, RiceKeyConstants.ERROR_DOCUMENT_MAINTENANCE_PARTIALLY_FILLED_OUT_REF_FKEYS,
1230 new String[]{fieldNameReadable, fKeysReadable});
1231 }
1232 }
1233 }
1234
1235 return success;
1236 }
1237
1238
1239
1240
1241
1242
1243
1244 protected StringBuffer consolidateFieldNames(List fieldNames, String delimiter) {
1245
1246 StringBuffer sb = new StringBuffer();
1247
1248
1249 boolean firstPass = true;
1250 String delim = "";
1251
1252
1253 for (Iterator iter = fieldNames.iterator(); iter.hasNext(); ) {
1254 String fieldName = (String) iter.next();
1255
1256
1257
1258 sb.append(delim + ddService.getAttributeLabel(newBo.getClass(), fieldName));
1259
1260
1261 if (firstPass) {
1262 delim = delimiter;
1263 firstPass = false;
1264 }
1265 }
1266
1267 return sb;
1268 }
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278 protected String getFieldLabel(String fieldName) {
1279 return ddService.getAttributeLabel(newBo.getClass(), fieldName) + "(" +
1280 ddService.getAttributeShortLabel(newBo.getClass(), fieldName) + ")";
1281 }
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292 protected String getFieldLabel(Class boClass, String fieldName) {
1293 return ddService.getAttributeLabel(boClass, fieldName) + "(" +
1294 ddService.getAttributeShortLabel(boClass, fieldName) + ")";
1295 }
1296
1297
1298
1299
1300
1301
1302 protected final BusinessObjectService getBoService() {
1303 return boService;
1304 }
1305
1306
1307
1308
1309
1310
1311 public final void setBoService(BusinessObjectService boService) {
1312 this.boService = boService;
1313 }
1314
1315
1316
1317
1318
1319
1320 protected final ConfigurationService getConfigService() {
1321 return configService;
1322 }
1323
1324
1325
1326
1327
1328
1329 public final void setConfigService(ConfigurationService configService) {
1330 this.configService = configService;
1331 }
1332
1333
1334
1335
1336
1337
1338 protected final DataDictionaryService getDdService() {
1339 return ddService;
1340 }
1341
1342
1343
1344
1345
1346
1347 public final void setDdService(DataDictionaryService ddService) {
1348 this.ddService = ddService;
1349 }
1350
1351
1352
1353
1354
1355
1356 protected final DictionaryValidationService getDictionaryValidationService() {
1357 return dictionaryValidationService;
1358 }
1359
1360
1361
1362
1363
1364
1365 public final void setDictionaryValidationService(DictionaryValidationService dictionaryValidationService) {
1366 this.dictionaryValidationService = dictionaryValidationService;
1367 }
1368
1369
1370
1371
1372
1373
1374 protected final MaintenanceDocumentDictionaryService getMaintDocDictionaryService() {
1375 return maintDocDictionaryService;
1376 }
1377
1378
1379
1380
1381
1382
1383 public final void setMaintDocDictionaryService(MaintenanceDocumentDictionaryService maintDocDictionaryService) {
1384 this.maintDocDictionaryService = maintDocDictionaryService;
1385 }
1386
1387
1388
1389
1390
1391
1392 protected final Object getNewBo() {
1393 return newBo;
1394 }
1395
1396 protected void setNewBo(Object newBo) {
1397 this.newBo = newBo;
1398 }
1399
1400
1401
1402
1403
1404
1405 protected final Object getOldBo() {
1406 return oldBo;
1407 }
1408
1409
1410
1411
1412
1413
1414 protected final PersistenceStructureService getPersistenceStructureService() {
1415 return persistenceStructureService;
1416 }
1417
1418
1419
1420
1421
1422
1423 public final void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
1424 this.persistenceStructureService = persistenceStructureService;
1425 }
1426
1427
1428
1429
1430
1431
1432 public WorkflowDocumentService getWorkflowDocumentService() {
1433 return workflowDocumentService;
1434 }
1435
1436
1437
1438
1439
1440
1441 public void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) {
1442 this.workflowDocumentService = workflowDocumentService;
1443 }
1444
1445 public boolean processAddCollectionLineBusinessRules(MaintenanceDocument document, String collectionName,
1446 PersistableBusinessObject bo) {
1447 LOG.debug("processAddCollectionLineBusinessRules");
1448
1449
1450 setupBaseConvenienceObjects(document);
1451
1452
1453 this.validateMaintenanceDocument(document);
1454
1455 boolean success = true;
1456 MessageMap map = GlobalVariables.getMessageMap();
1457 int errorCount = map.getErrorCount();
1458 map.addToErrorPath(MAINTAINABLE_ERROR_PATH);
1459 if (LOG.isDebugEnabled()) {
1460 LOG.debug("processAddCollectionLineBusinessRules - BO: " + bo);
1461 LOG.debug("Before Validate: " + map);
1462 }
1463
1464 getMaintDocDictionaryService().validateMaintainableCollectionsAddLineRequiredFields(document,
1465 document.getNewMaintainableObject().getBusinessObject(), collectionName);
1466 String errorPath = KRADConstants.MAINTENANCE_ADD_PREFIX + collectionName;
1467 map.addToErrorPath(errorPath);
1468
1469 getDictionaryValidationService().validateBusinessObject(bo, false);
1470 success &= map.getErrorCount() == errorCount;
1471 success &= dictionaryValidationService.validateDefaultExistenceChecksForNewCollectionItem(
1472 document.getNewMaintainableObject().getBusinessObject(), bo, collectionName);
1473 success &= validateDuplicateIdentifierInDataDictionary(document, collectionName, bo);
1474 success &= processCustomAddCollectionLineBusinessRules(document, collectionName, bo);
1475
1476 map.removeFromErrorPath(errorPath);
1477 map.removeFromErrorPath(MAINTAINABLE_ERROR_PATH);
1478 if (LOG.isDebugEnabled()) {
1479 LOG.debug("After Validate: " + map);
1480 LOG.debug("processAddCollectionLineBusinessRules returning: " + success);
1481 }
1482
1483 return success;
1484 }
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499 protected boolean validateDuplicateIdentifierInDataDictionary(MaintenanceDocument document, String collectionName,
1500 PersistableBusinessObject bo) {
1501 boolean valid = true;
1502 PersistableBusinessObject maintBo = document.getNewMaintainableObject().getBusinessObject();
1503 Collection maintCollection = (Collection) ObjectUtils.getPropertyValue(maintBo, collectionName);
1504 List<String> duplicateIdentifier = document.getNewMaintainableObject()
1505 .getDuplicateIdentifierFieldsFromDataDictionary(
1506 document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName(), collectionName);
1507 if (duplicateIdentifier.size() > 0) {
1508 List<String> existingIdentifierString = document.getNewMaintainableObject()
1509 .getMultiValueIdentifierList(maintCollection, duplicateIdentifier);
1510 if (document.getNewMaintainableObject()
1511 .hasBusinessObjectExisted(bo, existingIdentifierString, duplicateIdentifier)) {
1512 valid = false;
1513 GlobalVariables.getMessageMap()
1514 .putError(duplicateIdentifier.get(0), RiceKeyConstants.ERROR_DUPLICATE_ELEMENT, "entries in ",
1515 document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName());
1516 }
1517 }
1518 return valid;
1519 }
1520
1521 public boolean processCustomAddCollectionLineBusinessRules(MaintenanceDocument document, String collectionName,
1522 PersistableBusinessObject line) {
1523 return true;
1524 }
1525
1526 public PersonService getPersonService() {
1527 return personService;
1528 }
1529
1530 public void setPersonService(PersonService personService) {
1531 this.personService = personService;
1532 }
1533
1534 public DateTimeService getDateTimeService() {
1535 return CoreApiServiceLocator.getDateTimeService();
1536 }
1537
1538
1539
1540
1541 public DocumentHelperService getDocumentHelperService() {
1542 return this.documentHelperService;
1543 }
1544
1545
1546
1547
1548 public void setDocumentHelperService(DocumentHelperService documentHelperService) {
1549 this.documentHelperService = documentHelperService;
1550 }
1551
1552 protected RoleService getRoleService() {
1553 if (this.roleService == null) {
1554 this.roleService = KimApiServiceLocator.getRoleService();
1555 }
1556 return this.roleService;
1557 }
1558
1559 protected DataObjectMetaDataService getDataObjectMetaDataService() {
1560 if (dataObjectMetaDataService == null) {
1561 this.dataObjectMetaDataService = KRADServiceLocatorWeb.getDataObjectMetaDataService();
1562 }
1563 return dataObjectMetaDataService;
1564 }
1565
1566 public void setDataObjectMetaDataService(DataObjectMetaDataService dataObjectMetaDataService) {
1567 this.dataObjectMetaDataService = dataObjectMetaDataService;
1568 }
1569
1570 public void setBusinessObjectAuthorizationService(
1571 BusinessObjectAuthorizationService businessObjectAuthorizationService) {
1572 this.businessObjectAuthorizationService = businessObjectAuthorizationService;
1573 }
1574
1575 public void setBusinessObjectMetaDataService(BusinessObjectMetaDataService businessObjectMetaDataService) {
1576 this.businessObjectMetaDataService = businessObjectMetaDataService;
1577 }
1578
1579 public void setBoDictionaryService(BusinessObjectDictionaryService boDictionaryService) {
1580 this.boDictionaryService = boDictionaryService;
1581 }
1582 }
1583