001 /**
002 * Copyright 2005-2014 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 java.lang.reflect.InvocationTargetException;
019 import java.util.ArrayList;
020 import java.util.Collections;
021 import java.util.HashMap;
022 import java.util.Iterator;
023 import java.util.List;
024 import java.util.Map;
025
026 import org.apache.commons.beanutils.BeanUtils;
027 import org.apache.commons.beanutils.PropertyUtils;
028 import org.apache.commons.lang.ArrayUtils;
029 import org.apache.commons.lang.StringUtils;
030 import org.kuali.rice.core.api.exception.RiceRuntimeException;
031 import org.kuali.rice.core.api.uif.RemotableAttributeError;
032 import org.kuali.rice.kew.api.KewApiConstants;
033 import org.kuali.rice.kew.api.action.ActionRequestPolicy;
034 import org.kuali.rice.kew.api.rule.RuleTemplateAttributeContract;
035 import org.kuali.rice.kew.doctype.bo.DocumentType;
036 import org.kuali.rice.kew.rule.GroupRuleResponsibility;
037 import org.kuali.rice.kew.rule.PersonRuleResponsibility;
038 import org.kuali.rice.kew.rule.RoleRuleResponsibility;
039 import org.kuali.rice.kew.rule.RuleBaseValues;
040 import org.kuali.rice.kew.rule.RuleDelegationBo;
041 import org.kuali.rice.kew.rule.RuleExtensionBo;
042 import org.kuali.rice.kew.rule.RuleExtensionValue;
043 import org.kuali.rice.kew.rule.RuleResponsibilityBo;
044 import org.kuali.rice.kew.rule.WorkflowRuleAttributeRows;
045 import org.kuali.rice.kew.rule.bo.RuleTemplateAttributeBo;
046 import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
047 import org.kuali.rice.kew.rule.service.RuleServiceInternal;
048 import org.kuali.rice.kew.service.KEWServiceLocator;
049 import org.kuali.rice.kim.api.group.Group;
050 import org.kuali.rice.kim.api.identity.principal.Principal;
051 import org.kuali.rice.kns.web.ui.Field;
052 import org.kuali.rice.kns.web.ui.Row;
053 import org.kuali.rice.kns.web.ui.Section;
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 if (rule.getRuleTemplate().getDelegationTemplateId() != null) {
222 RuleBaseValues defaultRule =
223 ((RuleServiceInternal) KEWServiceLocator.getService(KEWServiceLocator.RULE_SERVICE)).
224 findDefaultRuleByRuleTemplateId(rule.getRuleTemplate().getDelegationTemplateId());
225
226 if (defaultRule != null) {
227 defaultRule.setActivationDate(null);
228 defaultRule.setCurrentInd(null);
229 defaultRule.setDeactivationDate(null);
230 defaultRule.setDocTypeName(null);
231 defaultRule.setVersionNumber(null);
232 defaultRule.setId(null);
233 defaultRule.setTemplateRuleInd(Boolean.FALSE);
234 defaultRule.setVersionNbr(null);
235 try {
236 PropertyUtils.copyProperties(rule, defaultRule);
237 } catch (IllegalAccessException e) {
238 throw new RuntimeException(e);
239 } catch (InvocationTargetException e) {
240 throw new RuntimeException(e);
241 } catch (NoSuchMethodException e) {
242 throw new RuntimeException(e);
243 }
244 }
245 }
246 }
247
248 public static List<Section> customizeSections(RuleBaseValues rule, List<Section> sections, boolean delegateRule) {
249
250 List<Section> finalSections = new ArrayList<Section>();
251 for (Section section : sections) {
252 // unfortunately, in the case of an inquiry the sectionId will always be null so we have to check section title
253 if (section.getSectionTitle().equals(RULE_ATTRIBUTES_SECTION_TITLE) ||
254 RULE_ATTRIBUTES_SECTION_ID.equals(section.getSectionId())) {
255 List<Row> ruleTemplateRows = getRuleTemplateRows(rule, delegateRule);
256 if (!ruleTemplateRows.isEmpty()) {
257 section.setRows(ruleTemplateRows);
258 finalSections.add(section);
259 }
260 } else if (ROLES_MAINTENANCE_SECTION_ID.equals(section.getSectionId())) {
261 if (hasRoles(rule)) {
262 finalSections.add(section);
263 }
264 } else {
265 finalSections.add(section);
266 }
267 }
268
269 return finalSections;
270 }
271
272 public static List<Row> getRuleTemplateRows(RuleBaseValues rule, boolean delegateRule) {
273 List<Row> rows = new ArrayList<Row>();
274 RuleTemplateBo ruleTemplate = rule.getRuleTemplate();
275 Map<String, String> fieldNameMap = new HashMap<String, String>();
276 // refetch rule template from service because after persistence in KNS, it comes back without any rule template attributes
277 if (ruleTemplate != null) {
278 ruleTemplate = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateId(ruleTemplate.getId());
279 if (ruleTemplate != null) {
280 List<RuleTemplateAttributeBo> ruleTemplateAttributes = ruleTemplate.getActiveRuleTemplateAttributes();
281 Collections.sort(ruleTemplateAttributes);
282 for (RuleTemplateAttributeBo ruleTemplateAttribute : ruleTemplateAttributes) {
283 if (!ruleTemplateAttribute.isWorkflowAttribute()) {
284 continue;
285 }
286 Map<String, String> parameters = getFieldMapForRuleTemplateAttribute(rule, ruleTemplateAttribute);
287 WorkflowRuleAttributeRows workflowRuleAttributeRows =
288 KEWServiceLocator.getWorkflowRuleAttributeMediator().getRuleRows(parameters, ruleTemplateAttribute);
289 List<Row> attributeRows = transformAndPopulateAttributeRows(workflowRuleAttributeRows.getRows(),
290 ruleTemplateAttribute, rule, fieldNameMap, delegateRule);
291 rows.addAll(attributeRows);
292 }
293 }
294 transformFieldConversions(rows, fieldNameMap);
295 }
296 return rows;
297 }
298
299 public static void transformFieldConversions(List<Row> rows, Map<String, String> fieldNameMap) {
300 for (Row row : rows) {
301 Map<String, String> transformedFieldConversions = new HashMap<String, String>();
302 for (Field field : row.getFields()) {
303 Map<String, String> fieldConversions = field.getFieldConversionMap();
304 for (String lookupFieldName : fieldConversions.keySet()) {
305 String localFieldName = fieldConversions.get(lookupFieldName);
306 if (fieldNameMap.containsKey(localFieldName)) {
307 // set the transformed value
308 transformedFieldConversions.put(lookupFieldName, fieldNameMap.get(localFieldName));
309 } else {
310 // set the original value (not sure if this case will happen, but just in case)
311 transformedFieldConversions.put(lookupFieldName, fieldConversions.get(lookupFieldName));
312 }
313 }
314 field.setFieldConversions(transformedFieldConversions);
315 }
316 }
317 }
318
319 private static boolean hasRoles(RuleBaseValues rule) {
320 RuleTemplateBo ruleTemplate = rule.getRuleTemplate();
321 return !ruleTemplate.getRoles().isEmpty();
322 }
323
324 /**
325 * Processes the Fields on the various attributes Rows to assign an appropriate field name to them so that the
326 * field name rendered in the maintenance HTML will properly assign the value to RuleBaseValues.fieldValues.
327 */
328
329 public static List<Row> transformAndPopulateAttributeRows(List<Row> attributeRows, RuleTemplateAttributeBo ruleTemplateAttribute, RuleBaseValues rule, Map<String, String> fieldNameMap, boolean delegateRule) {
330
331 for (Row row : attributeRows) {
332 for (Field field : row.getFields()) {
333 String fieldName = field.getPropertyName();
334 if (!StringUtils.isBlank(fieldName)) {
335 String valueKey = ruleTemplateAttribute.getId() + ID_SEPARATOR + fieldName;
336
337 String propertyName;
338
339 if (delegateRule) {
340 propertyName = "delegationRule.fieldValues(" + valueKey + ")";
341 } else {
342 propertyName = "fieldValues(" + valueKey + ")";
343 }
344
345 fieldNameMap.put(fieldName, propertyName);
346 field.setPropertyName(propertyName);
347 field.setPropertyValue(rule.getFieldValues().get(valueKey));
348 }
349 }
350 }
351 return attributeRows;
352 }
353
354 /**
355 * Since editing of a Rule should actually result in a rule with a new ID and new
356 * entries in the rule and rule responsibility tables, we need to clear out
357 * the primary keys of the rule and related objects.
358 */
359 public static void clearKeysForSave(RuleBaseValues rule) {
360 rule.setId(null);
361 rule.setActivationDate(null);
362 rule.setDeactivationDate(null);
363 rule.setCurrentInd(false);
364 rule.setVersionNbr(null);
365 rule.setObjectId(null);
366 rule.setVersionNumber(null);
367 }
368
369 public static void clearKeysForSave(RuleDelegationBo ruleDelegation) {
370 ruleDelegation.setRuleDelegationId(null);
371 ruleDelegation.setObjectId(null);
372 ruleDelegation.setVersionNumber(null);
373 clearKeysForSave(ruleDelegation.getDelegationRule());
374 }
375
376 public static void translateResponsibilitiesForSave(RuleBaseValues rule) {
377 rule.getRuleResponsibilities().clear();
378 for (PersonRuleResponsibility responsibility : rule.getPersonResponsibilities()) {
379 RuleResponsibilityBo ruleResponsibility = new RuleResponsibilityBo();
380 ruleResponsibility.setActionRequestedCd(responsibility.getActionRequestedCd());
381 ruleResponsibility.setPriority(responsibility.getPriority());
382 ruleResponsibility.setResponsibilityId(responsibility.getResponsibilityId());
383 if (ruleResponsibility.getResponsibilityId() == null) {
384 ruleResponsibility.setResponsibilityId(KEWServiceLocator.getResponsibilityIdService().getNewResponsibilityId());
385 }
386 String principalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(responsibility.getPrincipalName());
387 ruleResponsibility.setRuleResponsibilityName(principalId);
388 ruleResponsibility.setRuleResponsibilityType(KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID);
389 // default the approve policy to First Approve
390 ruleResponsibility.setApprovePolicy(ActionRequestPolicy.FIRST.getCode());
391 rule.getRuleResponsibilities().add(ruleResponsibility);
392 }
393 for (GroupRuleResponsibility responsibility : rule.getGroupResponsibilities()) {
394 RuleResponsibilityBo ruleResponsibility = new RuleResponsibilityBo();
395 ruleResponsibility.setActionRequestedCd(responsibility.getActionRequestedCd());
396 ruleResponsibility.setPriority(responsibility.getPriority());
397 ruleResponsibility.setResponsibilityId(responsibility.getResponsibilityId());
398 if (ruleResponsibility.getResponsibilityId() == null) {
399 ruleResponsibility.setResponsibilityId(KEWServiceLocator.getResponsibilityIdService().getNewResponsibilityId());
400 }
401 Group group = KEWServiceLocator.getIdentityHelperService().getGroupByName(responsibility.getNamespaceCode(), responsibility.getName());
402 ruleResponsibility.setRuleResponsibilityName(group.getId());
403 ruleResponsibility.setRuleResponsibilityType(KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID);
404 ruleResponsibility.setApprovePolicy(ActionRequestPolicy.FIRST.getCode());
405 rule.getRuleResponsibilities().add(ruleResponsibility);
406 }
407 for (RoleRuleResponsibility responsibility : rule.getRoleResponsibilities()) {
408 RuleResponsibilityBo ruleResponsibility = new RuleResponsibilityBo();
409 ruleResponsibility.setActionRequestedCd(responsibility.getActionRequestedCd());
410 ruleResponsibility.setPriority(responsibility.getPriority());
411 ruleResponsibility.setResponsibilityId(responsibility.getResponsibilityId());
412 if (ruleResponsibility.getResponsibilityId() == null) {
413 ruleResponsibility.setResponsibilityId(KEWServiceLocator.getResponsibilityIdService().getNewResponsibilityId());
414 }
415 ruleResponsibility.setRuleResponsibilityName(responsibility.getRoleName());
416 ruleResponsibility.setRuleResponsibilityType(KewApiConstants.RULE_RESPONSIBILITY_ROLE_ID);
417 ruleResponsibility.setApprovePolicy(responsibility.getApprovePolicy());
418 rule.getRuleResponsibilities().add(ruleResponsibility);
419 }
420 }
421
422 public static void translateFieldValuesForSave(RuleBaseValues rule) {
423 RuleTemplateBo ruleTemplate = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateId(rule.getRuleTemplateId());
424
425 /** Populate rule extension values * */
426 List extensions = new ArrayList();
427 for (Iterator iterator = ruleTemplate.getActiveRuleTemplateAttributes().iterator(); iterator.hasNext();) {
428 RuleTemplateAttributeBo ruleTemplateAttribute = (RuleTemplateAttributeBo) iterator.next();
429 if (!ruleTemplateAttribute.isWorkflowAttribute()) {
430 continue;
431 }
432 Map<String, String> parameterMap = getFieldMapForRuleTemplateAttribute(rule, ruleTemplateAttribute);
433 WorkflowRuleAttributeRows workflowRuleAttributeRows =
434 KEWServiceLocator.getWorkflowRuleAttributeMediator().getRuleRows(parameterMap, ruleTemplateAttribute);
435
436
437 // validate rule data populates the rule extension values for us
438 List<RemotableAttributeError> attValidationErrors = workflowRuleAttributeRows.getValidationErrors();
439
440 // because validation should be handled by business rules now, if we encounter a validation error at this point in
441 // time, let's throw an exception
442 if (attValidationErrors != null && !attValidationErrors.isEmpty()) {
443 throw new RiceRuntimeException("Encountered attribute validation errors when attempting to save the Rule!");
444 }
445
446 Map<String, String> ruleExtensionValuesMap = workflowRuleAttributeRows.getRuleExtensionValues();
447 if (ruleExtensionValuesMap != null && !ruleExtensionValuesMap.isEmpty()) {
448 RuleExtensionBo ruleExtension = new RuleExtensionBo();
449 ruleExtension.setRuleTemplateAttributeId(ruleTemplateAttribute.getId());
450 List<RuleExtensionValue> ruleExtensionValues = new ArrayList<RuleExtensionValue>();
451 for (String key : ruleExtensionValuesMap.keySet()) {
452 RuleExtensionValue ruleExtensionValue = new RuleExtensionValue();
453 ruleExtensionValue.setExtension(ruleExtension);
454 ruleExtensionValue.setKey(key);
455 ruleExtensionValue.setValue(ruleExtensionValuesMap.get(key));
456 ruleExtensionValues.add(ruleExtensionValue);
457 }
458 ruleExtension.setExtensionValues(ruleExtensionValues);
459 extensions.add(ruleExtension);
460 }
461
462 }
463 rule.setRuleExtensions(extensions);
464
465 for (Iterator iterator = rule.getRuleExtensions().iterator(); iterator.hasNext();) {
466 RuleExtensionBo ruleExtension = (RuleExtensionBo) iterator.next();
467 ruleExtension.setRuleBaseValues(rule);
468
469 for (Iterator iterator2 = ruleTemplate.getActiveRuleTemplateAttributes().iterator(); iterator2.hasNext();) {
470 RuleTemplateAttributeBo ruleTemplateAttribute = (RuleTemplateAttributeBo) iterator2.next();
471 if (StringUtils.equals(ruleTemplateAttribute.getId(), ruleExtension.getRuleTemplateAttributeId())) {
472 ruleExtension.setRuleTemplateAttribute(ruleTemplateAttribute);
473 break;
474 }
475 }
476
477 for (Iterator iterator2 = ruleExtension.getExtensionValues().iterator(); iterator2.hasNext();) {
478 RuleExtensionValue ruleExtensionValue = (RuleExtensionValue) iterator2.next();
479 ruleExtensionValue.setExtension(ruleExtension);
480 }
481 }
482 }
483
484 /**
485 * Based on original logic implemented in Rule system. Essentially constructs a Map of field values related
486 * to the given RuleTemplateAttribute.
487 */
488 public static Map<String, String> getFieldMapForRuleTemplateAttribute(RuleBaseValues rule, RuleTemplateAttributeContract ruleTemplateAttribute) {
489 Map<String, String> fieldMap = new HashMap<String, String>();
490 for (String fieldKey : rule.getFieldValues().keySet()) {
491 String ruleTemplateAttributeId = fieldKey.substring(0, fieldKey.indexOf(ID_SEPARATOR));
492 String fieldName = fieldKey.substring(fieldKey.indexOf(ID_SEPARATOR) + 1);
493 if (ruleTemplateAttribute.getId().equals(ruleTemplateAttributeId)) {
494 fieldMap.put(fieldName, rule.getFieldValues().get(fieldKey));
495 }
496 }
497 return fieldMap;
498 }
499
500 public static void processRuleForDelegationSave(RuleDelegationBo ruleDelegation) {
501 RuleBaseValues rule = ruleDelegation.getDelegationRule();
502 rule.setDelegateRule(true);
503 // certain items on a delegated rule responsibility are inherited from parent responsibility, set them to null
504 for (RuleResponsibilityBo responsibility : rule.getRuleResponsibilities()) {
505 responsibility.setActionRequestedCd(null);
506 responsibility.setPriority(null);
507 }
508 }
509
510 public static void populateForCopyOrEdit(RuleBaseValues oldRule, RuleBaseValues newRule) {
511 populateRuleMaintenanceFields(oldRule);
512 populateRuleMaintenanceFields(newRule);
513 // in the case of copy, our fields which are marked read only are cleared, this includes the rule template
514 // name and the document type name but we don't want these cleared
515 if (newRule.getRuleTemplate().getName() == null) {
516 newRule.getRuleTemplate().setName(oldRule.getRuleTemplate().getName());
517 }
518 if (newRule.getDocTypeName() == null) {
519 newRule.setDocTypeName(oldRule.getDocTypeName());
520 }
521 }
522
523 /**
524 * This method populates fields on RuleBaseValues which are used only for
525 * maintenance purposes. In otherwords, it populates the non-persistent fields
526 * on the RuleBaseValues which the maintenance document needs to function
527 * (such as the extension field values and responsibilities).
528 */
529 public static void populateRuleMaintenanceFields(RuleBaseValues rule) {
530 translateResponsibilitiesForLoad(rule);
531 translateRuleExtensionsForLoad(rule);
532 }
533
534 public static void translateResponsibilitiesForLoad(RuleBaseValues rule) {
535 for (RuleResponsibilityBo responsibility : rule.getRuleResponsibilities()) {
536 if (responsibility.getRuleResponsibilityType().equals(KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID)) {
537 PersonRuleResponsibility personResponsibility = new PersonRuleResponsibility();
538 copyResponsibility(responsibility, personResponsibility);
539 Principal principal = KEWServiceLocator.getIdentityHelperService().getPrincipal(personResponsibility.getRuleResponsibilityName());
540 personResponsibility.setPrincipalName(principal.getPrincipalName());
541 rule.getPersonResponsibilities().add(personResponsibility);
542 } else if (responsibility.getRuleResponsibilityType().equals(KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID)) {
543 GroupRuleResponsibility groupResponsibility = new GroupRuleResponsibility();
544 copyResponsibility(responsibility, groupResponsibility);
545 Group group = KEWServiceLocator.getIdentityHelperService().getGroup(groupResponsibility.getRuleResponsibilityName());
546 groupResponsibility.setNamespaceCode(group.getNamespaceCode());
547 groupResponsibility.setName(group.getName());
548 rule.getGroupResponsibilities().add(groupResponsibility);
549 } else if (responsibility.getRuleResponsibilityType().equals(KewApiConstants.RULE_RESPONSIBILITY_ROLE_ID)) {
550 RoleRuleResponsibility roleResponsibility = new RoleRuleResponsibility();
551 copyResponsibility(responsibility, roleResponsibility);
552 rule.getRoleResponsibilities().add(roleResponsibility);
553 } else {
554 throw new RiceRuntimeException("Original responsibility with id '" + responsibility.getId() + "' contained a bad type code of '" + responsibility.getRuleResponsibilityType());
555 }
556 }
557 // since we've loaded the responsibilities, let's clear the originals so they don't get serialized to the maint doc XML
558 rule.getRuleResponsibilities().clear();
559 }
560
561 public static void copyResponsibility(RuleResponsibilityBo source, RuleResponsibilityBo target) {
562 try {
563 BeanUtils.copyProperties(target, source);
564 } catch (Exception e) {
565 throw new RiceRuntimeException("Failed to copy properties from source to target responsibility", e);
566 }
567 }
568
569 public static void translateRuleExtensionsForLoad(RuleBaseValues rule) {
570 for (RuleExtensionBo ruleExtension : rule.getRuleExtensions()) {
571 String ruleTemplateAttributeId = ruleExtension.getRuleTemplateAttributeId();
572 for (RuleExtensionValue ruleExtensionValue : ruleExtension.getExtensionValues()) {
573 String fieldMapKey = ruleTemplateAttributeId + ID_SEPARATOR + ruleExtensionValue.getKey();
574 rule.getFieldValues().put(fieldMapKey, ruleExtensionValue.getValue());
575 }
576 }
577 // since we've loaded the extensions, let's clear the originals so that they don't get serialized to the maint doc XML
578 rule.getRuleExtensions().clear();
579 }
580
581 public static void processRuleForCopy(String documentNumber, RuleBaseValues oldRule, RuleBaseValues newRule) {
582 WebRuleUtils.populateForCopyOrEdit(oldRule, newRule);
583 clearKeysForCopy(newRule);
584 newRule.setDocumentId(documentNumber);
585 }
586
587 public static void clearKeysForCopy(RuleBaseValues rule) {
588 rule.setId(null);
589 rule.setPreviousRuleId(null);
590 rule.setPreviousVersion(null);
591 rule.setName(null);
592 for (PersonRuleResponsibility responsibility : rule.getPersonResponsibilities()) {
593 clearResponsibilityKeys(responsibility);
594 }
595 for (GroupRuleResponsibility responsibility : rule.getGroupResponsibilities()) {
596 clearResponsibilityKeys(responsibility);
597 }
598 for (RoleRuleResponsibility responsibility : rule.getRoleResponsibilities()) {
599 clearResponsibilityKeys(responsibility);
600 }
601 }
602
603 private static void clearResponsibilityKeys(RuleResponsibilityBo responsibility) {
604 responsibility.setResponsibilityId(null);
605 responsibility.setId(null);
606 responsibility.setRuleBaseValuesId(null);
607 }
608
609 }