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 processEngineResults(context, engineResults);
71 return peopleFlowRouteModule.findActionRequests(context);
72 }
73
74 @Override
75 public ResponsibleParty resolveResponsibilityId(String responsibilityId) throws WorkflowException {
76 return null;
77 }
78
79 @Override
80 public boolean isMoreRequestsAvailable(RouteContext context) {
81 return peopleFlowRouteModule.isMoreRequestsAvailable(context);
82 }
83
84 protected EngineResults executeRulesEngine(RouteContext context, Engine rulesEngine) {
85 RulesEngineExecutor executor = loadRulesEngineExecutor(context);
86 return executor.execute(context, rulesEngine);
87 }
88
89 protected void processEngineResults(RouteContext context, EngineResults engineResults) {
90 String peopleFlowsSelected = (String)engineResults.getAttribute(PEOPLE_FLOWS_SELECTED_ATTRIBUTE);
91 if (StringUtils.isBlank(peopleFlowsSelected)) {
92 LOG.info("No PeopleFlows returned from KRMS execution.");
93 } else {
94 LOG.info("PeopleFlows returned from KRMS execution: " + peopleFlowsSelected);
95 }
96 NodeState nodeState = context.getNodeInstance().getNodeState(PeopleFlowRouteModule.PEOPLE_FLOW_SEQUENCE);
97 if (nodeState == null) {
98 nodeState = new NodeState();
99 nodeState.setNodeInstance(context.getNodeInstance());
100 nodeState.setKey(PeopleFlowRouteModule.PEOPLE_FLOW_SEQUENCE);
101 context.getNodeInstance().addNodeState(nodeState);
102 }
103 nodeState.setValue(peopleFlowsSelected);
104 if (!context.isSimulation()) {
105 routeNodeService.save(nodeState);
106 }
107 }
108
109 protected RulesEngineExecutor loadRulesEngineExecutor(RouteContext context) {
110 RouteNode routeNode = context.getNodeInstance().getRouteNode();
111 Element rulesEngineElement = RouteNodeUtils.getCustomRouteNodeElement(
112 context.getNodeInstance().getRouteNode(), RULES_ENGINE_ELEMENT);
113 if (rulesEngineElement == null) {
114 throw new ConfigurationException("Failed to located rules engine configuration for route node: " + routeNode.getName());
115 }
116 String executorName = rulesEngineElement.getAttribute(EXECUTOR_NAME_ATTRIBUTE);
117 String executorClassName = rulesEngineElement.getAttribute(EXECUTOR_CLASS_ATTRIBUTE);
118 if (StringUtils.isBlank(executorName) && StringUtils.isBlank(executorClassName)) {
119 throw new ConfigurationException("Failed to resolve a valid executor name or class name from rules engine configuration, was null or blank.");
120 }
121 RulesEngineExecutor rulesEngineExecutor = null;
122 if (StringUtils.isNotBlank(executorClassName)) {
123 rulesEngineExecutor = GlobalResourceLoader.getObject(new ObjectDefinition(executorClassName));
124 } else if (StringUtils.isNotBlank(executorName)) {
125 ExtensionDefinition extensionDefinition = getExtensionRepositoryService().getExtensionByName(executorName);
126 if (extensionDefinition != null) {
127 rulesEngineExecutor = ExtensionUtils.loadExtension(extensionDefinition);
128 }
129 }
130 if (rulesEngineExecutor == null) {
131 throw new ConfigurationException("Failed to load RulesEngineExecutor for either executorName=" + executorName + " or executorClass=" + executorClassName);
132 }
133 return rulesEngineExecutor;
134 }
135
136 protected Engine getRulesEngine() {
137 if (rulesEngine == null) {
138 rulesEngine = KrmsApiServiceLocator.getEngine();
139 }
140 return rulesEngine;
141 }
142
143 public PeopleFlowRouteModule getPeopleFlowRouteModule() {
144 return peopleFlowRouteModule;
145 }
146
147 public void setPeopleFlowRouteModule(PeopleFlowRouteModule peopleFlowRouteModule) {
148 this.peopleFlowRouteModule = peopleFlowRouteModule;
149 }
150
151 public ExtensionRepositoryService getExtensionRepositoryService() {
152 return extensionRepositoryService;
153 }
154
155 public void setExtensionRepositoryService(ExtensionRepositoryService extensionRepositoryService) {
156 this.extensionRepositoryService = extensionRepositoryService;
157 }
158
159 public RouteNodeService getRouteNodeService() {
160 return routeNodeService;
161 }
162
163 public void setRouteNodeService(RouteNodeService routeNodeService) {
164 this.routeNodeService = routeNodeService;
165 }
166
167 }