1
2
3
4
5 package gboat2.serviceflow.service.impl;
6
7 import gboat2.serviceflow.JBPMHelper;
8 import gboat2.serviceflow.business.IJbpmWorkFlowBusiness;
9 import gboat2.serviceflow.model.ProcessInfo;
10 import gboat2.serviceflow.service.IFlowFilter;
11 import gboat2.serviceflow.service.IServiceFlowService;
12 import gboat2.serviceflow.service.ServiceFlowException;
13 import gboat2.serviceflow.util.WorkflowUtil;
14
15 import java.net.URL;
16 import java.util.Comparator;
17 import java.util.HashMap;
18 import java.util.Iterator;
19 import java.util.LinkedList;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.TreeMap;
23
24 import org.apache.commons.lang3.StringUtils;
25 import org.drools.builder.KnowledgeBuilder;
26 import org.drools.builder.KnowledgeBuilderError;
27 import org.drools.builder.KnowledgeBuilderErrors;
28 import org.drools.builder.ResourceType;
29 import org.drools.definition.process.Connection;
30 import org.drools.definition.process.Node;
31 import org.drools.io.Resource;
32 import org.drools.io.ResourceFactoryService;
33 import org.jbpm.workflow.core.node.HumanTaskNode;
34 import org.jbpm.workflow.core.node.Join;
35 import org.jbpm.workflow.core.node.Split;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38 import org.springframework.beans.factory.annotation.Autowired;
39
40
41
42
43
44
45
46
47
48 public class ServiceFlowServiceImpl implements IServiceFlowService {
49
50 private Logger logger = LoggerFactory.getLogger(ServiceFlowServiceImpl.class);
51
52 @Autowired
53 private IJbpmWorkFlowBusiness workflowService;
54
55 private Map<String,URL> picturePaths = new HashMap<String,URL>();
56
57 private Map<ProcessDefine,IFlowFilter> processes = new TreeMap<ProcessDefine,IFlowFilter>(new Comparator<ProcessDefine>(){
58
59 @Override
60 public int compare(ProcessDefine o1, ProcessDefine o2) {
61 if(o1.getPriority()!=o2.getPriority()){
62 return o1.getPriority()-o2.getPriority();
63 }else{
64 return o1.getProcessId().compareTo(o2.getProcessId());
65 }
66 }});
67
68
69
70
71
72 @Override
73 public void completeTask(String businessObjectId, String nodeName, Map<String, Object> params) {
74 logger.debug("complete task " + nodeName + " : " + businessObjectId);
75
76 String processId = getDealProcessId(businessObjectId, nodeName, params);
77 if(StringUtils.isEmpty(processId)){
78 throw new ServiceFlowException("Can't find process for "+nodeName);
79 }
80
81 WorkflowUtil.onExitAction(processId, businessObjectId, nodeName, params);
82
83 Node node = workflowService.getNode(nodeName, processId);
84 Node to;
85 String toType;
86 if(node!=null){
87 Map<String,List<Connection>> outs = node.getOutgoingConnections();
88 List<Connection> conns;
89 for(String out : outs.keySet()){
90 conns = outs.get(out);
91 for(Connection conn : conns){
92 toType = conn.getToType();
93 to = conn.getTo();
94 if (to instanceof HumanTaskNode) {
95 HumanTaskNode task = (HumanTaskNode) to;
96 String taskNameOfNode = (String) task.getWork().getParameter("TaskName");
97 logger.debug("Next : ["+toType+"] - "+to.getName()+" - "+taskNameOfNode);
98
99 WorkflowUtil.onEntryAction(processId, businessObjectId, taskNameOfNode, params);
100 }else if(to instanceof Split){
101 List<Node> nodes = getNextTaskNode((Split)to);
102 for(Node nd : nodes){
103 HumanTaskNode task = (HumanTaskNode) nd;
104 String taskNameOfNode = (String) task.getWork().getParameter("TaskName");
105 logger.debug("Next : ["+toType+"] - "+to.getName()+" - "+taskNameOfNode);
106 WorkflowUtil.onEntryAction(processId, businessObjectId, taskNameOfNode, params);
107 }
108 }else if(to instanceof Join){
109 List<Node> nodes = getNextTaskNode((Join)to);
110 for(Node nd : nodes){
111 HumanTaskNode task = (HumanTaskNode) nd;
112 String taskNameOfNode = (String) task.getWork().getParameter("TaskName");
113 logger.debug("Next : ["+toType+"] - "+to.getName()+" - "+taskNameOfNode);
114 WorkflowUtil.onEntryAction(processId, businessObjectId, taskNameOfNode, params);
115 }
116 }
117 }
118 }
119 }
120 }
121
122 private String getDealProcessId(String objectId, String nodeName, Map<String, Object> params) {
123 for(ProcessDefine pd:processes.keySet()){
124 if(workflowService.includeNode(nodeName, pd.getProcessId())&&processes.get(pd).accept(objectId, nodeName, params)){
125 return pd.getProcessId();
126 }
127 }
128
129 return null;
130 }
131
132 private List<Node> getNextTaskNode(Split split){
133 List<Node> nodes = new LinkedList<Node>();
134 Map<String,List<Connection>> outs = split.getOutgoingConnections();
135 List<Connection> conns;
136 Node to;
137 for(String out : outs.keySet()){
138 conns = outs.get(out);
139 for(Connection conn : conns){
140 to = conn.getTo();
141 if (to instanceof HumanTaskNode) {
142 nodes.add(to);
143 }else if(to instanceof Split){
144 nodes.addAll(getNextTaskNode((Split)to));
145 }else if(to instanceof Join){
146 nodes.addAll(getNextTaskNode((Join)to));
147 }
148 }
149 }
150
151 return nodes;
152 }
153
154 private List<Node> getNextTaskNode(Join join){
155 List<Node> nodes = new LinkedList<Node>();
156 Map<String,List<Connection>> outs = join.getOutgoingConnections();
157 List<Connection> conns;
158 Node to;
159 for(String out : outs.keySet()){
160 conns = outs.get(out);
161 for(Connection conn : conns){
162 to = conn.getTo();
163 if (to instanceof HumanTaskNode) {
164 nodes.add(to);
165 }else if(to instanceof Split){
166 nodes.addAll(getNextTaskNode((Split)to));
167 }else if(to instanceof Join){
168 nodes.addAll(getNextTaskNode((Join)to));
169 }
170 }
171 }
172
173 return nodes;
174 }
175
176
177
178
179
180 @Override
181 public synchronized void registProcess(IFlowFilter filter, String processId, URL processDefine) {
182 registProcess(0, filter, processId, processDefine);
183 }
184
185 @Override
186 public synchronized void registProcess(int priority,IFlowFilter filter, String processId, URL processDefine) {
187 KnowledgeBuilder kbuilder = JBPMHelper.getKnowledgeBuilder();
188 ResourceFactoryService resourceFactoryService = (ResourceFactoryService) JBPMHelper.getServiceRegistry().get(ResourceFactoryService.class);
189 Resource resource = resourceFactoryService.newUrlResource(processDefine);
190 kbuilder.add(resource, ResourceType.BPMN2);
191 if (kbuilder.hasErrors()) {
192 StringBuilder errorMessages = new StringBuilder("failed to add process define " + processDefine.getPath() + ". the errors like below :\n");
193 KnowledgeBuilderErrors errors = kbuilder.getErrors();
194 for (Iterator<KnowledgeBuilderError> it = errors.iterator(); it.hasNext();) {
195 errorMessages.append(it.next().toString()).append("\n");
196 }
197 logger.error(errorMessages.toString());
198 throw new ServiceFlowException(errorMessages.toString());
199 } else {
200 processes.put(new ProcessDefine(priority,processId),filter);
201 JBPMHelper.getKnowledgeBase().addKnowledgePackages(kbuilder.getKnowledgePackages());
202 }
203 }
204
205 @Override
206 public synchronized void registProcess(IFlowFilter filter, String processId, URL processDefine, URL picturePath) {
207 registProcess(0, filter, processId, processDefine, picturePath);
208 }
209
210 @Override
211 public synchronized void registProcess(int priority,IFlowFilter filter, String processId, URL processDefine, URL picturePath) {
212 KnowledgeBuilder kbuilder = JBPMHelper.getKnowledgeBuilder();
213 ResourceFactoryService resourceFactoryService = (ResourceFactoryService) JBPMHelper.getServiceRegistry().get(ResourceFactoryService.class);
214 Resource resource = resourceFactoryService.newUrlResource(processDefine);
215 kbuilder.add(resource, ResourceType.BPMN2);
216 if (kbuilder.hasErrors()) {
217 StringBuilder errorMessages = new StringBuilder("failed to add process define " + processDefine.getPath() + ". the errors like below :\n");
218 KnowledgeBuilderErrors errors = kbuilder.getErrors();
219 for (Iterator<KnowledgeBuilderError> it = errors.iterator(); it.hasNext();) {
220 errorMessages.append(it.next().toString()).append("\n");
221 }
222 logger.error(errorMessages.toString());
223 throw new ServiceFlowException(errorMessages.toString());
224 } else {
225 processes.put(new ProcessDefine(priority,processId),filter);
226 JBPMHelper.getKnowledgeBase().addKnowledgePackages(kbuilder.getKnowledgePackages());
227 picturePaths.put(processId, picturePath);
228 }
229 }
230
231 @Override
232 public List<ProcessInfo> getProcessInfos() {
233 List<ProcessInfo> processInfoList = workflowService.getProcessInfos();
234 return processInfoList;
235 }
236
237 @Override
238 public ProcessInfo getProcessInfo(String processId) {
239 ProcessInfo processInfo = workflowService.getProcessInfo(processId);
240 return processInfo;
241 }
242
243 @Override
244 public String getProcessIdForStepName(String stepName) {
245 for(ProcessDefine pd:processes.keySet()){
246 if(workflowService.includeNode(stepName, pd.getProcessId())){
247 return pd.getProcessId();
248 }
249 }
250 return null;
251 }
252
253 @Override
254 public boolean hasContainsStepName(String processId, String stepName) {
255 return workflowService.includeNode(stepName, processId);
256 }
257
258 @Override
259 public String getPathForDisplay(String processId) {
260 if(picturePaths.containsKey(processId)){
261 URL url = picturePaths.get(processId);
262 String path = url.getPath();
263 return path.substring(path.indexOf("/static"));
264 }
265 return null;
266 }
267 }