Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
MetaRuleExpression |
|
| 7.5;7.5 |
1 | /* | |
2 | * Copyright 2007-2008 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; | |
17 | ||
18 | import java.text.ParseException; | |
19 | import java.util.ArrayList; | |
20 | import java.util.List; | |
21 | ||
22 | import org.apache.commons.lang.StringUtils; | |
23 | import org.apache.log4j.Logger; | |
24 | import org.kuali.rice.kew.engine.RouteContext; | |
25 | import org.kuali.rice.kew.exception.WorkflowException; | |
26 | ||
27 | ||
28 | /** | |
29 | * Expression implementation for "meta rules". A "meta rule" consists of a sequence of | |
30 | * subordinate rule evaluations each processed according to an associated modifier: | |
31 | * <dl> | |
32 | * <dt>next<dt> | |
33 | * <dd>proceed with rule evaluation</dd> | |
34 | * <dt>true</dt> | |
35 | * <dd>if this rule evaluates to true, then return the responsibilities associated with the rule</dd> | |
36 | * <dt>false</dt> | |
37 | * <dd>if this rule evaluates to false, then return the responsibilities associated with the rule</dd> | |
38 | * </dl> | |
39 | * E.g. | |
40 | * <div><tt>bizRule1: next; bizRule2: true; bizRule3: false</tt></div> | |
41 | * @author Kuali Rice Team (rice.collab@kuali.org) | |
42 | */ | |
43 | 0 | public class MetaRuleExpression extends AccumulatingBSFRuleExpression { |
44 | 0 | private static final Logger LOG = Logger.getLogger(MetaRuleExpression.class); |
45 | ||
46 | @Override | |
47 | public RuleExpressionResult evaluate(Rule rule, RouteContext context) throws WorkflowException { | |
48 | 0 | RuleBaseValues ruleDefinition = rule.getDefinition(); |
49 | 0 | RuleExpressionDef exprDef = ruleDefinition.getRuleExpressionDef(); |
50 | 0 | if (exprDef == null) { |
51 | 0 | throw new WorkflowException("No expression defined in rule definition: " + ruleDefinition); |
52 | } | |
53 | 0 | String expression = exprDef.getExpression(); |
54 | 0 | if (StringUtils.isEmpty(expression)) { |
55 | 0 | throw new WorkflowException("Empty expression in rule definition: " + ruleDefinition); |
56 | } | |
57 | ||
58 | 0 | String lang = parseLang(ruleDefinition.getRuleExpressionDef().getType(), null); |
59 | 0 | if (lang == null) { |
60 | // if no language qualifier is specified, parse it as a built-in meta rule expression | |
61 | 0 | return evaluateBuiltinExpression(expression, rule, context); |
62 | } else { | |
63 | 0 | return super.evaluate(rule, context); |
64 | } | |
65 | } | |
66 | ||
67 | /** | |
68 | * Evaluates the builtin "meta" rule expression | |
69 | * @param expression the builtin meta rule expression | |
70 | * @param rule the rule | |
71 | * @param context the route context | |
72 | * @return RuleExpressionResult the result | |
73 | * @throws WorkflowException | |
74 | */ | |
75 | private RuleExpressionResult evaluateBuiltinExpression(String expression, Rule rule, RouteContext context) throws WorkflowException { | |
76 | try { | |
77 | 0 | KRAMetaRuleEngine engine = new KRAMetaRuleEngine(expression); |
78 | ||
79 | 0 | int responsibilityPriority = 0; // responsibility priority, lower value means higher priority (due to sort)...increment as we go |
80 | 0 | RuleExpressionResult result = null; |
81 | 0 | boolean success = false; |
82 | 0 | List<RuleResponsibility> responsibilities = new ArrayList<RuleResponsibility>(); |
83 | 0 | while (!engine.isDone()) { |
84 | 0 | result = engine.processSingleStatement(context); |
85 | 0 | if (result.isSuccess() && result.getResponsibilities() != null) { |
86 | // accumulate responsibilities if the evaluation was successful | |
87 | // make sure to reduce priority for each subsequent rule in order for sequential activation to work as desired | |
88 | 0 | for (RuleResponsibility responsibility: result.getResponsibilities()) { |
89 | 0 | responsibility.setPriority(Integer.valueOf(responsibilityPriority)); |
90 | 0 | responsibilities.add(responsibility); |
91 | } | |
92 | // decrement responsibilityPriority for next rule expression result responsibilities | |
93 | 0 | responsibilityPriority++; |
94 | 0 | success = true; |
95 | } | |
96 | } | |
97 | 0 | result = new RuleExpressionResult(rule, success, responsibilities); |
98 | 0 | LOG.debug("KRAMetaRuleExpression returning result: " + result); |
99 | 0 | return result; |
100 | 0 | } catch (ParseException pe) { |
101 | 0 | throw new WorkflowException("Error parsing expression", pe); |
102 | } | |
103 | } | |
104 | } |