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