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