1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.impl.support.krms;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.log4j.Logger;
20 import org.kuali.rice.core.api.config.ConfigurationException;
21 import org.kuali.rice.core.api.reflect.ObjectDefinition;
22 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
23 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
24 import org.kuali.rice.kew.api.exception.WorkflowException;
25 import org.kuali.rice.kew.api.extension.ExtensionDefinition;
26 import org.kuali.rice.kew.api.extension.ExtensionRepositoryService;
27 import org.kuali.rice.kew.api.extension.ExtensionUtils;
28 import org.kuali.rice.kew.engine.RouteContext;
29 import org.kuali.rice.kew.engine.node.NodeState;
30 import org.kuali.rice.kew.engine.node.RouteNode;
31 import org.kuali.rice.kew.engine.node.RouteNodeUtils;
32 import org.kuali.rice.kew.engine.node.service.RouteNodeService;
33 import org.kuali.rice.kew.framework.support.krms.RulesEngineExecutor;
34 import org.kuali.rice.kew.impl.peopleflow.PeopleFlowRouteModule;
35 import org.kuali.rice.kew.routemodule.RouteModule;
36 import org.kuali.rice.kew.util.ResponsibleParty;
37 import org.kuali.rice.krms.api.KrmsApiServiceLocator;
38 import org.kuali.rice.krms.api.engine.Engine;
39 import org.kuali.rice.krms.api.engine.EngineResults;
40 import org.w3c.dom.Element;
41
42 import java.util.List;
43
44
45
46
47
48
49
50
51
52 public class RulesEngineRouteModule implements RouteModule {
53
54 private static final Logger LOG = Logger.getLogger(RulesEngineRouteModule.class);
55
56 private static final String RULES_ENGINE_ELEMENT = "rulesEngine";
57 private static final String EXECUTOR_NAME_ATTRIBUTE = "executorName";
58 private static final String EXECUTOR_CLASS_ATTRIBUTE = "executorClass";
59 private static final String PEOPLE_FLOWS_SELECTED_ATTRIBUTE = "peopleFlowsSelected";
60
61 private volatile Engine rulesEngine;
62
63 private PeopleFlowRouteModule peopleFlowRouteModule;
64 private ExtensionRepositoryService extensionRepositoryService;
65 private RouteNodeService routeNodeService;
66
67 @Override
68 public List<ActionRequestValue> findActionRequests(RouteContext context) throws Exception {
69 EngineResults engineResults = executeRulesEngine(context, getRulesEngine());
70 if (engineResults != null) {
71 processEngineResults(context, engineResults);
72 }
73 return peopleFlowRouteModule.findActionRequests(context);
74 }
75
76 @Override
77 public ResponsibleParty resolveResponsibilityId(String responsibilityId) throws WorkflowException {
78 return null;
79 }
80
81 @Override
82 public boolean isMoreRequestsAvailable(RouteContext context) {
83 return peopleFlowRouteModule.isMoreRequestsAvailable(context);
84 }
85
86 protected EngineResults executeRulesEngine(RouteContext context, Engine rulesEngine) {
87 RulesEngineExecutor executor = loadRulesEngineExecutor(context);
88 return executor.execute(context, rulesEngine);
89 }
90
91 protected void processEngineResults(RouteContext context, EngineResults engineResults) {
92 String peopleFlowsSelected = (String)engineResults.getAttribute(PEOPLE_FLOWS_SELECTED_ATTRIBUTE);
93 if (StringUtils.isBlank(peopleFlowsSelected)) {
94 LOG.info("No PeopleFlows returned from KRMS execution.");
95 } else {
96 LOG.info("PeopleFlows returned from KRMS execution: " + peopleFlowsSelected);
97 }
98 NodeState nodeState = context.getNodeInstance().getNodeState(PeopleFlowRouteModule.PEOPLE_FLOW_SEQUENCE);
99 if (nodeState == null) {
100 nodeState = new NodeState();
101 nodeState.setNodeInstance(context.getNodeInstance());
102 nodeState.setKey(PeopleFlowRouteModule.PEOPLE_FLOW_SEQUENCE);
103 context.getNodeInstance().addNodeState(nodeState);
104 }
105 nodeState.setValue(peopleFlowsSelected);
106 if (!context.isSimulation()) {
107 routeNodeService.save(nodeState);
108 }
109 }
110
111 protected RulesEngineExecutor loadRulesEngineExecutor(RouteContext context) {
112 RouteNode routeNode = context.getNodeInstance().getRouteNode();
113 Element rulesEngineElement = RouteNodeUtils.getCustomRouteNodeElement(
114 context.getNodeInstance().getRouteNode(), RULES_ENGINE_ELEMENT);
115 if (rulesEngineElement == null) {
116 throw new ConfigurationException("Failed to located rules engine configuration for route node: " + routeNode.getName());
117 }
118 String executorName = rulesEngineElement.getAttribute(EXECUTOR_NAME_ATTRIBUTE);
119 String executorClassName = rulesEngineElement.getAttribute(EXECUTOR_CLASS_ATTRIBUTE);
120 if (StringUtils.isBlank(executorName) && StringUtils.isBlank(executorClassName)) {
121 throw new ConfigurationException("Failed to resolve a valid executor name or class name from rules engine configuration, was null or blank.");
122 }
123 RulesEngineExecutor rulesEngineExecutor = null;
124 if (StringUtils.isNotBlank(executorClassName)) {
125 rulesEngineExecutor = GlobalResourceLoader.getObject(new ObjectDefinition(executorClassName));
126 } else if (StringUtils.isNotBlank(executorName)) {
127 ExtensionDefinition extensionDefinition = getExtensionRepositoryService().getExtensionByName(executorName);
128 if (extensionDefinition != null) {
129 rulesEngineExecutor = ExtensionUtils.loadExtension(extensionDefinition);
130 }
131 }
132 if (rulesEngineExecutor == null) {
133 throw new ConfigurationException("Failed to load RulesEngineExecutor for either executorName=" + executorName + " or executorClass=" + executorClassName);
134 }
135 return rulesEngineExecutor;
136 }
137
138 protected Engine getRulesEngine() {
139 if (rulesEngine == null) {
140 rulesEngine = KrmsApiServiceLocator.getEngine();
141 }
142 return rulesEngine;
143 }
144
145 public PeopleFlowRouteModule getPeopleFlowRouteModule() {
146 return peopleFlowRouteModule;
147 }
148
149 public void setPeopleFlowRouteModule(PeopleFlowRouteModule peopleFlowRouteModule) {
150 this.peopleFlowRouteModule = peopleFlowRouteModule;
151 }
152
153 public ExtensionRepositoryService getExtensionRepositoryService() {
154 return extensionRepositoryService;
155 }
156
157 public void setExtensionRepositoryService(ExtensionRepositoryService extensionRepositoryService) {
158 this.extensionRepositoryService = extensionRepositoryService;
159 }
160
161 public RouteNodeService getRouteNodeService() {
162 return routeNodeService;
163 }
164
165 public void setRouteNodeService(RouteNodeService routeNodeService) {
166 this.routeNodeService = routeNodeService;
167 }
168
169 }