View Javadoc

1   /**
2    * Copyright 2005-2011 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.rule.web;
17  
18  import org.apache.commons.beanutils.PropertyUtils;
19  import org.apache.commons.lang.StringUtils;
20  import org.apache.struts.action.ActionErrors;
21  import org.apache.struts.action.ActionMessage;
22  import org.kuali.rice.core.api.util.RiceConstants;
23  import org.kuali.rice.core.framework.persistence.jdbc.sql.SQLUtils;
24  import org.kuali.rice.kew.api.rule.RoleName;
25  import org.kuali.rice.kew.api.util.CodeTranslator;
26  import org.kuali.rice.kew.exception.WorkflowServiceError;
27  import org.kuali.rice.kew.rule.KeyValueId;
28  import org.kuali.rice.kew.rule.RoleAttribute;
29  import org.kuali.rice.kew.rule.RuleBaseValues;
30  import org.kuali.rice.kew.rule.RuleDelegationBo;
31  import org.kuali.rice.kew.rule.RuleExtensionBo;
32  import org.kuali.rice.kew.rule.RuleExtensionValue;
33  import org.kuali.rice.kew.rule.RuleResponsibilityBo;
34  import org.kuali.rice.kew.rule.WorkflowRuleAttribute;
35  import org.kuali.rice.kew.rule.bo.RuleAttribute;
36  import org.kuali.rice.kew.rule.bo.RuleTemplateAttributeBo;
37  import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
38  import org.kuali.rice.kew.rule.service.RuleDelegationService;
39  import org.kuali.rice.kew.rule.service.RuleTemplateService;
40  import org.kuali.rice.kew.rule.xmlrouting.GenericXMLRuleAttribute;
41  import org.kuali.rice.kew.service.KEWServiceLocator;
42  import org.kuali.rice.kew.api.KewApiConstants;
43  import org.kuali.rice.kns.web.ui.Field;
44  import org.kuali.rice.kns.web.ui.Row;
45  
46  import java.sql.Timestamp;
47  import java.text.ParseException;
48  import java.text.SimpleDateFormat;
49  import java.util.ArrayList;
50  import java.util.Calendar;
51  import java.util.Collection;
52  import java.util.Collections;
53  import java.util.Date;
54  import java.util.HashMap;
55  import java.util.Iterator;
56  import java.util.List;
57  import java.util.Map;
58  
59  
60  /**
61   * A decorator around a {@link RuleBaseValues} object which provides some
62   * convienance functions for interacting with the bean from the web-tier.
63   * This helps to alleviate some of the weaknesses of JSTL.
64   *
65   * @author Kuali Rice Team (rice.collab@kuali.org)
66   */
67  public class WebRuleBaseValues extends RuleBaseValues {
68  
69  	private static final long serialVersionUID = 5938997470219200474L;
70      private static final int TO_DATE_UPPER_LIMIT = 2100;
71  	private List rows = new ArrayList();
72  	private List fields = new ArrayList();
73  	private List roles = new ArrayList();
74  	private String fromDateString;
75  	private String toDateString;
76  	private String ruleTemplateName;
77  	private boolean hasExtensionValueErrors = false;
78  
79  	public WebRuleBaseValues() {
80  	}
81  
82  	public WebRuleBaseValues(RuleBaseValues rule) throws Exception {
83  		edit(rule);
84  	}
85  
86  	private void loadFields() {
87  		fields.clear();
88  		if (getRuleTemplateId() != null) {
89  			RuleTemplateBo ruleTemplate = getRuleTemplateService().findByRuleTemplateId(getRuleTemplateId());
90  			if (ruleTemplate != null) {
91  				List ruleTemplateAttributes = ruleTemplate.getActiveRuleTemplateAttributes();
92  				Collections.sort(ruleTemplateAttributes);
93  				for (Iterator iter = ruleTemplateAttributes.iterator(); iter.hasNext();) {
94  					RuleTemplateAttributeBo ruleTemplateAttribute = (RuleTemplateAttributeBo) iter.next();
95  					if (!ruleTemplateAttribute.isWorkflowAttribute()) {
96  						continue;
97  					}
98  					WorkflowRuleAttribute workflowAttribute = ruleTemplateAttribute.getWorkflowAttribute();
99  					RuleAttribute ruleAttribute = ruleTemplateAttribute.getRuleAttribute();
100 					if (ruleAttribute.getType().equals(KewApiConstants.RULE_XML_ATTRIBUTE_TYPE)) {
101 						((GenericXMLRuleAttribute) workflowAttribute).setExtensionDefinition(RuleAttribute.to(ruleAttribute));
102 					}
103 					for (Object element : workflowAttribute.getRuleRows()) {
104 						Row row = (Row) element;
105 						for (Object element2 : row.getFields()) {
106 							Field field = (Field) element2;
107                             String fieldValue = "";
108                             RuleExtensionValue extensionValue = getRuleExtensionValue(ruleTemplateAttribute.getId(), field.getPropertyName());
109 
110                             fieldValue = (extensionValue != null) ? extensionValue.getValue() : field.getPropertyValue();
111                             fields.add(new KeyValueId(field.getPropertyName(), fieldValue, ruleTemplateAttribute.getId()));
112                         }
113 					}
114 				}
115 			}
116 		}
117 	}
118 
119 	public void loadFieldsWithDefaultValues() {
120 		fields.clear();
121 		if (getRuleTemplateId() != null) {
122 			RuleTemplateBo ruleTemplate = getRuleTemplateService().findByRuleTemplateId(getRuleTemplateId());
123 			if (ruleTemplate != null) {
124 				List ruleTemplateAttributes = ruleTemplate.getActiveRuleTemplateAttributes();
125 				Collections.sort(ruleTemplateAttributes);
126 				for (Iterator iter = ruleTemplateAttributes.iterator(); iter.hasNext();) {
127 					RuleTemplateAttributeBo ruleTemplateAttribute = (RuleTemplateAttributeBo) iter.next();
128 					if (!ruleTemplateAttribute.isWorkflowAttribute()) {
129 						continue;
130 					}
131 					WorkflowRuleAttribute workflowAttribute = ruleTemplateAttribute.getWorkflowAttribute();
132 					RuleAttribute ruleAttribute = ruleTemplateAttribute.getRuleAttribute();
133 					if (ruleAttribute.getType().equals(KewApiConstants.RULE_XML_ATTRIBUTE_TYPE)) {
134 						((GenericXMLRuleAttribute) workflowAttribute).setExtensionDefinition(RuleAttribute.to(ruleAttribute));
135 					}
136 					for (Object element : workflowAttribute.getRuleRows()) {
137 						Row row = (Row) element;
138 						for (Object element2 : row.getFields()) {
139 							Field field = (Field) element2;
140 							fields.add(new KeyValueId(field.getPropertyName(), field.getPropertyValue(), ruleTemplateAttribute.getId() + ""));
141 						}
142 					}
143 				}
144 			}
145 		}
146 	}
147 
148 	private void loadWebValues() {
149 		loadRows();
150 		loadDates();
151 		loadRuleTemplateName();
152 	}
153 
154 	private void loadRows() {
155 		getRoles().clear();
156 		if (getRuleTemplateId() != null) {
157 			RuleTemplateBo ruleTemplate = getRuleTemplateService().findByRuleTemplateId(getRuleTemplateId());
158 			if (ruleTemplate != null) {
159 				setRuleTemplateName(ruleTemplate.getName());
160 				List<RuleTemplateAttributeBo> ruleTemplateAttributes = ruleTemplate.getActiveRuleTemplateAttributes();
161 				Collections.sort(ruleTemplateAttributes);
162 				List<Row> rows = new ArrayList<Row>();
163 				for (RuleTemplateAttributeBo ruleTemplateAttribute : ruleTemplateAttributes) {
164 					if (!ruleTemplateAttribute.isWorkflowAttribute()) {
165 						continue;
166 					}
167 					WorkflowRuleAttribute workflowAttribute = ruleTemplateAttribute.getWorkflowAttribute();
168 
169 					RuleAttribute ruleAttribute = ruleTemplateAttribute.getRuleAttribute();
170 					if (ruleAttribute.getType().equals(KewApiConstants.RULE_XML_ATTRIBUTE_TYPE)) {
171 						((GenericXMLRuleAttribute) workflowAttribute).setExtensionDefinition(RuleAttribute.to(ruleAttribute));
172 					}
173 					workflowAttribute.validateRuleData(getFieldMap(ruleTemplateAttribute.getId()+""));
174 					rows.addAll(workflowAttribute.getRuleRows());
175 					if (workflowAttribute instanceof RoleAttribute) {
176 						RoleAttribute roleAttribute = (RoleAttribute) workflowAttribute;
177 						getRoles().addAll(roleAttribute.getRoleNames());
178 					}
179 				}
180 				setRows(rows);
181 			}
182 		}
183 	}
184 
185 	private void loadDates() {
186 		if (getFromDateString() != null) {
187 			setFromDateString(RiceConstants.getDefaultDateFormat().format(getFromDateValue()));
188 		}
189 		if (getToDateString() != null) {
190 			setToDateString(RiceConstants.getDefaultDateFormat().format(getToDateValue()));
191 		}
192 	}
193 
194 	private void loadRuleTemplateName() {
195 		if (org.apache.commons.lang.StringUtils.isEmpty(getRuleTemplateName()) && getRuleTemplateId() != null) {
196 			RuleTemplateBo ruleTemplate = getRuleTemplateService().findByRuleTemplateId(getRuleTemplateId());
197 			if (ruleTemplate != null) {
198 				setRuleTemplateName(ruleTemplate.getName());
199 			}
200 		}
201 	}
202 
203 	public List getFields() {
204 		return fields;
205 	}
206 
207 	public void setFields(List fields) {
208 		this.fields = fields;
209 	}
210 
211 	public KeyValueId getField(int index) {
212 		while (getFields().size() <= index) {
213 			KeyValueId field = new KeyValueId();
214 			getFields().add(field);
215 		}
216 		return (KeyValueId) getFields().get(index);
217 	}
218 
219 	public String getFromDateString() {
220 		return fromDateString;
221 	}
222 
223 	public void setFromDateString(String fromDateString) {
224 		this.fromDateString = fromDateString;
225 	}
226 
227 	public List<RoleName> getRoles() {
228 		return roles;
229 	}
230 
231 	public void setRoles(List<RoleName> roles) {
232 		this.roles = roles;
233 	}
234 
235 	public List<RoleName> getRows() {
236 		return rows;
237 	}
238 
239 	public void setRows(List ruleTemplateAttributes) {
240 		this.rows = ruleTemplateAttributes;
241 	}
242 
243     @Override
244 	public String getToDateString() {
245 		return this.toDateString;
246 	}
247 
248 	public void setToDateString(String toDateString) {
249 		this.toDateString = toDateString;
250 	}
251 
252 	@Override
253 	public String getRuleTemplateName() {
254 		return ruleTemplateName;
255 	}
256 
257 	public void setRuleTemplateName(String ruleTemplateName) {
258 		this.ruleTemplateName = ruleTemplateName;
259 	}
260 
261 	public boolean isHasExtensionValueErrors() {
262 		return hasExtensionValueErrors;
263 	}
264 
265 	public void setHasExtensionValueErrors(boolean hasRuleExtensionValueErrors) {
266 		this.hasExtensionValueErrors = hasRuleExtensionValueErrors;
267 	}
268 
269 	/** Web Logic * */
270 
271 	/**
272 	 * Populates this WebRuleBaseValues object for editing the given rule.
273 	 */
274 	public void edit(RuleBaseValues rule) throws Exception {
275 		load(rule);
276 		initialize();
277 	}
278 
279 	/**
280 	 * Loads the given rule into this WebRuleBaseValues.
281 	 */
282 	public void load(RuleBaseValues rule) throws Exception {
283 		PropertyUtils.copyProperties(this, rule);
284 		injectWebMembers();
285 	}
286 
287 	public void initialize() throws Exception {
288 		loadFields();
289 		// setPreviousRuleId(getId());
290 		for (Object element : getRuleResponsibilities()) {
291 			WebRuleResponsibility responsibility = (WebRuleResponsibility) element;
292 			responsibility.initialize();
293 		}
294 		establishRequiredState();
295 	}
296 
297 	private void injectWebMembers() throws Exception {
298 		List currentResponsibilities = getRuleResponsibilities();
299 		setRuleResponsibilities(new ArrayList());
300 		for (Iterator iterator = currentResponsibilities.iterator(); iterator.hasNext();) {
301 			RuleResponsibilityBo responsibility = (RuleResponsibilityBo) iterator.next();
302 			WebRuleResponsibility webResponsibility = createNewRuleResponsibility();
303 			webResponsibility.load(responsibility);
304 		}
305 	}
306 
307 	/**
308 	 * Establishes any missing and required state in the WebRuleBaseValues.
309 	 */
310 	public void establishRequiredState() throws Exception {
311 		loadWebValues();
312 		if (getRuleResponsibilities().isEmpty()) {
313 			createNewRuleResponsibility();
314 		}
315 		for (Object element : getRuleResponsibilities()) {
316 			WebRuleResponsibility responsibility = (WebRuleResponsibility) element;
317 			responsibility.establishRequiredState();
318 		}
319 	}
320 
321 	@Override
322 	public RuleResponsibilityBo getResponsibility(int index) {
323 		while (getRuleResponsibilities().size() <= index) {
324 			createNewRuleResponsibility();
325 		}
326 		return getRuleResponsibilities().get(index);
327 	}
328 
329 	public int getResponsibilitiesSize() {
330 		return getRuleResponsibilities().size();
331 	}
332 
333 	public WebRuleResponsibility createNewRuleResponsibility() {
334 		WebRuleResponsibility responsibility = new WebRuleResponsibility();
335 		responsibility.setRuleBaseValues(this);
336 		addRuleResponsibility(responsibility);
337 		return responsibility;
338 	}
339 
340 	public Map getFieldMap(String ruleTemplateAttributeId) {
341 		Map fieldMap = new HashMap();
342 		for (Iterator iterator = getFields().iterator(); iterator.hasNext();) {
343 			KeyValueId field = (KeyValueId) iterator.next();
344 			if (ruleTemplateAttributeId.equals(field.getId())) {
345 				fieldMap.put(field.getKey(), field.getValue());
346 			}
347 		}
348 		return fieldMap;
349 	}
350 
351 	public void populatePreviousRuleIds() {
352 		if (getPreviousRuleId() == null) {
353 			setPreviousRuleId(getId());
354 		}
355 		for (Object element : getRuleResponsibilities()) {
356 			WebRuleResponsibility responsibility = (WebRuleResponsibility) element;
357 			responsibility.populatePreviousRuleIds();
358 		}
359 	}
360 
361 	/**
362 	 * This method is used to "materialize" the web rule before it gets saved, if we don't do this then certain fields will be saved as NULL. For example, ruleTemplate.
363 	 */
364 	public void materialize() {
365 		if (getRuleTemplate() == null && getRuleTemplateId() != null) {
366 			setRuleTemplate(getRuleTemplateService().findByRuleTemplateId(getRuleTemplateId()));
367 		}
368 	}
369 
370 	public void validateRule(String keyPrefix, ActionErrors errors) {
371 		/** Validate Template * */
372 		if (getRuleTemplateId() == null) {
373 			errors.add(keyPrefix + "ruleTemplateId", new ActionMessage("routetemplate.required.html", "rule template"));
374 		} else {
375 			List errorList = new ArrayList();
376 			populateRuleExtensionValues(errorList);
377 			saveServiceErrors(keyPrefix + "ruleExtensionValues", errorList, errors);
378 			if (!errorList.isEmpty()) {
379 				setHasExtensionValueErrors(true);
380 			}
381 		}
382 
383 		/** Validate dates * */
384 
385 		boolean dateParseProblem = false;
386 		try {
387 			setToDateValue(decodeTimestamp(getToDateString()));
388 		} catch (ParseException e) {
389 			errors.add(keyPrefix + "toDateValue", new ActionMessage("routetemplate.required.html", "to date (MM/DD/YYYY)"));
390 			dateParseProblem = true;
391 		}
392 		try {
393 			setFromDateValue(decodeTimestamp(getFromDateString()));
394 		} catch (ParseException e) {
395 			errors.add(keyPrefix + "fromDateValue", new ActionMessage("routetemplate.required.html", "from date (MM/DD/YYYY)"));
396 			dateParseProblem = true;
397 		}
398         throttleDates();
399 		if (getFromDateValue() == null) {
400 			setFromDateValue(new Timestamp(new Date().getTime()));
401 		}
402 		if (getToDateValue() == null) {
403 			try {
404 				setToDateValue(new Timestamp(new SimpleDateFormat("MM/dd/yyyy").parse("01/01/2100").getTime()));
405 			} catch (ParseException e) {
406 				errors.add(keyPrefix + "toDateValue", new ActionMessage("routetemplate.required.html", "to date"));
407 				dateParseProblem = true;
408 			}
409 		}
410 		if (!dateParseProblem && getToDateValue().before(getFromDateValue())) {
411 			errors.add(keyPrefix + "toDateValue", new ActionMessage("routetemplate.ruleservice.daterange.fromafterto"));
412 		}
413 
414 		if (org.apache.commons.lang.StringUtils.isEmpty(getDescription())) {
415 			errors.add(keyPrefix + "description", new ActionMessage("routetemplate.ruleservice.description.required"));
416 		}
417 
418 		if (getRuleResponsibilities().isEmpty()) {
419 			errors.add(keyPrefix + "responsibilities", new ActionMessage("routetemplate.ruleservice.responsibility.required"));
420 		}
421 
422 		int respIndex = 0;
423 		for (Object element : getRuleResponsibilities()) {
424 			WebRuleResponsibility responsibility = (WebRuleResponsibility) element;
425 			String respPrefix = keyPrefix + "responsibility[" + respIndex + "].";
426 			responsibility.validateResponsibility(respPrefix, errors);
427 			respIndex++;
428 		}
429 	}
430 
431     /**
432      * This will ensure that the toDate is never larger than 2100, currently
433      * doesn't do any throttling on the from date
434      */
435     private void throttleDates() {
436         if (getToDateValue() != null) {
437             Calendar calendar = Calendar.getInstance();
438             calendar.setTime(getToDateValue());
439             if (calendar.get(Calendar.YEAR) > TO_DATE_UPPER_LIMIT) {
440                 calendar.set(Calendar.YEAR, TO_DATE_UPPER_LIMIT);
441                 setToDateValue(new Timestamp(calendar.getTimeInMillis()));
442                 setToDateString(new SimpleDateFormat("MM/dd/yyyy").format(getToDateValue()));
443             }
444         }
445     }
446 
447 	private void saveServiceErrors(String errorKey, Collection srvErrors, ActionErrors errors) {
448 		for (Iterator iterator = srvErrors.iterator(); iterator.hasNext();) {
449 			WorkflowServiceError error = (WorkflowServiceError) iterator.next();
450 			if (error.getArg1() == null && error.getArg2() == null) {
451 				errors.add(errorKey, new ActionMessage(error.getKey()));
452 			} else if (error.getArg1() != null && error.getArg2() == null) {
453 				errors.add(errorKey, new ActionMessage(error.getKey(), error.getArg1()));
454 			} else {
455 				errors.add(errorKey, new ActionMessage(error.getKey(), error.getArg1(), error.getArg2()));
456 			}
457 		}
458 	}
459 
460 	private Timestamp decodeTimestamp(String dateValue) throws ParseException {
461 		if (org.apache.commons.lang.StringUtils.isEmpty(dateValue)) {
462 			return null;
463 		}
464 		/*  Not the best solution below but does allow our forcing of the 4 digit year
465 		 *  until KEW and use the KNS for it's date entry/validation
466 		 */
467 		String convertedDate = SQLUtils.getEntryFormattedDate(dateValue);
468 		if (convertedDate == null) {
469 		    throw new ParseException("Date entered as '" + dateValue + "' is in invalid format", 0);
470 		}
471 		Date date = RiceConstants.getDefaultDateFormat().parse(convertedDate);
472 		return new Timestamp(date.getTime());
473 	}
474 
475 	private void populateRuleExtensionValues(List errorList) {
476 		RuleTemplateBo ruleTemplate = getRuleTemplateService().findByRuleTemplateId(getRuleTemplateId());
477 		setRuleTemplate(ruleTemplate);
478 
479 		/** Populate rule extension values * */
480 		List extensions = new ArrayList();
481 		for (Object element : ruleTemplate.getActiveRuleTemplateAttributes()) {
482 			RuleTemplateAttributeBo ruleTemplateAttribute = (RuleTemplateAttributeBo) element;
483 			if (!ruleTemplateAttribute.isWorkflowAttribute()) {
484 				continue;
485 			}
486 			WorkflowRuleAttribute workflowAttribute = ruleTemplateAttribute.getWorkflowAttribute();
487 
488 			RuleAttribute ruleAttribute = ruleTemplateAttribute.getRuleAttribute();
489 			if (ruleAttribute.getType().equals(KewApiConstants.RULE_XML_ATTRIBUTE_TYPE)) {
490 				((GenericXMLRuleAttribute) workflowAttribute).setExtensionDefinition(RuleAttribute.to(ruleAttribute));
491 			}
492 
493 			List attValidationErrors = workflowAttribute.validateRuleData(getFieldMap(ruleTemplateAttribute.getId()+""));
494 			if (attValidationErrors != null && !attValidationErrors.isEmpty()) {
495 				errorList.addAll(attValidationErrors);
496 			} else {
497 				List ruleExtensionValues = workflowAttribute.getRuleExtensionValues();
498 				if (ruleExtensionValues != null && !ruleExtensionValues.isEmpty()) {
499 					RuleExtensionBo ruleExtension = new RuleExtensionBo();
500 					ruleExtension.setRuleTemplateAttributeId(ruleTemplateAttribute.getId());
501 
502 					ruleExtension.setExtensionValues(ruleExtensionValues);
503 					extensions.add(ruleExtension);
504 				}
505 			}
506 		}
507 		setRuleExtensions(extensions);
508 		setRuleTemplate(ruleTemplate);
509 
510 		for (Object element : getRuleExtensions()) {
511 			RuleExtensionBo ruleExtension = (RuleExtensionBo) element;
512 			ruleExtension.setRuleBaseValues(this);
513 
514 			for (Object element2 : ruleTemplate.getActiveRuleTemplateAttributes()) {
515 				RuleTemplateAttributeBo ruleTemplateAttribute = (RuleTemplateAttributeBo) element2;
516 				if (StringUtils.equals(ruleTemplateAttribute.getId(), ruleExtension.getRuleTemplateAttributeId())) {
517 					ruleExtension.setRuleTemplateAttribute(ruleTemplateAttribute);
518 					break;
519 				}
520 			}
521 
522 			for (Object element2 : ruleExtension.getExtensionValues()) {
523 				RuleExtensionValue ruleExtensionValue = (RuleExtensionValue) element2;
524 				ruleExtensionValue.setExtension(ruleExtension);
525 			}
526 		}
527 
528 	}
529 
530 	private RuleTemplateService getRuleTemplateService() {
531 		return (RuleTemplateService) KEWServiceLocator.getService(KEWServiceLocator.RULE_TEMPLATE_SERVICE);
532 	}
533 
534 	/**
535 	 * @return Returns the actionRequestCodes.
536 	 */
537 	public Map getActionRequestCodes() {
538 		Map actionRequestCodes = new HashMap();
539 		actionRequestCodes.putAll(CodeTranslator.arLabels);
540 		if (getRuleTemplateId() != null) {
541 			RuleTemplateBo ruleTemplate = getRuleTemplateService().findByRuleTemplateId(getRuleTemplateId());
542 			if (ruleTemplate != null) {
543 				if (ruleTemplate.getAcknowledge() != null && "false".equals(ruleTemplate.getAcknowledge().getValue())) {
544 					actionRequestCodes.remove(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ);
545 				}
546 				if (ruleTemplate.getComplete() != null && "false".equals(ruleTemplate.getComplete().getValue())) {
547 					actionRequestCodes.remove(KewApiConstants.ACTION_REQUEST_COMPLETE_REQ);
548 				}
549 				if (ruleTemplate.getApprove() != null && "false".equals(ruleTemplate.getApprove().getValue())) {
550 					actionRequestCodes.remove(KewApiConstants.ACTION_REQUEST_APPROVE_REQ);
551 				}
552 				if (ruleTemplate.getFyi() != null && "false".equals(ruleTemplate.getFyi().getValue())) {
553 					actionRequestCodes.remove(KewApiConstants.ACTION_REQUEST_FYI_REQ);
554 				}
555 			}
556 		}
557 		return actionRequestCodes;
558 	}
559 
560 	public RuleDelegationBo getRuleDelegation() {
561 		if (getDelegateRule().booleanValue()) {
562 			List ruleDelegations = getRuleDelegationService().findByDelegateRuleId(getId());
563 			RuleDelegationBo currentRuleDelegation = (RuleDelegationBo) ruleDelegations.get(0);
564 			RuleBaseValues mostRecentRule = currentRuleDelegation.getRuleResponsibility().getRuleBaseValues();
565 
566 			for (Iterator iter = ruleDelegations.iterator(); iter.hasNext();) {
567 				RuleDelegationBo ruleDelegation = (RuleDelegationBo) iter.next();
568 				RuleBaseValues parentRule = ruleDelegation.getRuleResponsibility().getRuleBaseValues();
569 
570 				if (parentRule.getActivationDate().after(mostRecentRule.getActivationDate())) {
571 					mostRecentRule = ruleDelegation.getRuleResponsibility().getRuleBaseValues();
572 					currentRuleDelegation = ruleDelegation;
573 				}
574 			}
575 			return currentRuleDelegation;
576 		}
577 		return null;
578 	}
579 
580 	public String getParentRuleId() {
581 		if (getDelegateRule().booleanValue()) {
582 			List ruleDelegations = getRuleDelegationService().findByDelegateRuleId(getId());
583 			RuleDelegationBo currentRuleDelegation = (RuleDelegationBo) ruleDelegations.get(0);
584 			RuleBaseValues mostRecentRule = currentRuleDelegation.getRuleResponsibility().getRuleBaseValues();
585 
586 			for (Iterator iter = ruleDelegations.iterator(); iter.hasNext();) {
587 				RuleDelegationBo ruleDelegation = (RuleDelegationBo) iter.next();
588 				RuleBaseValues parentRule = ruleDelegation.getRuleResponsibility().getRuleBaseValues();
589 
590 				if (parentRule.getActivationDate().after(mostRecentRule.getActivationDate())) {
591 					mostRecentRule = ruleDelegation.getRuleResponsibility().getRuleBaseValues();
592 				}
593 			}
594 			return mostRecentRule.getId();
595 		}
596 		return null;
597 	}
598 
599 	private RuleDelegationService getRuleDelegationService() {
600 		return (RuleDelegationService) KEWServiceLocator.getService(KEWServiceLocator.RULE_DELEGATION_SERVICE);
601 	}
602 }