View Javadoc
1   /**
2    * Copyright 2005-2015 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kew.document;
17  
18  import org.apache.commons.lang3.StringUtils;
19  import org.kuali.rice.core.api.uif.RemotableAttributeError;
20  import org.kuali.rice.core.api.util.RiceKeyConstants;
21  import org.kuali.rice.kew.api.KEWPropertyConstants;
22  import org.kuali.rice.kew.api.KewApiConstants;
23  import org.kuali.rice.kew.api.KewApiServiceLocator;
24  import org.kuali.rice.kew.api.rule.RuleTemplate;
25  import org.kuali.rice.kew.api.rule.RuleTemplateAttribute;
26  import org.kuali.rice.kew.doctype.service.DocumentTypeService;
27  import org.kuali.rice.kew.rule.GroupRuleResponsibility;
28  import org.kuali.rice.kew.rule.PersonRuleResponsibility;
29  import org.kuali.rice.kew.rule.RuleBaseValues;
30  import org.kuali.rice.kew.rule.RuleResponsibilityBo;
31  import org.kuali.rice.kew.rule.WorkflowRuleAttributeRows;
32  import org.kuali.rice.kew.rule.bo.RuleAttribute;
33  import org.kuali.rice.kew.rule.web.WebRuleUtils;
34  import org.kuali.rice.kew.service.KEWServiceLocator;
35  import org.kuali.rice.kns.document.MaintenanceDocument;
36  import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
37  import org.kuali.rice.krad.bo.PersistableBusinessObject;
38  
39  import java.util.List;
40  import java.util.Map;
41  
42  /**
43   * This is a description of what this class does - Garey don't forget to fill this in.
44   *
45   * @author Kuali Rice Team (rice.collab@kuali.org)
46   *
47   */
48  public class RoutingRuleMaintainableBusRule extends MaintenanceDocumentRuleBase {
49  
50  	/**
51  	 * This overridden method ...
52  	 *
53  	 * @see org.kuali.rice.krad.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.krad.maintenance.MaintenanceDocument)
54  	 */
55  	@Override
56  	protected boolean processCustomSaveDocumentBusinessRules(
57  			MaintenanceDocument document) {
58  
59  		boolean isValid = true;
60  
61  		RuleBaseValues ruleBaseValues = this.getRuleBaseValues(document);
62  		RuleBaseValues oldRuleBaseValues = this.getOldRuleBaseValues(document);
63  		
64  		isValid &= this.populateErrorMap(ruleBaseValues);
65  
66  
67  		return isValid;
68  	}
69  
70  	protected RuleBaseValues getRuleBaseValues(MaintenanceDocument document){
71  		return (RuleBaseValues)document.getNewMaintainableObject().getBusinessObject();
72  	}
73  	
74  	protected RuleBaseValues getOldRuleBaseValues(MaintenanceDocument document){
75  		return (RuleBaseValues)document.getOldMaintainableObject().getBusinessObject();
76  	}
77  	
78  
79  	protected void populateErrorMap(Map<String,String> errorMap){
80  		for(Map.Entry<String, String> entry : errorMap.entrySet()){
81  			this.putFieldError(entry.getKey(), entry.getValue());
82  		}
83  	}
84  
85  	/**
86  	 * This overridden method ...
87  	 *
88  	 * @see org.kuali.rice.krad.rules.MaintenanceDocumentRuleBase#processCustomAddCollectionLineBusinessRules(org.kuali.rice.krad.maintenance.MaintenanceDocument, java.lang.String, org.kuali.rice.krad.bo.PersistableBusinessObject)
89  	 */
90  	@Override
91  	public boolean processCustomAddCollectionLineBusinessRules(
92  			MaintenanceDocument document, String collectionName,
93  			PersistableBusinessObject line) {
94  
95  		boolean isValid = true;
96  
97  		if(getPersonSectionName().equals(collectionName)){
98  			PersonRuleResponsibility pr = (PersonRuleResponsibility)line;
99  			String name = pr.getPrincipalName();
100 
101 			if(!personExists(name)){
102 				isValid &= false;
103 				this.putFieldError(getPersonSectionName(), "error.document.personResponsibilities.principleDoesNotExist");
104 			}
105 		}else if(getGroupSectionName().equals(collectionName)){
106 			GroupRuleResponsibility gr = (GroupRuleResponsibility)line;
107 			if(!groupExists(gr.getNamespaceCode(), gr.getName())){
108 				isValid &= false;
109 				this.putFieldError(getGroupSectionName(), "error.document.personResponsibilities.groupDoesNotExist");
110 			}
111 		}
112 
113 		return isValid;
114 	}
115 
116 	protected String getPersonSectionName(){
117 		return KEWPropertyConstants.PERSON_RESP_SECTION;
118 	}
119 	protected String getGroupSectionName(){
120 		return KEWPropertyConstants.GROUP_RESP_SECTION;
121 	}
122 
123 	protected boolean personExists(String principalName){
124 		boolean bRet = false;
125 		try{
126 			KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(principalName);
127 			bRet = true;
128 		}catch(Exception ex){
129 			bRet = false;
130 			//ex.printStackTrace();
131 		}
132 
133 		return bRet;
134 	}
135 
136 	protected boolean groupExists(String namespaceCode, String groupName){
137 		boolean bRet = false;
138 		try{
139 			KEWServiceLocator.getIdentityHelperService().getGroupByName(namespaceCode, groupName);
140 			bRet = true;
141 		}catch(Exception ex){
142 			bRet = false;
143 			//ex.printStackTrace();
144 		}
145 		return bRet;
146 	}
147 
148 	protected boolean populateErrorMap(RuleBaseValues ruleBaseValues){
149 
150 		boolean isValid = true;
151 
152 		if (getDocumentTypeService().findByName(ruleBaseValues.getDocTypeName()) == null) {
153             putFieldError("docTypeName", "doctype.documenttypeservice.doctypename.required");
154             isValid = false;
155         }
156         if(ruleBaseValues.getName() != null){
157         	if(ruleExists(ruleBaseValues)){
158         		putFieldError("name", "routetemplate.ruleservice.name.unique");
159             	isValid = false;
160         	}
161         }
162 
163         /*
164          * Logic: If both from and to dates exist, make sure toDate is after fromDate
165          */
166         if(ruleBaseValues.getToDateValue() != null && ruleBaseValues.getFromDateValue() != null){
167         	if (ruleBaseValues.getToDateValue().before(ruleBaseValues.getFromDateValue())) {
168     			putFieldError("toDate", "error.document.maintainableItems.toDate");
169     			isValid = false;
170             }
171         }
172 
173 		if(!setRuleAttributeErrors(ruleBaseValues)){
174 			isValid = false;
175 		}
176 
177 		// This doesn't map directly to a single field. It's either the person or the group tab
178 		if ( ruleBaseValues.getPersonResponsibilities().isEmpty()
179 		        && ruleBaseValues.getGroupResponsibilities().isEmpty()
180 		        && ruleBaseValues.getRoleResponsibilities().isEmpty() ) {
181             putFieldError("Persons", "error.document.responsibility.required");
182             isValid = false;		    
183         } else {
184             for (PersonRuleResponsibility responsibility : ruleBaseValues.getPersonResponsibilities()) {
185                 if ( StringUtils.isBlank( responsibility.getPrincipalName() ) || KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(responsibility.getPrincipalName()) == null ) {
186                     putFieldError("Persons", "routetemplate.ruleservice.user.invalid");
187                     isValid = false;
188                     break;
189                 }
190             }
191             for (GroupRuleResponsibility responsibility : ruleBaseValues.getGroupResponsibilities()) {
192                 if ( StringUtils.isBlank( responsibility.getNamespaceCode() ) 
193                         || StringUtils.isBlank( responsibility.getName() )
194                         || getGroupService().getGroupByNamespaceCodeAndName(responsibility.getNamespaceCode(), responsibility.getName() ) == null ) {
195                 	putFieldError("Groups", "routetemplate.ruleservice.workgroup.invalid");
196                 	isValid = false;
197                 	break;
198                 }
199             }
200         }
201 
202         return isValid;
203 	}
204 
205 	protected boolean ruleExists(RuleBaseValues rule){
206 		boolean bRet = false;
207 
208 		RuleBaseValues tmp = KEWServiceLocator.getRuleService().getRuleByName(rule.getName());
209 
210 		if(tmp != null) {
211 		    if ((rule.getPreviousRuleId() == null)
212 		         || (rule.getPreviousRuleId() != null
213 		            && !rule.getPreviousRuleId().equals(tmp.getId()))) {
214 			    bRet = true;
215 		    }
216 		}
217 
218 		return bRet;
219 	}
220 
221 	protected DocumentTypeService getDocumentTypeService() {
222         return (DocumentTypeService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE);
223     }
224 
225 
226 	protected boolean setRuleAttributeErrors(RuleBaseValues rule){
227 
228 		boolean isValid = true;
229 
230 		RuleTemplate ruleTemplate = KewApiServiceLocator.getRuleService().getRuleTemplate(rule.getRuleTemplateId());
231 
232 		/** Populate rule extension values * */
233 		for (RuleTemplateAttribute ruleTemplateAttribute : ruleTemplate.getActiveRuleTemplateAttributes()) {
234             if (!RuleAttribute.isWorkflowAttribute(ruleTemplateAttribute.getRuleAttribute().getType())) {
235                 continue;
236             }
237             Map<String, String> parameterMap = WebRuleUtils.getFieldMapForRuleTemplateAttribute(rule, ruleTemplateAttribute);
238             WorkflowRuleAttributeRows rows =
239                     KEWServiceLocator.getWorkflowRuleAttributeMediator().getRuleRows(parameterMap, ruleTemplateAttribute);
240 
241 			// TODO hook validation of rule data into PreRules
242             List<RemotableAttributeError> errors = rows.getValidationErrors();
243 			if (!errors.isEmpty()) {
244                 isValid = false;
245 				for(RemotableAttributeError error: errors){
246 				    this.putFieldError("RuleAttributes", RiceKeyConstants.ERROR_CUSTOM, error.getMessage());
247 				}
248 			}
249 		}
250 		return isValid;
251 
252 	}
253 
254 }