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 org.apache.log4j.Logger;
19 import org.kuali.rice.core.api.exception.RiceIllegalStateException;
20 import org.kuali.rice.kew.api.KewApiServiceLocator;
21 import org.kuali.rice.kew.api.WorkflowRuntimeException;
22 import org.kuali.rice.kew.api.exception.WorkflowException;
23 import org.kuali.rice.kew.engine.RouteContext;
24
25 import javax.script.ScriptEngine;
26 import javax.script.ScriptEngineManager;
27 import javax.script.ScriptException;
28
29
30
31
32
33
34
35
36
37 public class BSFRuleExpression implements RuleExpression {
38 private static final Logger LOG = Logger.getLogger(BSFRuleExpression.class);
39
40 public RuleExpressionResult evaluate(Rule rule, RouteContext context) {
41 org.kuali.rice.kew.api.rule.RuleContract ruleDefinition = rule.getDefinition();
42 String name = "" + ruleDefinition.getName();
43 String type = ruleDefinition.getRuleExpressionDef().getType();
44 String lang = parseLang(type, "groovy");
45 String expression = ruleDefinition.getRuleExpressionDef().getExpression();
46 RuleExpressionResult result;
47 ScriptEngineManager factory = new ScriptEngineManager();
48 ScriptEngine engine = factory.getEngineByName(lang);
49 try {
50 declareBeans(engine, rule, context);
51 result = (RuleExpressionResult) engine.eval(expression);
52 } catch (ScriptException e) {
53 String details = ( e.getLineNumber() >= 0 ? " line: " + e.getLineNumber() + " column: " + e.getColumnNumber() : "" );
54 LOG.debug("Error evaluating rule '" + name + "' " + type + " expression" + details + ": '" + expression + "'" + details, e);
55 throw new RiceIllegalStateException("Error evaluating rule '" + name + "' " + type + " expression" + details, e);
56 }
57 if (result == null) {
58 return new RuleExpressionResult(rule, false);
59 } else {
60 return result;
61 }
62 }
63
64
65
66
67
68
69
70 protected String parseLang(String type, String deflt) {
71 int colon = type.indexOf(':');
72 if (colon > -1) {
73 return type.substring(colon + 1);
74 } else {
75 return deflt;
76 }
77 }
78
79
80
81
82
83
84
85
86 protected void declareBeans(ScriptEngine engine, Rule rule, RouteContext context) throws ScriptException {
87 engine.put("rule", rule);
88 engine.put("routeContext", context);
89 engine.put("workflow", new WorkflowRuleAPI(context));
90 }
91
92
93
94
95
96
97
98 protected static final class WorkflowRuleAPI {
99 private final RouteContext context;
100 WorkflowRuleAPI(RouteContext context) {
101 this.context = context;
102 }
103
104
105
106
107
108
109 public RuleExpressionResult invokeRule(String name) throws WorkflowException {
110 org.kuali.rice.kew.api.rule.Rule rbv = KewApiServiceLocator.getRuleService().getRuleByName(name);
111 if (rbv == null) throw new WorkflowRuntimeException("Could not find rule named \"" + name + "\"");
112 Rule r = new RuleImpl(rbv);
113 return r.evaluate(r, context);
114 }
115 }
116 }