View Javadoc

1   /**
2    * Copyright 2005-2011 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.joda.time.DateTime;
19  import org.kuali.rice.kew.api.KewApiServiceLocator;
20  import org.kuali.rice.kew.api.WorkflowRuntimeException;
21  import org.kuali.rice.kew.engine.RouteContext;
22  import org.kuali.rice.kew.engine.node.RouteNodeInstance;
23  import org.kuali.rice.kew.routeheader.DocumentContent;
24  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
25  import org.kuali.rice.kew.rule.bo.RuleTemplateAttributeBo;
26  import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
27  import org.kuali.rice.kew.service.KEWServiceLocator;
28  import org.kuali.rice.kew.util.PerformanceLogger;
29  
30  import java.sql.Timestamp;
31  import java.util.ArrayList;
32  import java.util.Collections;
33  import java.util.HashSet;
34  import java.util.List;
35  import java.util.Set;
36  
37  /**
38   * Rule selector that selects rules based on configured template name 
39   * @author Kuali Rice Team (rice.collab@kuali.org)
40   */
41  class TemplateRuleSelector implements RuleSelector {
42      /**
43       * Records the number of selected rules, prior to MassRuleAttribute filtering
44       */
45      private int numberOfSelectedRules;
46  
47      /**
48       * @return the number of selected rules, prior to MassRuleAttribute filtering
49       */
50      int getNumberOfSelectedRules() {
51  	return numberOfSelectedRules;
52      }
53  
54      public List<Rule> selectRules(RouteContext context, DocumentRouteHeaderValue routeHeader, RouteNodeInstance nodeInstance, String selectionCriterion, Timestamp effectiveDate) {
55          // for TemplateRuleSelector, the criterion is taken as a ruletemplate name
56          final String ruleTemplateName = selectionCriterion;
57  
58          Set<MassRuleAttribute> massRules = new HashSet<MassRuleAttribute>();
59          RuleTemplateBo template = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateName(ruleTemplateName);
60          //RuleTemplate template = KewApiServiceLocator.getRuleService().getRuleTemplateByName(ruleTemplateName);
61          if (template == null) {
62              throw new WorkflowRuntimeException("Could not locate the rule template with name " + ruleTemplateName + " on document " + routeHeader.getDocumentId());
63          }
64          for (RuleTemplateAttributeBo templateAttribute : template.getActiveRuleTemplateAttributes()) {
65              if (!templateAttribute.isWorkflowAttribute()) {
66              continue;
67              }
68              WorkflowRuleAttribute attribute = templateAttribute.getWorkflowAttribute();
69              if (attribute instanceof MassRuleAttribute) {
70              massRules.add((MassRuleAttribute) attribute);
71              }
72  
73          }
74  
75          List<org.kuali.rice.kew.api.rule.Rule> rules = Collections.emptyList();
76          if (effectiveDate == null) {
77              rules = KewApiServiceLocator.getRuleService()
78                      .getRulesByTemplateNameAndDocumentTypeName(ruleTemplateName,
79                              routeHeader.getDocumentType().getName());
80          } else {
81              rules = KewApiServiceLocator.getRuleService()
82                      .getRulesByTemplateNameAndDocumentTypeNameAndEffectiveDate(ruleTemplateName,
83                              routeHeader.getDocumentType().getName(), new DateTime(effectiveDate.getTime()));
84          }
85          numberOfSelectedRules = rules.size();
86  
87          // TODO really the route context just needs to be able to support nested create and clears
88          // (i.e. a Stack model similar to transaction intercepting in Spring) and we wouldn't have to do this
89          if (context.getDocument() == null) {
90              context.setDocument(routeHeader);
91          }
92          if (context.getNodeInstance() == null) {
93              context.setNodeInstance(nodeInstance);
94          }
95          DocumentContent documentContent = context.getDocumentContent();
96          PerformanceLogger performanceLogger = new PerformanceLogger();
97          // have all mass rule attributes filter the list of non applicable rules
98          for (MassRuleAttribute massRuleAttribute : massRules) {
99              rules = massRuleAttribute.filterNonMatchingRules(context, rules);
100         }
101         performanceLogger.log("Time to filter massRules for template " + template.getName());
102 
103         List<Rule> ruleList = new ArrayList<Rule>(rules.size());
104         for (org.kuali.rice.kew.api.rule.Rule ruleDefinition: rules) {
105             ruleList.add(new RuleImpl(ruleDefinition));
106         }
107         return ruleList;
108     }
109 
110 }