1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.jbpm;
12
13 import org.mule.api.NamedObject;
14 import org.mule.api.lifecycle.Disposable;
15 import org.mule.api.lifecycle.Initialisable;
16 import org.mule.module.bpm.BPMS;
17 import org.mule.module.bpm.MessageService;
18 import org.mule.util.IOUtils;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.util.Map;
23 import java.util.Properties;
24 import java.util.Set;
25
26 import org.jbpm.api.Configuration;
27 import org.jbpm.api.Execution;
28 import org.jbpm.api.ProcessEngine;
29 import org.jbpm.api.ProcessInstance;
30 import org.jbpm.api.task.Task;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34
35
36
37 public class Jbpm implements BPMS, Initialisable, Disposable, NamedObject
38 {
39
40
41
42 protected ProcessEngine processEngine = null;
43
44
45
46
47 private String configurationResource;
48
49
50
51
52 private Properties processDefinitions;
53
54
55
56
57 private String name;
58
59
60
61
62
63 protected boolean containerManaged = true;
64
65 public static final String PROCESS_ENDED = "Process has ended";
66
67
68
69
70
71
72 public static final int PROCESS_CREATION_WAIT = 3000;
73
74 protected static final Logger log = LoggerFactory.getLogger(Jbpm.class);
75
76
77
78
79
80
81
82
83 public Jbpm()
84 {
85
86 }
87
88
89
90
91
92
93 public Jbpm(String configurationResource, Properties processDefinitions)
94 {
95 this.configurationResource = configurationResource;
96 this.processDefinitions = processDefinitions;
97 }
98
99
100
101
102
103 public Jbpm(ProcessEngine processEngine, Properties processDefinitions)
104 {
105 this.processEngine = processEngine;
106 this.processDefinitions = processDefinitions;
107 }
108
109 public void initialise()
110 {
111 if (processEngine == null)
112 {
113 Configuration config = new Configuration();
114 if (configurationResource != null)
115 {
116 config.setResource(configurationResource);
117 }
118 setProcessEngine(config.buildProcessEngine());
119 containerManaged = false;
120 }
121 if (processDefinitions != null)
122 {
123 for (Object def : processDefinitions.values())
124 {
125 try
126 {
127 deployProcess((String) def);
128 }
129 catch (IOException e)
130 {
131 log.error("Unable to deploy process definition: " + e.getMessage());
132 }
133 }
134 }
135 }
136
137 public void dispose()
138 {
139 if (!containerManaged && processEngine != null)
140 {
141 processEngine.close();
142 processEngine = null;
143 }
144 }
145
146 public void setMessageService(MessageService msgService)
147 {
148 MuleMessageService serviceProxy = processEngine.get(MuleMessageService.class);
149 serviceProxy.setMessageService(msgService);
150 }
151
152
153
154
155
156
157
158
159
160
161 public Object startProcess(Object processDefinitionKey) throws Exception
162 {
163 return startProcess(processDefinitionKey, null, null);
164 }
165
166
167
168
169
170
171 public Object startProcess(Object processDefinitionKey, Object signalName, Map variables) throws Exception
172 {
173 ProcessInstance processInstance =
174 processEngine.getExecutionService().startProcessInstanceByKey((String) processDefinitionKey, (Map) variables);
175
176 if (processInstance == null)
177 {
178 throw new IllegalArgumentException("No process definition found for process " + processDefinitionKey);
179 }
180
181 return processInstance;
182 }
183
184
185
186
187
188
189 public Object advanceProcess(Object executionId) throws Exception
190 {
191 return advanceProcess(executionId, null, null);
192 }
193
194
195
196
197
198
199
200
201
202
203 public Object advanceProcess(Object executionId, Object signalName, Map variables) throws Exception
204 {
205 int waitTime = 0;
206 Execution execution = processEngine.getExecutionService().findExecutionById((String) executionId);
207 while (execution == null && waitTime < PROCESS_CREATION_WAIT)
208 {
209
210
211
212 Thread.sleep(PROCESS_CREATION_WAIT / 10);
213 waitTime += (PROCESS_CREATION_WAIT / 10);
214 execution = processEngine.getExecutionService().findExecutionById((String) executionId);
215 }
216 if (execution == null)
217 {
218 throw new IllegalArgumentException("No process execution found with id = " + executionId + " (it may have already terminated)");
219 }
220
221 String processId;
222 if (execution.getProcessInstance() != null)
223 {
224 processId = execution.getProcessInstance().getId();
225 }
226 else
227 {
228 processId = execution.getId();
229 }
230
231
232 if (variables != null && !variables.isEmpty())
233 {
234 processEngine.getExecutionService().setVariables((String) executionId, variables);
235 }
236
237
238 synchronized (this)
239 {
240 processEngine.getExecutionService().signalExecutionById((String) executionId, (String) signalName, variables);
241 }
242
243
244 ProcessInstance process = processEngine.getExecutionService().findProcessInstanceById(processId);
245 if (process == null)
246 {
247
248 process = new EndedProcess(processId);
249 }
250 return process;
251 }
252
253
254
255
256
257
258 public Object updateProcess(Object executionId, Map variables) throws Exception
259 {
260
261 String processId;
262 Execution execution = processEngine.getExecutionService().findExecutionById((String) executionId);
263 if (execution == null)
264 {
265 throw new IllegalArgumentException("No process execution found with id = " + executionId + " (it may have already terminated)");
266 }
267 if (execution.getProcessInstance() != null)
268 {
269 processId = execution.getProcessInstance().getId();
270 }
271 else
272 {
273 processId = execution.getId();
274 }
275
276
277 if (variables != null && !variables.isEmpty())
278 {
279 processEngine.getExecutionService().setVariables((String) executionId, variables);
280 }
281
282
283 ProcessInstance process = processEngine.getExecutionService().findProcessInstanceById(processId);
284 if (process == null)
285 {
286
287 process = new EndedProcess(processId);
288 }
289 return process;
290 }
291
292
293
294
295 public void abortProcess(Object processInstanceId) throws Exception
296 {
297 processEngine.getExecutionService().endProcessInstance((String) processInstanceId, Execution.STATE_ENDED);
298 }
299
300
301
302
303
304 public boolean isProcess(Object obj) throws Exception
305 {
306 return (obj instanceof ProcessInstance);
307 }
308
309 public Object getId(Object process) throws Exception
310 {
311 return ((ProcessInstance) process).getId();
312 }
313
314 public Object getState(Object process) throws Exception
315 {
316 return getState((ProcessInstance) process);
317 }
318
319 public static String getState(ProcessInstance processInstance) throws Exception
320 {
321 if (processInstance == null || processInstance.isEnded())
322 {
323 return ProcessInstance.STATE_ENDED;
324 }
325
326 Set activities = processInstance.findActiveActivityNames();
327 String state = null;
328
329 for (Object activityName : activities)
330 {
331 if (state == null)
332 {
333 state = (String) activityName;
334 }
335 else
336 {
337 state += " / " + activityName;
338 }
339 }
340 return state;
341 }
342
343 public boolean hasEnded(Object process) throws Exception
344 {
345 return process == null ? true : ((ProcessInstance) process).isEnded();
346 }
347
348
349
350
351
352
353 public Object lookupProcess(Object processId) throws Exception
354 {
355 return processEngine.getExecutionService().findProcessInstanceById((String) processId);
356 }
357
358
359
360
361
362 public void deployProcess(String processDefinitionFile) throws IOException
363 {
364 deployProcessFromStream(processDefinitionFile, IOUtils.getResourceAsStream(processDefinitionFile,
365 getClass()));
366 }
367
368 public void deployProcessFromStream(String resourceName, InputStream processDefinition)
369 throws IOException
370 {
371 processEngine.getRepositoryService().createDeployment()
372 .addResourceFromInputStream(resourceName, processDefinition)
373 .deploy();
374 }
375
376 public void undeployProcess(String resource) throws Exception
377 {
378
379 }
380
381 public void completeTask(Task task)
382 {
383 completeTask(task, null, null);
384 }
385
386 public void completeTask(Task task, String outcome, Map variables)
387 {
388 processEngine.getTaskService().completeTask(task.getId(), outcome, variables);
389 }
390
391
392
393
394
395 public ProcessEngine getProcessEngine()
396 {
397 return processEngine;
398 }
399
400 public void setProcessEngine(ProcessEngine processEngine)
401 {
402 this.processEngine = processEngine;
403 }
404
405 public String getConfigurationResource()
406 {
407 return configurationResource;
408 }
409
410 public void setConfigurationResource(String configurationResource)
411 {
412 this.configurationResource = configurationResource;
413 }
414
415 public Properties getProcessDefinitions()
416 {
417 return processDefinitions;
418 }
419
420 public void setProcessDefinitions(Properties processDefinitions)
421 {
422 this.processDefinitions = processDefinitions;
423 }
424
425 public void setName(String name)
426 {
427 this.name = name;
428 }
429
430 public String getName()
431 {
432 return name;
433 }
434 }