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