001 /** 002 * Copyright 2005-2013 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 */ 016 package org.kuali.rice.kew.rule.web; 017 018 import org.apache.commons.beanutils.BeanUtils; 019 import org.apache.commons.beanutils.PropertyUtils; 020 import org.apache.commons.lang.ArrayUtils; 021 import org.apache.commons.lang.StringUtils; 022 import org.kuali.rice.core.api.exception.RiceRuntimeException; 023 import org.kuali.rice.core.api.uif.RemotableAttributeError; 024 import org.kuali.rice.kew.api.KewApiConstants; 025 import org.kuali.rice.kew.api.action.ActionRequestPolicy; 026 import org.kuali.rice.kew.api.rule.RuleTemplateAttributeContract; 027 import org.kuali.rice.kew.doctype.bo.DocumentType; 028 import org.kuali.rice.kew.rule.GroupRuleResponsibility; 029 import org.kuali.rice.kew.rule.PersonRuleResponsibility; 030 import org.kuali.rice.kew.rule.RoleRuleResponsibility; 031 import org.kuali.rice.kew.rule.RuleBaseValues; 032 import org.kuali.rice.kew.rule.RuleDelegationBo; 033 import org.kuali.rice.kew.rule.RuleExtensionBo; 034 import org.kuali.rice.kew.rule.RuleExtensionValue; 035 import org.kuali.rice.kew.rule.RuleResponsibilityBo; 036 import org.kuali.rice.kew.rule.WorkflowRuleAttributeRows; 037 import org.kuali.rice.kew.rule.bo.RuleTemplateAttributeBo; 038 import org.kuali.rice.kew.rule.bo.RuleTemplateBo; 039 import org.kuali.rice.kew.rule.service.RuleServiceInternal; 040 import org.kuali.rice.kew.service.KEWServiceLocator; 041 import org.kuali.rice.kim.api.group.Group; 042 import org.kuali.rice.kim.api.identity.principal.Principal; 043 import org.kuali.rice.kns.web.ui.Field; 044 import org.kuali.rice.kns.web.ui.Row; 045 import org.kuali.rice.kns.web.ui.Section; 046 047 import java.lang.reflect.InvocationTargetException; 048 import java.util.ArrayList; 049 import java.util.Collections; 050 import java.util.HashMap; 051 import java.util.Iterator; 052 import java.util.List; 053 import java.util.Map; 054 055 /** 056 * Some utilities which are utilized by the {@link RuleAction}. 057 * 058 * @author Kuali Rice Team (rice.collab@kuali.org) 059 */ 060 public final class WebRuleUtils { 061 062 public static final String RULE_TEMPLATE_ID_PARAM = "ruleCreationValues.ruleTemplateId"; 063 public static final String RULE_TEMPLATE_NAME_PARAM = "ruleCreationValues.ruleTemplateName"; 064 public static final String DOCUMENT_TYPE_NAME_PARAM = "ruleCreationValues.docTypeName"; 065 public static final String RESPONSIBILITY_ID_PARAM = "ruleCreationValues.responsibilityId"; 066 067 private static final String ID_SEPARATOR = "~"; 068 private static final String RULE_ATTRIBUTES_SECTION_ID = "RuleAttributes"; 069 private static final String RULE_ATTRIBUTES_SECTION_TITLE = "Rule Attributes"; 070 private static final String ROLES_MAINTENANCE_SECTION_ID = "RolesMaintenance"; 071 072 private WebRuleUtils() { 073 throw new UnsupportedOperationException("do not call"); 074 } 075 076 /** 077 * Copies the existing rule onto the current document. This is used within the web-based rule GUI to make a 078 * copy of a rule on the existing document. Essentially, this method makes a copy of the rule and all 079 * delegates but preserves the document ID of the original rule. 080 */ 081 public static WebRuleBaseValues copyRuleOntoExistingDocument(WebRuleBaseValues rule) throws Exception { 082 WebRuleBaseValues ruleCopy = new WebRuleBaseValues(); 083 PropertyUtils.copyProperties(ruleCopy, rule); 084 ruleCopy.setPreviousRuleId(null); 085 ruleCopy.setCurrentInd(null); 086 ruleCopy.setVersionNbr(null); 087 088 List responsibilities = new ArrayList(); 089 for (Iterator iter = ruleCopy.getRuleResponsibilities().iterator(); iter.hasNext();) { 090 WebRuleResponsibility responsibility = (WebRuleResponsibility) iter.next(); 091 WebRuleResponsibility responsibilityCopy = new WebRuleResponsibility(); 092 PropertyUtils.copyProperties(responsibilityCopy, responsibility); 093 094 responsibilityCopy.setResponsibilityId(null); 095 responsibilityCopy.setId(null); 096 097 List delegations = new ArrayList(); 098 for (Iterator iterator = responsibilityCopy.getDelegationRules().iterator(); iterator.hasNext();) { 099 RuleDelegationBo delegation = (RuleDelegationBo) iterator.next(); 100 RuleDelegationBo delegationCopy = new RuleDelegationBo(); 101 PropertyUtils.copyProperties(delegationCopy, delegation); 102 103 delegationCopy.setDelegateRuleId(null); 104 delegationCopy.setVersionNumber(null); 105 delegationCopy.setRuleDelegationId(null); 106 delegationCopy.setResponsibilityId(null); 107 108 WebRuleBaseValues delegationRule = ((WebRuleBaseValues) delegation.getDelegationRule()); 109 WebRuleBaseValues ruleDelegateCopy = new WebRuleBaseValues(); 110 PropertyUtils.copyProperties(ruleDelegateCopy, delegationRule); 111 112 ruleDelegateCopy.setPreviousRuleId(null); 113 ruleDelegateCopy.setCurrentInd(null); 114 ruleDelegateCopy.setVersionNbr(null); 115 116 List delegateResps = new ArrayList(); 117 for (Iterator iterator1 = ruleDelegateCopy.getRuleResponsibilities().iterator(); iterator1.hasNext();) { 118 WebRuleResponsibility delegateResp = (WebRuleResponsibility) iterator1.next(); 119 WebRuleResponsibility delegateRespCopy = new WebRuleResponsibility(); 120 PropertyUtils.copyProperties(delegateRespCopy, delegateResp); 121 122 delegateRespCopy.setResponsibilityId(null); 123 delegateRespCopy.setId(null); 124 delegateResps.add(delegateRespCopy); 125 } 126 ruleDelegateCopy.setRuleResponsibilities(delegateResps); 127 delegationCopy.setDelegationRule(ruleDelegateCopy); 128 delegations.add(delegationCopy); 129 } 130 //responsibilityCopy.setDelegationRules(delegations); 131 responsibilities.add(responsibilityCopy); 132 } 133 ruleCopy.setRuleResponsibilities(responsibilities); 134 return ruleCopy; 135 } 136 137 /** 138 * Makes a copy of the rule and clears the document id on the rule and any of its delegates. 139 * This method is used for making a copy of a rule for a new document. It essentially calls 140 * the copyRuleOntoExistingDocument method and then clears out the document IDs. 141 * 142 * @param webRuleBaseValues 143 */ 144 public static WebRuleBaseValues copyToNewRule(WebRuleBaseValues webRuleBaseValues) throws Exception { 145 WebRuleBaseValues newRule = copyRuleOntoExistingDocument(webRuleBaseValues); 146 // clear out all document IDs on the rule and it's delegates 147 newRule.setDocumentId(null); 148 for (Iterator iterator = newRule.getRuleResponsibilities().iterator(); iterator.hasNext(); ) { 149 RuleResponsibilityBo responsibility = (RuleResponsibilityBo) iterator.next(); 150 for (Iterator iterator2 = responsibility.getDelegationRules().iterator(); iterator2.hasNext(); ) { 151 RuleDelegationBo delegation = (RuleDelegationBo) iterator2.next(); 152 delegation.getDelegationRule().setDocumentId(null); 153 } 154 } 155 return newRule; 156 } 157 158 public static void validateRuleTemplateAndDocumentType(RuleBaseValues oldRule, RuleBaseValues newRule, Map<String, String[]> parameters) { 159 String[] ruleTemplateIds = parameters.get(RULE_TEMPLATE_ID_PARAM); 160 String[] ruleTemplateNames = parameters.get(RULE_TEMPLATE_NAME_PARAM); 161 String[] documentTypeNames = parameters.get(DOCUMENT_TYPE_NAME_PARAM); 162 if (ArrayUtils.isEmpty(ruleTemplateIds) && ArrayUtils.isEmpty(ruleTemplateNames)) { 163 throw new RiceRuntimeException("Rule document must be initiated with a valid rule template id or rule template name."); 164 } 165 if (ArrayUtils.isEmpty(documentTypeNames)) { 166 throw new RiceRuntimeException("Rule document must be initiated with a valid document type name."); 167 } 168 RuleTemplateBo ruleTemplate = null; 169 if (!ArrayUtils.isEmpty(ruleTemplateIds)) { 170 String ruleTemplateId = ruleTemplateIds[0]; 171 ruleTemplate = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateId(ruleTemplateId); 172 if (ruleTemplate == null) { 173 throw new RiceRuntimeException("Failed to load rule template with id '" + ruleTemplateId + "'"); 174 } 175 } 176 if (ruleTemplate == null) { 177 String ruleTemplateName = ruleTemplateNames[0]; 178 ruleTemplate = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateName(ruleTemplateName); 179 if (ruleTemplate == null) { 180 throw new RiceRuntimeException("Failed to load rule template with name '" + ruleTemplateName + "'"); 181 } 182 } 183 String documentTypeName = documentTypeNames[0]; 184 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName); 185 if (documentType == null) { 186 throw new RiceRuntimeException("Failed to locate document type with name '" + documentTypeName + "'"); 187 } 188 189 // it appears that there is always an old maintainable, even in the case of a new document creation, 190 // if we don't initialize both the old and new versions we get errors during meshSections 191 initializeRuleAfterNew(oldRule, ruleTemplate, documentTypeName); 192 initializeRuleAfterNew(newRule, ruleTemplate, documentTypeName); 193 } 194 195 private static void initializeRuleAfterNew(RuleBaseValues rule, RuleTemplateBo ruleTemplate, String documentTypeName) { 196 rule.setRuleTemplate(ruleTemplate); 197 rule.setRuleTemplateId(ruleTemplate.getId()); 198 rule.setDocTypeName(documentTypeName); 199 } 200 201 public static void validateRuleAndResponsibility(RuleDelegationBo oldRuleDelegation, RuleDelegationBo newRuleDelegation, Map<String, String[]> parameters) { 202 String[] responsibilityIds = parameters.get(RESPONSIBILITY_ID_PARAM); 203 if (ArrayUtils.isEmpty(responsibilityIds)) { 204 throw new RiceRuntimeException("Delegation rule document must be initiated with a valid responsibility ID to delegate from."); 205 } 206 if (!ArrayUtils.isEmpty(responsibilityIds)) { 207 String responsibilityId = responsibilityIds[0]; 208 RuleResponsibilityBo ruleResponsibility = KEWServiceLocator.getRuleService().findRuleResponsibility(responsibilityId); 209 if (ruleResponsibility == null) { 210 throw new RiceRuntimeException("Failed to locate a rule responsibility for responsibility ID " + responsibilityId); 211 } 212 oldRuleDelegation.setResponsibilityId(responsibilityId); 213 newRuleDelegation.setResponsibilityId(responsibilityId); 214 } 215 216 } 217 218 public static void establishDefaultRuleValues(RuleBaseValues rule) { 219 rule.setActive(true); 220 221 RuleBaseValues defaultRule = ((RuleServiceInternal) KEWServiceLocator.getService(KEWServiceLocator.RULE_SERVICE)).findDefaultRuleByRuleTemplateId( 222 rule.getRuleTemplate().getDelegationTemplateId()); 223 if (defaultRule != null) { 224 defaultRule.setActivationDate(null); 225 defaultRule.setCurrentInd(null); 226 defaultRule.setDeactivationDate(null); 227 defaultRule.setDocTypeName(null); 228 defaultRule.setVersionNumber(null); 229 defaultRule.setId(null); 230 defaultRule.setTemplateRuleInd(Boolean.FALSE); 231 defaultRule.setVersionNbr(null); 232 try { 233 PropertyUtils.copyProperties(rule, defaultRule); 234 } catch (IllegalAccessException e) { 235 throw new RuntimeException(e); 236 } catch (InvocationTargetException e) { 237 throw new RuntimeException(e); 238 } catch (NoSuchMethodException e) { 239 throw new RuntimeException(e); 240 } 241 } 242 } 243 244 245 public static List<Section> customizeSections(RuleBaseValues rule, List<Section> sections, boolean delegateRule) { 246 247 List<Section> finalSections = new ArrayList<Section>(); 248 for (Section section : sections) { 249 // unfortunately, in the case of an inquiry the sectionId will always be null so we have to check section title 250 if (section.getSectionTitle().equals(RULE_ATTRIBUTES_SECTION_TITLE) || 251 RULE_ATTRIBUTES_SECTION_ID.equals(section.getSectionId())) { 252 List<Row> ruleTemplateRows = getRuleTemplateRows(rule, delegateRule); 253 if (!ruleTemplateRows.isEmpty()) { 254 section.setRows(ruleTemplateRows); 255 finalSections.add(section); 256 } 257 } else if (ROLES_MAINTENANCE_SECTION_ID.equals(section.getSectionId())) { 258 if (hasRoles(rule)) { 259 finalSections.add(section); 260 } 261 } else { 262 finalSections.add(section); 263 } 264 } 265 266 return finalSections; 267 } 268 269 public static List<Row> getRuleTemplateRows(RuleBaseValues rule, boolean delegateRule) { 270 List<Row> rows = new ArrayList<Row>(); 271 RuleTemplateBo ruleTemplate = rule.getRuleTemplate(); 272 Map<String, String> fieldNameMap = new HashMap<String, String>(); 273 // refetch rule template from service because after persistence in KNS, it comes back without any rule template attributes 274 if (ruleTemplate != null) { 275 ruleTemplate = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateId(ruleTemplate.getId()); 276 if (ruleTemplate != null) { 277 List<RuleTemplateAttributeBo> ruleTemplateAttributes = ruleTemplate.getActiveRuleTemplateAttributes(); 278 Collections.sort(ruleTemplateAttributes); 279 for (RuleTemplateAttributeBo ruleTemplateAttribute : ruleTemplateAttributes) { 280 if (!ruleTemplateAttribute.isWorkflowAttribute()) { 281 continue; 282 } 283 Map<String, String> parameters = getFieldMapForRuleTemplateAttribute(rule, ruleTemplateAttribute); 284 WorkflowRuleAttributeRows workflowRuleAttributeRows = 285 KEWServiceLocator.getWorkflowRuleAttributeMediator().getRuleRows(parameters, ruleTemplateAttribute); 286 List<Row> attributeRows = transformAndPopulateAttributeRows(workflowRuleAttributeRows.getRows(), 287 ruleTemplateAttribute, rule, fieldNameMap, delegateRule); 288 rows.addAll(attributeRows); 289 } 290 } 291 transformFieldConversions(rows, fieldNameMap); 292 } 293 return rows; 294 } 295 296 public static void transformFieldConversions(List<Row> rows, Map<String, String> fieldNameMap) { 297 for (Row row : rows) { 298 Map<String, String> transformedFieldConversions = new HashMap<String, String>(); 299 for (Field field : row.getFields()) { 300 Map<String, String> fieldConversions = field.getFieldConversionMap(); 301 for (String lookupFieldName : fieldConversions.keySet()) { 302 String localFieldName = fieldConversions.get(lookupFieldName); 303 if (fieldNameMap.containsKey(localFieldName)) { 304 // set the transformed value 305 transformedFieldConversions.put(lookupFieldName, fieldNameMap.get(localFieldName)); 306 } else { 307 // set the original value (not sure if this case will happen, but just in case) 308 transformedFieldConversions.put(lookupFieldName, fieldConversions.get(lookupFieldName)); 309 } 310 } 311 field.setFieldConversions(transformedFieldConversions); 312 } 313 } 314 } 315 316 private static boolean hasRoles(RuleBaseValues rule) { 317 RuleTemplateBo ruleTemplate = rule.getRuleTemplate(); 318 return !ruleTemplate.getRoles().isEmpty(); 319 } 320 321 /** 322 * Processes the Fields on the various attributes Rows to assign an appropriate field name to them so that the 323 * field name rendered in the maintenance HTML will properly assign the value to RuleBaseValues.fieldValues. 324 */ 325 326 public static List<Row> transformAndPopulateAttributeRows(List<Row> attributeRows, RuleTemplateAttributeBo ruleTemplateAttribute, RuleBaseValues rule, Map<String, String> fieldNameMap, boolean delegateRule) { 327 328 for (Row row : attributeRows) { 329 for (Field field : row.getFields()) { 330 String fieldName = field.getPropertyName(); 331 if (!StringUtils.isBlank(fieldName)) { 332 String valueKey = ruleTemplateAttribute.getId() + ID_SEPARATOR + fieldName; 333 334 String propertyName; 335 336 if (delegateRule) { 337 propertyName = "delegationRule.fieldValues(" + valueKey + ")"; 338 } else { 339 propertyName = "fieldValues(" + valueKey + ")"; 340 } 341 342 fieldNameMap.put(fieldName, propertyName); 343 field.setPropertyName(propertyName); 344 field.setPropertyValue(rule.getFieldValues().get(valueKey)); 345 } 346 } 347 } 348 return attributeRows; 349 } 350 351 /** 352 * Since editing of a Rule should actually result in a rule with a new ID and new 353 * entries in the rule and rule responsibility tables, we need to clear out 354 * the primary keys of the rule and related objects. 355 */ 356 public static void clearKeysForSave(RuleBaseValues rule) { 357 rule.setId(null); 358 rule.setActivationDate(null); 359 rule.setDeactivationDate(null); 360 rule.setCurrentInd(false); 361 rule.setVersionNbr(null); 362 rule.setObjectId(null); 363 rule.setVersionNumber(0L); 364 } 365 366 public static void clearKeysForSave(RuleDelegationBo ruleDelegation) { 367 ruleDelegation.setRuleDelegationId(null); 368 ruleDelegation.setObjectId(null); 369 ruleDelegation.setVersionNumber(0L); 370 clearKeysForSave(ruleDelegation.getDelegationRule()); 371 } 372 373 public static void translateResponsibilitiesForSave(RuleBaseValues rule) { 374 rule.getRuleResponsibilities().clear(); 375 for (PersonRuleResponsibility responsibility : rule.getPersonResponsibilities()) { 376 RuleResponsibilityBo ruleResponsibility = new RuleResponsibilityBo(); 377 ruleResponsibility.setActionRequestedCd(responsibility.getActionRequestedCd()); 378 ruleResponsibility.setPriority(responsibility.getPriority()); 379 ruleResponsibility.setResponsibilityId(responsibility.getResponsibilityId()); 380 if (ruleResponsibility.getResponsibilityId() == null) { 381 ruleResponsibility.setResponsibilityId(KEWServiceLocator.getResponsibilityIdService().getNewResponsibilityId()); 382 } 383 String principalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(responsibility.getPrincipalName()); 384 ruleResponsibility.setRuleResponsibilityName(principalId); 385 ruleResponsibility.setRuleResponsibilityType(KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID); 386 // default the approve policy to First Approve 387 ruleResponsibility.setApprovePolicy(ActionRequestPolicy.FIRST.getCode()); 388 rule.getRuleResponsibilities().add(ruleResponsibility); 389 } 390 for (GroupRuleResponsibility responsibility : rule.getGroupResponsibilities()) { 391 RuleResponsibilityBo ruleResponsibility = new RuleResponsibilityBo(); 392 ruleResponsibility.setActionRequestedCd(responsibility.getActionRequestedCd()); 393 ruleResponsibility.setPriority(responsibility.getPriority()); 394 ruleResponsibility.setResponsibilityId(responsibility.getResponsibilityId()); 395 if (ruleResponsibility.getResponsibilityId() == null) { 396 ruleResponsibility.setResponsibilityId(KEWServiceLocator.getResponsibilityIdService().getNewResponsibilityId()); 397 } 398 Group group = KEWServiceLocator.getIdentityHelperService().getGroupByName(responsibility.getNamespaceCode(), responsibility.getName()); 399 ruleResponsibility.setRuleResponsibilityName(group.getId()); 400 ruleResponsibility.setRuleResponsibilityType(KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID); 401 ruleResponsibility.setApprovePolicy(ActionRequestPolicy.FIRST.getCode()); 402 rule.getRuleResponsibilities().add(ruleResponsibility); 403 } 404 for (RoleRuleResponsibility responsibility : rule.getRoleResponsibilities()) { 405 RuleResponsibilityBo ruleResponsibility = new RuleResponsibilityBo(); 406 ruleResponsibility.setActionRequestedCd(responsibility.getActionRequestedCd()); 407 ruleResponsibility.setPriority(responsibility.getPriority()); 408 ruleResponsibility.setResponsibilityId(responsibility.getResponsibilityId()); 409 if (ruleResponsibility.getResponsibilityId() == null) { 410 ruleResponsibility.setResponsibilityId(KEWServiceLocator.getResponsibilityIdService().getNewResponsibilityId()); 411 } 412 ruleResponsibility.setRuleResponsibilityName(responsibility.getRoleName()); 413 ruleResponsibility.setRuleResponsibilityType(KewApiConstants.RULE_RESPONSIBILITY_ROLE_ID); 414 ruleResponsibility.setApprovePolicy(responsibility.getApprovePolicy()); 415 rule.getRuleResponsibilities().add(ruleResponsibility); 416 } 417 } 418 419 public static void translateFieldValuesForSave(RuleBaseValues rule) { 420 RuleTemplateBo ruleTemplate = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateId(rule.getRuleTemplateId()); 421 422 /** Populate rule extension values * */ 423 List extensions = new ArrayList(); 424 for (Iterator iterator = ruleTemplate.getActiveRuleTemplateAttributes().iterator(); iterator.hasNext();) { 425 RuleTemplateAttributeBo ruleTemplateAttribute = (RuleTemplateAttributeBo) iterator.next(); 426 if (!ruleTemplateAttribute.isWorkflowAttribute()) { 427 continue; 428 } 429 Map<String, String> parameterMap = getFieldMapForRuleTemplateAttribute(rule, ruleTemplateAttribute); 430 WorkflowRuleAttributeRows workflowRuleAttributeRows = 431 KEWServiceLocator.getWorkflowRuleAttributeMediator().getRuleRows(parameterMap, ruleTemplateAttribute); 432 433 434 // validate rule data populates the rule extension values for us 435 List<RemotableAttributeError> attValidationErrors = workflowRuleAttributeRows.getValidationErrors(); 436 437 // because validation should be handled by business rules now, if we encounter a validation error at this point in 438 // time, let's throw an exception 439 if (attValidationErrors != null && !attValidationErrors.isEmpty()) { 440 throw new RiceRuntimeException("Encountered attribute validation errors when attempting to save the Rule!"); 441 } 442 443 Map<String, String> ruleExtensionValuesMap = workflowRuleAttributeRows.getRuleExtensionValues(); 444 if (ruleExtensionValuesMap != null && !ruleExtensionValuesMap.isEmpty()) { 445 RuleExtensionBo ruleExtension = new RuleExtensionBo(); 446 ruleExtension.setRuleTemplateAttributeId(ruleTemplateAttribute.getId()); 447 List<RuleExtensionValue> ruleExtensionValues = new ArrayList<RuleExtensionValue>(); 448 for (String key : ruleExtensionValuesMap.keySet()) { 449 RuleExtensionValue ruleExtensionValue = new RuleExtensionValue(); 450 ruleExtensionValue.setExtension(ruleExtension); 451 ruleExtensionValue.setKey(key); 452 ruleExtensionValue.setValue(ruleExtensionValuesMap.get(key)); 453 ruleExtensionValues.add(ruleExtensionValue); 454 } 455 ruleExtension.setExtensionValues(ruleExtensionValues); 456 extensions.add(ruleExtension); 457 } 458 459 } 460 rule.setRuleExtensions(extensions); 461 462 for (Iterator iterator = rule.getRuleExtensions().iterator(); iterator.hasNext();) { 463 RuleExtensionBo ruleExtension = (RuleExtensionBo) iterator.next(); 464 ruleExtension.setRuleBaseValues(rule); 465 466 for (Iterator iterator2 = ruleTemplate.getActiveRuleTemplateAttributes().iterator(); iterator2.hasNext();) { 467 RuleTemplateAttributeBo ruleTemplateAttribute = (RuleTemplateAttributeBo) iterator2.next(); 468 if (StringUtils.equals(ruleTemplateAttribute.getId(), ruleExtension.getRuleTemplateAttributeId())) { 469 ruleExtension.setRuleTemplateAttribute(ruleTemplateAttribute); 470 break; 471 } 472 } 473 474 for (Iterator iterator2 = ruleExtension.getExtensionValues().iterator(); iterator2.hasNext();) { 475 RuleExtensionValue ruleExtensionValue = (RuleExtensionValue) iterator2.next(); 476 ruleExtensionValue.setExtension(ruleExtension); 477 } 478 } 479 } 480 481 /** 482 * Based on original logic implemented in Rule system. Essentially constructs a Map of field values related 483 * to the given RuleTemplateAttribute. 484 */ 485 public static Map<String, String> getFieldMapForRuleTemplateAttribute(RuleBaseValues rule, RuleTemplateAttributeContract ruleTemplateAttribute) { 486 Map<String, String> fieldMap = new HashMap<String, String>(); 487 for (String fieldKey : rule.getFieldValues().keySet()) { 488 String ruleTemplateAttributeId = fieldKey.substring(0, fieldKey.indexOf(ID_SEPARATOR)); 489 String fieldName = fieldKey.substring(fieldKey.indexOf(ID_SEPARATOR) + 1); 490 if (ruleTemplateAttribute.getId().equals(ruleTemplateAttributeId)) { 491 fieldMap.put(fieldName, rule.getFieldValues().get(fieldKey)); 492 } 493 } 494 return fieldMap; 495 } 496 497 public static void processRuleForDelegationSave(RuleDelegationBo ruleDelegation) { 498 RuleBaseValues rule = ruleDelegation.getDelegationRule(); 499 rule.setDelegateRule(true); 500 // certain items on a delegated rule responsibility are inherited from parent responsibility, set them to null 501 for (RuleResponsibilityBo responsibility : rule.getRuleResponsibilities()) { 502 responsibility.setActionRequestedCd(null); 503 responsibility.setPriority(null); 504 } 505 } 506 507 public static void populateForCopyOrEdit(RuleBaseValues oldRule, RuleBaseValues newRule) { 508 populateRuleMaintenanceFields(oldRule); 509 populateRuleMaintenanceFields(newRule); 510 // in the case of copy, our fields which are marked read only are cleared, this includes the rule template 511 // name and the document type name but we don't want these cleared 512 if (newRule.getRuleTemplate().getName() == null) { 513 newRule.getRuleTemplate().setName(oldRule.getRuleTemplate().getName()); 514 } 515 if (newRule.getDocTypeName() == null) { 516 newRule.setDocTypeName(oldRule.getDocTypeName()); 517 } 518 } 519 520 /** 521 * This method populates fields on RuleBaseValues which are used only for 522 * maintenance purposes. In otherwords, it populates the non-persistent fields 523 * on the RuleBaseValues which the maintenance document needs to function 524 * (such as the extension field values and responsibilities). 525 */ 526 public static void populateRuleMaintenanceFields(RuleBaseValues rule) { 527 translateResponsibilitiesForLoad(rule); 528 translateRuleExtensionsForLoad(rule); 529 } 530 531 public static void translateResponsibilitiesForLoad(RuleBaseValues rule) { 532 for (RuleResponsibilityBo responsibility : rule.getRuleResponsibilities()) { 533 if (responsibility.getRuleResponsibilityType().equals(KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID)) { 534 PersonRuleResponsibility personResponsibility = new PersonRuleResponsibility(); 535 copyResponsibility(responsibility, personResponsibility); 536 Principal principal = KEWServiceLocator.getIdentityHelperService().getPrincipal(personResponsibility.getRuleResponsibilityName()); 537 personResponsibility.setPrincipalName(principal.getPrincipalName()); 538 rule.getPersonResponsibilities().add(personResponsibility); 539 } else if (responsibility.getRuleResponsibilityType().equals(KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID)) { 540 GroupRuleResponsibility groupResponsibility = new GroupRuleResponsibility(); 541 copyResponsibility(responsibility, groupResponsibility); 542 Group group = KEWServiceLocator.getIdentityHelperService().getGroup(groupResponsibility.getRuleResponsibilityName()); 543 groupResponsibility.setNamespaceCode(group.getNamespaceCode()); 544 groupResponsibility.setName(group.getName()); 545 rule.getGroupResponsibilities().add(groupResponsibility); 546 } else if (responsibility.getRuleResponsibilityType().equals(KewApiConstants.RULE_RESPONSIBILITY_ROLE_ID)) { 547 RoleRuleResponsibility roleResponsibility = new RoleRuleResponsibility(); 548 copyResponsibility(responsibility, roleResponsibility); 549 rule.getRoleResponsibilities().add(roleResponsibility); 550 } else { 551 throw new RiceRuntimeException("Original responsibility with id '" + responsibility.getId() + "' contained a bad type code of '" + responsibility.getRuleResponsibilityType()); 552 } 553 } 554 // since we've loaded the responsibilities, let's clear the originals so they don't get serialized to the maint doc XML 555 rule.getRuleResponsibilities().clear(); 556 } 557 558 public static void copyResponsibility(RuleResponsibilityBo source, RuleResponsibilityBo target) { 559 try { 560 BeanUtils.copyProperties(target, source); 561 } catch (Exception e) { 562 throw new RiceRuntimeException("Failed to copy properties from source to target responsibility", e); 563 } 564 } 565 566 public static void translateRuleExtensionsForLoad(RuleBaseValues rule) { 567 for (RuleExtensionBo ruleExtension : rule.getRuleExtensions()) { 568 String ruleTemplateAttributeId = ruleExtension.getRuleTemplateAttributeId(); 569 for (RuleExtensionValue ruleExtensionValue : ruleExtension.getExtensionValues()) { 570 String fieldMapKey = ruleTemplateAttributeId + ID_SEPARATOR + ruleExtensionValue.getKey(); 571 rule.getFieldValues().put(fieldMapKey, ruleExtensionValue.getValue()); 572 } 573 } 574 // since we've loaded the extensions, let's clear the originals so that they don't get serialized to the maint doc XML 575 rule.getRuleExtensions().clear(); 576 } 577 578 public static void processRuleForCopy(String documentNumber, RuleBaseValues oldRule, RuleBaseValues newRule) { 579 WebRuleUtils.populateForCopyOrEdit(oldRule, newRule); 580 clearKeysForCopy(newRule); 581 newRule.setDocumentId(documentNumber); 582 } 583 584 public static void clearKeysForCopy(RuleBaseValues rule) { 585 rule.setId(null); 586 rule.setPreviousRuleId(null); 587 rule.setPreviousVersion(null); 588 rule.setName(null); 589 for (PersonRuleResponsibility responsibility : rule.getPersonResponsibilities()) { 590 clearResponsibilityKeys(responsibility); 591 } 592 for (GroupRuleResponsibility responsibility : rule.getGroupResponsibilities()) { 593 clearResponsibilityKeys(responsibility); 594 } 595 for (RoleRuleResponsibility responsibility : rule.getRoleResponsibilities()) { 596 clearResponsibilityKeys(responsibility); 597 } 598 } 599 600 private static void clearResponsibilityKeys(RuleResponsibilityBo responsibility) { 601 responsibility.setResponsibilityId(null); 602 responsibility.setId(null); 603 responsibility.setRuleBaseValuesId(null); 604 } 605 606 }