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