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