001/** 002 * Copyright 2005-2017 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.kew.document; 017 018import org.apache.commons.lang3.StringUtils; 019import org.kuali.rice.core.api.uif.RemotableAttributeError; 020import org.kuali.rice.core.api.util.RiceKeyConstants; 021import org.kuali.rice.kew.api.KEWPropertyConstants; 022import org.kuali.rice.kew.api.KewApiConstants; 023import org.kuali.rice.kew.api.KewApiServiceLocator; 024import org.kuali.rice.kew.api.rule.RuleTemplate; 025import org.kuali.rice.kew.api.rule.RuleTemplateAttribute; 026import org.kuali.rice.kew.doctype.service.DocumentTypeService; 027import org.kuali.rice.kew.rule.GroupRuleResponsibility; 028import org.kuali.rice.kew.rule.PersonRuleResponsibility; 029import org.kuali.rice.kew.rule.RuleBaseValues; 030import org.kuali.rice.kew.rule.RuleResponsibilityBo; 031import org.kuali.rice.kew.rule.WorkflowRuleAttributeRows; 032import org.kuali.rice.kew.rule.bo.RuleAttribute; 033import org.kuali.rice.kew.rule.web.WebRuleUtils; 034import org.kuali.rice.kew.service.KEWServiceLocator; 035import org.kuali.rice.kns.document.MaintenanceDocument; 036import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase; 037import org.kuali.rice.krad.bo.PersistableBusinessObject; 038 039import java.util.List; 040import java.util.Map; 041 042/** 043 * This is a description of what this class does - Garey don't forget to fill this in. 044 * 045 * @author Kuali Rice Team (rice.collab@kuali.org) 046 * 047 */ 048public class RoutingRuleMaintainableBusRule extends MaintenanceDocumentRuleBase { 049 050 /** 051 * This overridden method ... 052 * 053 * @see org.kuali.rice.krad.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.krad.maintenance.MaintenanceDocument) 054 */ 055 @Override 056 protected boolean processCustomSaveDocumentBusinessRules( 057 MaintenanceDocument document) { 058 059 boolean isValid = true; 060 061 RuleBaseValues ruleBaseValues = this.getRuleBaseValues(document); 062 RuleBaseValues oldRuleBaseValues = this.getOldRuleBaseValues(document); 063 064 isValid &= this.populateErrorMap(ruleBaseValues); 065 066 067 return isValid; 068 } 069 070 protected RuleBaseValues getRuleBaseValues(MaintenanceDocument document){ 071 return (RuleBaseValues)document.getNewMaintainableObject().getBusinessObject(); 072 } 073 074 protected RuleBaseValues getOldRuleBaseValues(MaintenanceDocument document){ 075 return (RuleBaseValues)document.getOldMaintainableObject().getBusinessObject(); 076 } 077 078 079 protected void populateErrorMap(Map<String,String> errorMap){ 080 for(Map.Entry<String, String> entry : errorMap.entrySet()){ 081 this.putFieldError(entry.getKey(), entry.getValue()); 082 } 083 } 084 085 /** 086 * This overridden method ... 087 * 088 * @see org.kuali.rice.krad.rules.MaintenanceDocumentRuleBase#processCustomAddCollectionLineBusinessRules(org.kuali.rice.krad.maintenance.MaintenanceDocument, java.lang.String, org.kuali.rice.krad.bo.PersistableBusinessObject) 089 */ 090 @Override 091 public boolean processCustomAddCollectionLineBusinessRules( 092 MaintenanceDocument document, String collectionName, 093 PersistableBusinessObject line) { 094 095 boolean isValid = true; 096 097 if(getPersonSectionName().equals(collectionName)){ 098 PersonRuleResponsibility pr = (PersonRuleResponsibility)line; 099 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}