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