1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.rule;
17
18 import java.text.ParseException;
19
20 import org.apache.commons.lang.StringUtils;
21 import org.apache.log4j.Logger;
22 import org.kuali.rice.core.api.exception.RiceIllegalStateException;
23 import org.kuali.rice.kew.api.KewApiServiceLocator;
24 import org.kuali.rice.kew.engine.RouteContext;
25
26
27
28
29
30
31 public class KRAMetaRuleEngine {
32 private static final Logger LOG = Logger.getLogger(KRAMetaRuleEngine.class);
33
34
35
36
37 private static enum KRA_RULE_FLAG {
38 NEXT, TRUE, FALSE
39 }
40
41 private final String expression;
42 private final String[] statements;
43 private int curStatement = 0;
44
45
46
47 private boolean stop = false;
48
49 public KRAMetaRuleEngine(String expression) throws ParseException {
50 this.expression = expression;
51 statements = expression.split("\\s*[;\r\n]\\s*");
52
53 if (statements.length == 0) {
54 throw new ParseException("No statements parsed in expression: " + expression, 0);
55 }
56 }
57
58
59
60
61 public String getExpression() {
62 return expression;
63 }
64
65
66
67
68 public String[] getStatements() {
69 return statements;
70 }
71
72
73
74
75 public int getCurStatement() {
76 return curStatement;
77 }
78
79
80
81
82 public void setCurStatement(int statementNo) {
83 this.curStatement = statementNo;
84 }
85
86
87
88
89 public boolean isDone() {
90 return curStatement >= statements.length || stop;
91 }
92
93
94
95
96
97
98
99 public RuleExpressionResult processSingleStatement(RouteContext context) throws ParseException {
100 if (isDone()) {
101 return null;
102 }
103
104 int stmtNum = curStatement + 1;
105 String statement = statements[curStatement];
106 LOG.debug("Processing statement: " + statement);
107 String[] words = statement.split("\\s*:\\s*");
108 if (words.length < 2) {
109 throw new ParseException("Invalid statement (#" + stmtNum + "): " + statement, 0);
110 }
111 String ruleName = words[0];
112 if (StringUtils.isEmpty(ruleName)) {
113 throw new ParseException("Invalid rule in statement (#" + stmtNum + "): " + statement, 0);
114 }
115 String flag = words[1];
116 LOG.debug(flag.toUpperCase());
117 KRA_RULE_FLAG flagCode = KRA_RULE_FLAG.valueOf(flag.toUpperCase());
118 if (flagCode == null) {
119 throw new ParseException("Invalid flag in statement (#" + stmtNum + "): " + statement, 0);
120 }
121 org.kuali.rice.kew.api.rule.Rule nestedRule = KewApiServiceLocator.getRuleService().getRuleByName(ruleName);
122 if (nestedRule == null) {
123 throw new ParseException("Rule '" + ruleName + "' in statement (#" + stmtNum + ") not found: " + statement, 0);
124 }
125
126 Rule rule = new RuleImpl(nestedRule);
127 RuleExpressionResult result;
128 switch (flagCode) {
129 case NEXT:
130 result = rule.evaluate(rule, context);
131 break;
132 case TRUE:
133 result = rule.evaluate(rule, context);
134 if (!result.isSuccess()) {
135 stop = true;
136 }
137 break;
138 case FALSE:
139 result = rule.evaluate(rule, context);
140 if (result.isSuccess()) {
141 stop = true;
142
143
144 result = new RuleExpressionResult(rule, false, result.getResponsibilities());
145 }
146 break;
147 default:
148 throw new RiceIllegalStateException("Unhandled statement flag: " + flagCode);
149 }
150
151 curStatement++;
152 LOG.debug("Result of statement '" + statement + "': " + result);
153 return result;
154 }
155 }