View Javadoc

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 org.apache.log4j.Logger;
19  import org.kuali.rice.kew.engine.RouteContext;
20  import org.kuali.rice.kew.exception.WorkflowException;
21  
22  import javax.script.ScriptEngine;
23  import javax.script.ScriptException;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  /**
28   * An extension of BSFRuleExpression that makes it easier to accumulate a list of responsibilities
29   * to emit. 
30   * 
31   * @author Kuali Rice Team (rice.collab@kuali.org)
32   */
33  public class AccumulatingBSFRuleExpression extends BSFRuleExpression {
34      private static final Logger LOG = Logger.getLogger(AccumulatingBSFRuleExpression.class);
35  
36      @Override
37      protected void declareBeans(ScriptEngine engine, Rule rule, RouteContext context) throws ScriptException {
38          // define the standard beans
39          super.declareBeans(engine, rule, context);
40          // define our special rule helper class
41          RuleHelper rh = new RuleHelper(rule, context);
42          engine.put("metarule", rh); // backwards compatibility with existing KRAMetaRuleExpression usage
43          engine.put("rulehelper", rh);
44      }
45  
46      /**
47       * Helper class that is exposed to groovy scripts
48       */
49      private static final class RuleHelper {
50          private Rule rule;
51          private WorkflowRuleAPI workflow;
52          /**
53           * Responsibilities accumulated during the evaluation
54           */
55          private List<RuleResponsibility> responsibilities = new ArrayList<RuleResponsibility>();
56          private int responsibilityPriority = 0;
57  
58          private RuleHelper(Rule rule, RouteContext context) {
59              this.workflow = new WorkflowRuleAPI(context);
60              this.rule = rule;
61          }
62  
63          /**
64           * @return the accumulated responsibilities
65           */
66          public List<RuleResponsibility> getResponsibilities() {
67              return responsibilities;
68          }
69  
70          /**
71           * @param success whether the result should be successful
72           * @return the RuleExpressionResult with success flag and accumulated responsibilities
73           */
74          public RuleExpressionResult getResult(boolean success) {
75              return new RuleExpressionResult(rule, success, responsibilities);
76          }
77  
78          /**
79           * Adds the responsibilities in the result to the list of accumulated responsibilities 
80           * @param result a RuleExpressionResult whose responsibilities to accumulate
81           */
82          public void accumulate(RuleExpressionResult result) {
83              if (result.getResponsibilities() == null || result.getResponsibilities().size() == 0) return;
84  
85              Integer curPriority = Integer.valueOf(responsibilityPriority);
86              for (RuleResponsibility responsibility: result.getResponsibilities()) {
87                  responsibility.setPriority(curPriority);
88                  responsibilities.add(responsibility);
89              }
90              // increment responsibilityPriority for next rule expression result responsibilities
91              responsibilityPriority++;
92          }
93  
94          /**
95           * Evaluates a named rule accumulating responsibilities regardless of rule success
96           * @param ruleName the name of the rule to evaluate
97           * @return whether the rule was successful
98           */
99          public boolean evalRule(String ruleName) throws WorkflowException {
100             RuleExpressionResult result = workflow.invokeRule(ruleName);
101             accumulate(result);
102             return result.isSuccess();
103         }
104 
105         /**
106          * Evaluates a named rule and if it is successful accumulates the rule responsibilities
107          * @param ruleName the name of the rule to evaluate
108          * @param accumOnSuccess whether to accumulate the rules responsibilities on success (true), or on failure (false)
109          * @return whether the rule was successful
110          */
111         public boolean evalRule(String ruleName, boolean accumOnSuccess) throws WorkflowException {
112             RuleExpressionResult result = workflow.invokeRule(ruleName);
113             if (accumOnSuccess == result.isSuccess()) {
114                 accumulate(result);
115             }
116             return result.isSuccess();
117         }
118 
119     }
120 }