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 keyValue = CoreApiServiceLocator.getEncryptionService().encrypt(keyValue);
348 } catch (GeneralSecurityException e) {
349 LOG.error("Exception while trying to encrypted value for inquiry framework.", e);
350 throw new RuntimeException(e);
351 }
352 }
353
354 parameters.put(keyName, keyValue);
355 }
356
357 String blockingUrl = UrlFactory.parameterizeUrl(KRADConstants.DISPLAY_ALL_INACTIVATION_BLOCKERS_ACTION,
358 parameters);
359
360
361 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS,
362 RiceKeyConstants.ERROR_INACTIVATION_BLOCKED, blockingUrl);
363 }
364
365
366
367
368 @Override
369 public boolean processApproveDocument(ApproveDocumentEvent approveEvent) {
370 MaintenanceDocument maintenanceDocument = (MaintenanceDocument) approveEvent.getDocument();
371
372
373
374 clearErrorPath();
375
376
377 setupBaseConvenienceObjects(maintenanceDocument);
378
379
380 processGlobalSaveDocumentBusinessRules(maintenanceDocument);
381
382
383
384 boolean success = true;
385
386
387 success &= processGlobalApproveDocumentBusinessRules(maintenanceDocument);
388
389
390
391
392 success &= processCustomApproveDocumentBusinessRules(maintenanceDocument);
393
394
395
396 resumeErrorPath();
397
398 return success;
399 }
400
401
402
403
404
405
406
407
408 protected void putGlobalError(String errorConstant) {
409 if (!errorAlreadyExists(KRADConstants.DOCUMENT_ERRORS, errorConstant)) {
410 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRADConstants.DOCUMENT_ERRORS, errorConstant);
411 }
412 }
413
414
415
416
417
418
419
420
421
422 protected void putGlobalError(String errorConstant, String parameter) {
423 if (!errorAlreadyExists(KRADConstants.DOCUMENT_ERRORS, errorConstant)) {
424 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRADConstants.DOCUMENT_ERRORS, errorConstant,
425 parameter);
426 }
427 }
428
429
430
431
432
433
434
435
436
437 protected void putGlobalError(String errorConstant, String[] parameters) {
438 if (!errorAlreadyExists(KRADConstants.DOCUMENT_ERRORS, errorConstant)) {
439 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRADConstants.DOCUMENT_ERRORS, errorConstant,
440 parameters);
441 }
442 }
443
444
445
446
447
448
449
450
451
452
453
454
455 protected void putFieldError(String propertyName, String errorConstant) {
456 if (!errorAlreadyExists(MAINTAINABLE_ERROR_PREFIX + propertyName, errorConstant)) {
457 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(MAINTAINABLE_ERROR_PREFIX + propertyName,
458 errorConstant);
459 }
460 }
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477 protected void putFieldError(String propertyName, String errorConstant, String parameter) {
478 if (!errorAlreadyExists(MAINTAINABLE_ERROR_PREFIX + propertyName, errorConstant)) {
479 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(MAINTAINABLE_ERROR_PREFIX + propertyName,
480 errorConstant, parameter);
481 }
482 }
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498 protected void putFieldError(String propertyName, String errorConstant, String[] parameters) {
499 if (!errorAlreadyExists(MAINTAINABLE_ERROR_PREFIX + propertyName, errorConstant)) {
500 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(MAINTAINABLE_ERROR_PREFIX + propertyName,
501 errorConstant, parameters);
502 }
503 }
504
505
506
507
508
509
510
511
512
513 protected void putFieldErrorWithShortLabel(String propertyName, String errorConstant) {
514 String shortLabel = getDataDictionaryService().getAttributeShortLabel(dataObjectClass, propertyName);
515 putFieldError(propertyName, errorConstant, shortLabel);
516 }
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533 protected void putDocumentError(String propertyName, String errorConstant, String parameter) {
534 if (!errorAlreadyExists(DOCUMENT_ERROR_PREFIX + propertyName, errorConstant)) {
535 GlobalVariables.getMessageMap().putError(DOCUMENT_ERROR_PREFIX + propertyName, errorConstant, parameter);
536 }
537 }
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553 protected void putDocumentError(String propertyName, String errorConstant, String[] parameters) {
554 GlobalVariables.getMessageMap().putError(DOCUMENT_ERROR_PREFIX + propertyName, errorConstant, parameters);
555 }
556
557
558
559
560
561
562
563
564
565
566 protected boolean errorAlreadyExists(String propertyName, String errorConstant) {
567 if (GlobalVariables.getMessageMap().fieldHasMessage(propertyName, errorConstant)) {
568 return true;
569 } else {
570 return false;
571 }
572 }
573
574
575
576
577
578
579
580
581
582 protected void putGlobalsError(String propertyName, String errorConstant) {
583 if (!errorAlreadyExists(propertyName, errorConstant)) {
584 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(propertyName, errorConstant);
585 }
586 }
587
588
589
590
591
592
593
594
595
596
597 protected void putGlobalsError(String propertyName, String errorConstant, String parameter) {
598 if (!errorAlreadyExists(propertyName, errorConstant)) {
599 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(propertyName, errorConstant, parameter);
600 }
601 }
602
603
604
605
606
607
608
609
610
611
612
613
614
615 protected void clearErrorPath() {
616
617 priorErrorPath.addAll(GlobalVariables.getMessageMap().getErrorPath());
618
619
620 GlobalVariables.getMessageMap().getErrorPath().clear();
621 }
622
623
624
625
626
627
628
629
630
631
632
633 protected void resumeErrorPath() {
634
635
636 GlobalVariables.getMessageMap().getErrorPath().addAll(priorErrorPath);
637 }
638
639
640
641
642
643
644
645 protected boolean dataDictionaryValidate(MaintenanceDocument document) {
646
647 boolean success = true;
648 LOG.debug("MaintenanceDocument validation beginning");
649
650
651
652 GlobalVariables.getMessageMap().addToErrorPath("document.newMaintainableObject");
653
654
655 Maintainable newMaintainable = document.getNewMaintainableObject();
656 if (newMaintainable == null) {
657 GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject");
658 throw new ValidationException(
659 "Maintainable object from Maintenance Document '" + document.getDocumentTitle() +
660 "' is null, unable to proceed.");
661 }
662
663
664 Object dataObject = newMaintainable.getDataObject();
665 if (dataObject == null) {
666 GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject.");
667 throw new ValidationException("Maintainable's component business object is null.");
668 }
669
670
671 GlobalVariables.getMessageMap().addToErrorPath("dataObject");
672 DictionaryValidationResult dictionaryValidationResult = getDictionaryValidationService().validate(
673 newDataObject);
674 if (dictionaryValidationResult.getNumberOfErrors() > 0) {
675 success &= false;
676
677 for (ConstraintValidationResult cvr : dictionaryValidationResult) {
678 if (cvr.getStatus() == ErrorLevel.ERROR) {
679 GlobalVariables.getMessageMap().putError(cvr.getAttributePath(), cvr.getErrorKey());
680 }
681 }
682 }
683
684
685
686
687
688
689
690 GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject");
691
692 LOG.debug("MaintenanceDocument validation ending");
693 return true;
694 }
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712 protected boolean primaryKeyCheck(MaintenanceDocument document) {
713
714 boolean success = true;
715 Class<?> dataObjectClass = document.getNewMaintainableObject().getDataObjectClass();
716
717 Object oldBo = document.getOldMaintainableObject().getDataObject();
718 Object newDataObject = document.getNewMaintainableObject().getDataObject();
719
720
721
722
723
724
725 if (newDataObject instanceof GlobalBusinessObject) {
726 return success;
727 }
728
729
730
731 if (document.isEdit()) {
732 if (!getDataObjectMetaDataService().equalsByPrimaryKeys(oldBo, newDataObject)) {
733
734 putDocumentError(KRADConstants.DOCUMENT_ERRORS,
735 RiceKeyConstants.ERROR_DOCUMENT_MAINTENANCE_PRIMARY_KEYS_CHANGED_ON_EDIT,
736 getHumanReadablePrimaryKeyFieldNames(dataObjectClass));
737 success &= false;
738 }
739 }
740
741
742
743 else if (document.isNew()) {
744
745
746 if (newDataObject instanceof PersistableBusinessObject) {
747
748
749 Map<String, ?> newPkFields = getDataObjectMetaDataService().getPrimaryKeyFieldValues(newDataObject);
750
751
752
753
754
755
756
757 PersistableBusinessObject testBo = getBoService().findByPrimaryKey(dataObjectClass.asSubclass(
758 PersistableBusinessObject.class), newPkFields);
759
760
761
762 if (testBo != null) {
763 putDocumentError(KRADConstants.DOCUMENT_ERRORS,
764 RiceKeyConstants.ERROR_DOCUMENT_MAINTENANCE_KEYS_ALREADY_EXIST_ON_CREATE_NEW,
765 getHumanReadablePrimaryKeyFieldNames(dataObjectClass));
766 success &= false;
767 }
768 }
769 }
770
771 return success;
772 }
773
774
775
776
777
778
779
780
781 protected String getHumanReadablePrimaryKeyFieldNames(Class<?> dataObjectClass) {
782 String delim = "";
783 StringBuffer pkFieldNames = new StringBuffer();
784
785
786 List<String> pkFields = getDataObjectMetaDataService().listPrimaryKeyFieldNames(dataObjectClass);
787 for (Iterator<String> iter = pkFields.iterator(); iter.hasNext(); ) {
788 String pkFieldName = (String) iter.next();
789
790
791
792 String humanReadableFieldName = getDataDictionaryService().getAttributeLabel(dataObjectClass, pkFieldName);
793
794
795 pkFieldNames.append(delim + humanReadableFieldName);
796
797
798 if (delim.equalsIgnoreCase("")) {
799 delim = ", ";
800 }
801 }
802
803 return pkFieldNames.toString();
804 }
805
806
807
808
809
810
811
812
813
814
815
816
817
818 protected boolean processGlobalApproveDocumentBusinessRules(MaintenanceDocument document) {
819 return true;
820 }
821
822
823
824
825
826
827
828
829
830
831
832
833
834 protected boolean processGlobalRouteDocumentBusinessRules(MaintenanceDocument document) {
835 boolean success = true;
836
837
838 success &= checkEmptyDocumentField(
839 KRADPropertyConstants.DOCUMENT_HEADER + "." + KRADPropertyConstants.DOCUMENT_DESCRIPTION,
840 document.getDocumentHeader().getDocumentDescription(), "Description");
841
842 return success;
843 }
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863 protected boolean processGlobalSaveDocumentBusinessRules(MaintenanceDocument document) {
864
865 boolean success = true;
866
867
868 success &= primaryKeyCheck(document);
869
870
871
872 success &= this.dataDictionaryValidate(document);
873
874 return success;
875 }
876
877
878
879
880
881
882
883 protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) {
884 return true;
885 }
886
887
888
889
890
891
892
893 protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
894 return true;
895 }
896
897
898
899
900
901
902
903 protected boolean processCustomApproveDocumentBusinessRules(MaintenanceDocument document) {
904 return true;
905 }
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920 protected boolean isDocumentValidForSave(MaintenanceDocument maintenanceDocument) {
921
922 boolean success = true;
923
924 success &= super.isDocumentOverviewValid(maintenanceDocument);
925 success &= validateDocumentStructure((Document) maintenanceDocument);
926 success &= validateMaintenanceDocument(maintenanceDocument);
927 success &= validateGlobalBusinessObjectPersistable(maintenanceDocument);
928 return success;
929 }
930
931
932
933
934
935
936
937
938
939
940
941 protected boolean validateDocumentStructure(Document document) {
942 boolean success = true;
943
944
945 String documentHeaderId = document.getDocumentNumber();
946 if (documentHeaderId == null || StringUtils.isEmpty(documentHeaderId)) {
947 throw new ValidationException("Document has no document number, unable to proceed.");
948 }
949
950 return success;
951 }
952
953
954
955
956
957
958
959
960
961
962
963
964 protected boolean validateMaintenanceDocument(MaintenanceDocument maintenanceDocument) {
965 boolean success = true;
966 Maintainable newMaintainable = maintenanceDocument.getNewMaintainableObject();
967
968
969 if (newMaintainable == null) {
970 throw new ValidationException(
971 "Maintainable object from Maintenance Document '" + maintenanceDocument.getDocumentTitle() +
972 "' is null, unable to proceed.");
973 }
974
975
976 if (newMaintainable.getDataObject() == null) {
977 throw new ValidationException("Maintainable's component data object is null.");
978 }
979
980 return success;
981 }
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996 protected boolean validateGlobalBusinessObjectPersistable(MaintenanceDocument document) {
997 boolean success = true;
998
999 if (document.getNewMaintainableObject() == null) {
1000 return success;
1001 }
1002 if (document.getNewMaintainableObject().getDataObject() == null) {
1003 return success;
1004 }
1005 if (!(document.getNewMaintainableObject().getDataObject() instanceof GlobalBusinessObject)) {
1006 return success;
1007 }
1008
1009 PersistableBusinessObject bo = (PersistableBusinessObject) document.getNewMaintainableObject().getDataObject();
1010 GlobalBusinessObject gbo = (GlobalBusinessObject) bo;
1011 return gbo.isPersistable();
1012 }
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023 protected boolean isCorrectMaintenanceClass(MaintenanceDocument document, Class clazz) {
1024
1025 if (document == null || clazz == null) {
1026 throw new IllegalArgumentException("Null arguments were passed in.");
1027 }
1028
1029
1030 if (clazz.toString().equals(document.getNewMaintainableObject().getDataObjectClass().toString())) {
1031 return true;
1032 } else {
1033 return false;
1034 }
1035 }
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048 protected boolean checkEmptyBOField(String propertyName, Object valueToTest, String parameter) {
1049 boolean success = true;
1050
1051 success = checkEmptyValue(valueToTest);
1052
1053
1054 if (!success) {
1055 putFieldError(propertyName, RiceKeyConstants.ERROR_REQUIRED, parameter);
1056 }
1057
1058 return success;
1059 }
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073 protected boolean checkEmptyDocumentField(String propertyName, Object valueToTest, String parameter) {
1074 boolean success = true;
1075 success = checkEmptyValue(valueToTest);
1076 if (!success) {
1077 putDocumentError(propertyName, RiceKeyConstants.ERROR_REQUIRED, parameter);
1078 }
1079 return success;
1080 }
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092 protected boolean checkEmptyValue(Object valueToTest) {
1093 boolean success = true;
1094
1095
1096 if (valueToTest == null) {
1097 success = false;
1098 } else {
1099
1100 if (valueToTest instanceof String) {
1101 if (StringUtils.isBlank((String) valueToTest)) {
1102 success = false;
1103 }
1104 }
1105 }
1106
1107 return success;
1108 }
1109
1110
1111
1112
1113
1114
1115 protected void showErrorMap() {
1116 if (GlobalVariables.getMessageMap().hasNoErrors()) {
1117 return;
1118 }
1119
1120 for (Iterator i = GlobalVariables.getMessageMap().getAllPropertiesAndErrors().iterator(); i.hasNext(); ) {
1121 Map.Entry e = (Map.Entry) i.next();
1122
1123 AutoPopulatingList errorList = (AutoPopulatingList) e.getValue();
1124 for (Iterator j = errorList.iterator(); j.hasNext(); ) {
1125 ErrorMessage em = (ErrorMessage) j.next();
1126
1127 if (em.getMessageParameters() == null) {
1128 LOG.error(e.getKey().toString() + " = " + em.getErrorKey());
1129 } else {
1130 LOG.error(e.getKey().toString() + " = " + em.getErrorKey() + " : " +
1131 em.getMessageParameters().toString());
1132 }
1133 }
1134 }
1135 }
1136
1137
1138
1139
1140 public void setupBaseConvenienceObjects(MaintenanceDocument document) {
1141
1142 oldDataObject = document.getOldMaintainableObject().getDataObject();
1143 if (oldDataObject != null && oldDataObject instanceof PersistableBusinessObject) {
1144 ((PersistableBusinessObject) oldDataObject).refreshNonUpdateableReferences();
1145 }
1146
1147
1148 newDataObject = document.getNewMaintainableObject().getDataObject();
1149 if (newDataObject instanceof PersistableBusinessObject) {
1150 ((PersistableBusinessObject) newDataObject).refreshNonUpdateableReferences();
1151 }
1152
1153 dataObjectClass = document.getNewMaintainableObject().getDataObjectClass();
1154
1155
1156 setupConvenienceObjects();
1157 }
1158
1159 public void setupConvenienceObjects() {
1160
1161 }
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173 protected boolean checkForPartiallyFilledOutReferenceForeignKeys(String referenceName) {
1174 boolean success = true;
1175
1176 if (newDataObject instanceof PersistableBusinessObject) {
1177 ForeignKeyFieldsPopulationState fkFieldsState;
1178 fkFieldsState = getPersistenceStructureService().getForeignKeyFieldsPopulationState(
1179 (PersistableBusinessObject) newDataObject, referenceName);
1180
1181
1182 if (fkFieldsState.isAnyFieldsPopulated() && !fkFieldsState.isAllFieldsPopulated()) {
1183 success = false;
1184
1185
1186
1187
1188 List fKeys = new ArrayList(getPersistenceStructureService().getForeignKeysForReference(
1189 newDataObject.getClass().asSubclass(PersistableBusinessObject.class), referenceName).keySet());
1190 String fKeysReadable = consolidateFieldNames(fKeys, ", ").toString();
1191
1192
1193 for (Iterator iter = fkFieldsState.getUnpopulatedFieldNames().iterator(); iter.hasNext(); ) {
1194 String fieldName = (String) iter.next();
1195
1196
1197 String fieldNameReadable = getDataDictionaryService().getAttributeLabel(newDataObject.getClass(),
1198 fieldName);
1199
1200
1201 putFieldError(fieldName, RiceKeyConstants.ERROR_DOCUMENT_MAINTENANCE_PARTIALLY_FILLED_OUT_REF_FKEYS,
1202 new String[]{fieldNameReadable, fKeysReadable});
1203 }
1204 }
1205 }
1206
1207 return success;
1208 }
1209
1210
1211
1212
1213
1214
1215
1216 protected StringBuffer consolidateFieldNames(List fieldNames, String delimiter) {
1217 StringBuffer sb = new StringBuffer();
1218
1219
1220 boolean firstPass = true;
1221 String delim = "";
1222
1223
1224 for (Iterator iter = fieldNames.iterator(); iter.hasNext(); ) {
1225 String fieldName = (String) iter.next();
1226
1227
1228
1229 sb.append(delim + getDataDictionaryService().getAttributeLabel(newDataObject.getClass(), fieldName));
1230
1231
1232 if (firstPass) {
1233 delim = delimiter;
1234 firstPass = false;
1235 }
1236 }
1237
1238 return sb;
1239 }
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249 protected String getFieldLabel(String fieldName) {
1250 return getDataDictionaryService().getAttributeLabel(newDataObject.getClass(), fieldName) + "(" +
1251 getDataDictionaryService().getAttributeShortLabel(newDataObject.getClass(), fieldName) + ")";
1252 }
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263 protected String getFieldLabel(Class dataObjectClass, String fieldName) {
1264 return getDataDictionaryService().getAttributeLabel(dataObjectClass, fieldName) + "(" +
1265 getDataDictionaryService().getAttributeShortLabel(dataObjectClass, fieldName) + ")";
1266 }
1267
1268
1269
1270
1271
1272
1273 protected final Object getNewDataObject() {
1274 return newDataObject;
1275 }
1276
1277 protected void setNewDataObject(Object newDataObject) {
1278 this.newDataObject = newDataObject;
1279 }
1280
1281
1282
1283
1284
1285
1286 protected final Object getOldDataObject() {
1287 return oldDataObject;
1288 }
1289
1290 public boolean processCustomAddCollectionLineBusinessRules(MaintenanceDocument document, String collectionName,
1291 PersistableBusinessObject line) {
1292 return true;
1293 }
1294
1295 protected final BusinessObjectService getBoService() {
1296 if (boService == null) {
1297 this.boService = KRADServiceLocator.getBusinessObjectService();
1298 }
1299 return boService;
1300 }
1301
1302 public final void setBoService(BusinessObjectService boService) {
1303 this.boService = boService;
1304 }
1305
1306 protected final ConfigurationService getConfigService() {
1307 if (configService == null) {
1308 this.configService = KRADServiceLocator.getKualiConfigurationService();
1309 }
1310 return configService;
1311 }
1312
1313 public final void setConfigService(ConfigurationService configService) {
1314 this.configService = configService;
1315 }
1316
1317 protected final DataDictionaryService getDdService() {
1318 if (ddService == null) {
1319 this.ddService = KRADServiceLocatorWeb.getDataDictionaryService();
1320 }
1321 return ddService;
1322 }
1323
1324 public final void setDdService(DataDictionaryService ddService) {
1325 this.ddService = ddService;
1326 }
1327
1328 protected final DictionaryValidationService getDictionaryValidationService() {
1329 if (dictionaryValidationService == null) {
1330 this.dictionaryValidationService = KRADServiceLocatorWeb.getDictionaryValidationService();
1331 }
1332 return dictionaryValidationService;
1333 }
1334
1335 public final void setDictionaryValidationService(DictionaryValidationService dictionaryValidationService) {
1336 this.dictionaryValidationService = dictionaryValidationService;
1337 }
1338
1339 public PersonService getPersonService() {
1340 if (personService == null) {
1341 this.personService = KimApiServiceLocator.getPersonService();
1342 }
1343 return personService;
1344 }
1345
1346 public void setPersonService(PersonService personService) {
1347 this.personService = personService;
1348 }
1349
1350 public DateTimeService getDateTimeService() {
1351 return CoreApiServiceLocator.getDateTimeService();
1352 }
1353
1354 protected RoleService getRoleService() {
1355 if (this.roleService == null) {
1356 this.roleService = KimApiServiceLocator.getRoleService();
1357 }
1358 return this.roleService;
1359 }
1360
1361 protected DataObjectMetaDataService getDataObjectMetaDataService() {
1362 if (dataObjectMetaDataService == null) {
1363 this.dataObjectMetaDataService = KRADServiceLocatorWeb.getDataObjectMetaDataService();
1364 }
1365 return dataObjectMetaDataService;
1366 }
1367
1368 public void setDataObjectMetaDataService(DataObjectMetaDataService dataObjectMetaDataService) {
1369 this.dataObjectMetaDataService = dataObjectMetaDataService;
1370 }
1371
1372 protected final PersistenceStructureService getPersistenceStructureService() {
1373 if (persistenceStructureService == null) {
1374 this.persistenceStructureService = KRADServiceLocator.getPersistenceStructureService();
1375 }
1376 return persistenceStructureService;
1377 }
1378
1379 public final void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
1380 this.persistenceStructureService = persistenceStructureService;
1381 }
1382
1383 public WorkflowDocumentService getWorkflowDocumentService() {
1384 if (workflowDocumentService == null) {
1385 this.workflowDocumentService = KRADServiceLocatorWeb.getWorkflowDocumentService();
1386 }
1387 return workflowDocumentService;
1388 }
1389
1390 public void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) {
1391 this.workflowDocumentService = workflowDocumentService;
1392 }
1393
1394 public DataObjectAuthorizationService getDataObjectAuthorizationService() {
1395 if (dataObjectAuthorizationService == null) {
1396 this.dataObjectAuthorizationService = KRADServiceLocatorWeb.getDataObjectAuthorizationService();
1397 }
1398 return dataObjectAuthorizationService;
1399 }
1400
1401 public void setDataObjectAuthorizationService(DataObjectAuthorizationService dataObjectAuthorizationService) {
1402 this.dataObjectAuthorizationService = dataObjectAuthorizationService;
1403 }
1404
1405 }
1406