KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jbpm > taskmgmt > exe > TaskInstance


1 package org.jbpm.taskmgmt.exe;
2
3 import java.io.Serializable JavaDoc;
4 import java.util.ArrayList JavaDoc;
5 import java.util.Date JavaDoc;
6 import java.util.HashSet JavaDoc;
7 import java.util.Iterator JavaDoc;
8 import java.util.List JavaDoc;
9 import java.util.Map JavaDoc;
10 import java.util.Set JavaDoc;
11
12 import org.apache.commons.logging.Log;
13 import org.apache.commons.logging.LogFactory;
14 import org.jbpm.calendar.BusinessCalendar;
15 import org.jbpm.calendar.Duration;
16 import org.jbpm.graph.def.Event;
17 import org.jbpm.graph.def.Transition;
18 import org.jbpm.graph.exe.Comment;
19 import org.jbpm.graph.exe.ExecutionContext;
20 import org.jbpm.graph.exe.Token;
21 import org.jbpm.graph.node.TaskNode;
22 import org.jbpm.security.Authentication;
23 import org.jbpm.taskmgmt.def.Swimlane;
24 import org.jbpm.taskmgmt.def.Task;
25 import org.jbpm.taskmgmt.log.TaskAssignLog;
26 import org.jbpm.taskmgmt.log.TaskEndLog;
27
28 /**
29  * is one task instance that can be assigned to an actor (read: put in
30  * someones task list) and that can trigger the coninuation of execution
31  * of the token upon completion.
32  */

33 public class TaskInstance implements Serializable JavaDoc, Assignable {
34
35   private static final long serialVersionUID = 1L;
36
37   private long id = 0;
38   protected String JavaDoc name = null;
39   protected String JavaDoc description = null;
40   protected String JavaDoc actorId = null;
41   protected Date JavaDoc create = null;
42   protected Date JavaDoc start = null;
43   protected Date JavaDoc end = null;
44   protected Date JavaDoc dueDate = null;
45   protected int priority = Task.PRIORITY_NORMAL;
46   protected boolean isCancelled = false;
47   protected boolean isSignalling = true;
48   protected boolean isBlocking = false;
49   protected Task task = null;
50   protected Token token = null;
51   protected SwimlaneInstance swimlaneInstance = null;
52   protected TaskMgmtInstance taskMgmtInstance = null;
53   protected Set JavaDoc pooledActors = null;
54   protected List JavaDoc comments = null;
55   
56   protected String JavaDoc previousActorId = null; // not persisted. just extra information for listeners of the assign-event
57

58   public TaskInstance() {
59   }
60
61   public TaskInstance(String JavaDoc taskName) {
62     this.name = taskName;
63   }
64
65   public TaskInstance(String JavaDoc taskName, String JavaDoc actorId) {
66     this.name = taskName;
67     this.actorId = actorId;
68   }
69
70   public void setTask(Task task) {
71     this.name = task.getName();
72     this.description = task.getDescription();
73     this.task = task;
74     this.isBlocking = task.isBlocking();
75     this.priority = task.getPriority();
76     if (task.getTaskNode()!=null) {
77       int signal = task.getTaskNode().getSignal();
78       this.isSignalling = ( (signal==TaskNode.SIGNAL_FIRST )
79                             || (signal==TaskNode.SIGNAL_LAST )
80                             || (signal==TaskNode.SIGNAL_FIRST_WAIT )
81                             || (signal==TaskNode.SIGNAL_LAST_WAIT )
82                           );
83     }
84     if (task.getDueDate()!=null) {
85       BusinessCalendar businessCalendar = new BusinessCalendar();
86       this.dueDate = businessCalendar.add(new Date JavaDoc(), new Duration(task.getDueDate()));
87     }
88   }
89   
90   public void create() {
91     create(null);
92   }
93
94   public void create(ExecutionContext executionContext) {
95     if (create!=null) {
96       throw new IllegalStateException JavaDoc("task instance '"+id+"' was already created");
97     }
98     create = new Date JavaDoc();
99     
100     // if this task instance is associated with a task...
101
if ( (task!=null)
102          && (executionContext!=null)
103        ) {
104       // the TASK_CREATE event is fired
105
executionContext.setTaskInstance(this);
106       executionContext.setTask(task);
107       task.fireEvent(Event.EVENTTYPE_TASK_CREATE, executionContext);
108     }
109   }
110
111   public void assign(ExecutionContext executionContext) {
112     TaskMgmtInstance taskMgmtInstance = executionContext.getTaskMgmtInstance();
113     
114     Swimlane swimlane = task.getSwimlane();
115     // if this task is in a swimlane
116
if (swimlane!=null) {
117       
118       // if this is a task assignment for a start-state
119
if (isStartTaskInstance()) {
120         // initialize the swimlane
121
swimlaneInstance = new SwimlaneInstance(swimlane);
122         taskMgmtInstance.addSwimlaneInstance(swimlaneInstance);
123         // with the current authenticated actor
124
swimlaneInstance.setActorId(Authentication.getAuthenticatedActorId());
125         
126       } else {
127         
128         // lazy initialize the swimlane...
129
// get the swimlane instance (if there is any)
130
swimlaneInstance = taskMgmtInstance.getInitializedSwimlaneInstance(executionContext, swimlane);
131         
132         // copy the swimlaneInstance assignment into the taskInstance assignment
133
copySwimlaneInstanceAssignment(swimlaneInstance);
134       }
135
136     } else { // this task is not in a swimlane
137
taskMgmtInstance.invokeAssignmentHandler(task.getAssignmentDelegation(), this, executionContext);
138     }
139     
140     updatePooledActorsReferences(swimlaneInstance);
141   }
142
143
144   public boolean isStartTaskInstance() {
145     boolean isStartTaskInstance = false;
146     if ( (taskMgmtInstance!=null)
147          && (taskMgmtInstance.getTaskMgmtDefinition()!=null)
148        ) {
149          isStartTaskInstance = (task==taskMgmtInstance.getTaskMgmtDefinition().getStartTask());
150     }
151     return isStartTaskInstance;
152   }
153
154   private void updatePooledActorsReferences(SwimlaneInstance swimlaneInstance) {
155     if (pooledActors!=null) {
156       Iterator JavaDoc iter = pooledActors.iterator();
157       while (iter.hasNext()) {
158         PooledActor pooledActor = (PooledActor) iter.next();
159         pooledActor.setSwimlaneInstance(swimlaneInstance);
160         pooledActor.addTaskInstance(this);
161       }
162     }
163   }
164
165   /**
166    * copies the assignment (that includes both the swimlaneActorId and the set of pooledActors) of
167    * the given swimlane into this taskInstance.
168    */

169   public void copySwimlaneInstanceAssignment(SwimlaneInstance swimlaneInstance) {
170     setSwimlaneInstance(swimlaneInstance);
171     setActorId(swimlaneInstance.actorId);
172     setPooledActors(swimlaneInstance.pooledActors!=null ? new HashSet JavaDoc(swimlaneInstance.pooledActors) : null);
173   }
174
175   /**
176    * gets the pool of actors for this task instance. If this task has a simlaneInstance
177    * and no pooled actors, the pooled actors of the swimlane instance are returned.
178    */

179   public Set JavaDoc getPooledActors() {
180     if ( (swimlaneInstance!=null)
181          && ( (pooledActors==null)
182               || (pooledActors.isEmpty())
183             )
184        ){
185       return swimlaneInstance.pooledActors;
186     }
187     return pooledActors;
188   }
189
190   /**
191    * (re)assign this task to the given actor. If this task is related
192    * to a swimlane instance, that swimlane instance will be updated as well.
193    */

194   public void setActorId(String JavaDoc actorId) {
195     setActorId(actorId, true);
196   }
197
198   /**
199    * (re)assign this task to the given actor.
200    * @param actorId is reference to the person that is assigned to this task.
201    * @param overwriteSwimlane specifies if the related swimlane
202    * should be overwritten with the given swimlaneActorId.
203    */

204   public void setActorId(String JavaDoc actorId, boolean overwriteSwimlane){
205     if ( (task!=null)
206          && (token!=null)
207        ) {
208       ExecutionContext executionContext = new ExecutionContext(token);
209       executionContext.setTask(task);
210       executionContext.setTaskInstance(this);
211       task.fireEvent(Event.EVENTTYPE_TASK_ASSIGN, executionContext);
212     }
213     
214     this.previousActorId = this.actorId;
215     this.actorId = actorId;
216     if ( (swimlaneInstance!=null)
217          && (overwriteSwimlane) ) {
218       swimlaneInstance.setActorId(actorId);
219     }
220     
221     if (token!=null) {
222       // log this assignment
223
token.addLog(new TaskAssignLog(this, previousActorId, actorId));
224     }
225   }
226
227   public void setPooledActors(String JavaDoc[] actorIds) {
228     this.pooledActors = PooledActor.createPool(actorIds);
229   }
230
231   /**
232    * can optionally be used to indicate that the actor is starting to
233    * work on this task instance.
234    */

235   public void start(){
236     if (start!=null) {
237       throw new IllegalStateException JavaDoc("task instance '"+id+"' is already started");
238     }
239     
240     start = new Date JavaDoc();
241     if ( (task!=null)
242          && (token!=null)
243        ) {
244       ExecutionContext executionContext = new ExecutionContext(token);
245       task.fireEvent(Event.EVENTTYPE_TASK_START, executionContext);
246     }
247   }
248
249   /**
250    * convenience method that combines a {@link #setActorId(String)} and
251    * a {@link #start()}.
252    */

253   public void start(String JavaDoc actorId){
254     setActorId(actorId);
255     start();
256   }
257   
258   /**
259    * cancels this task.
260    */

261   public void cancel() {
262     isCancelled = true;
263     end();
264   }
265
266   /**
267    * marks this task as done. If this task is related to a task node
268    * this might trigger a signal on the token.
269    * @see #end(Transition)
270    */

271   public void end() {
272     end((Transition)null);
273   }
274
275   /**
276    * marks this task as done and specifies the name of a transition
277    * leaving the task-node for the case that the completion of this
278    * task instances triggers a signal on the token.
279    * If this task leads to a signal on the token, the given transition
280    * name will be used in the signal.
281    * If this task completion does not trigger execution to move on,
282    * the transitionName is ignored.
283    */

284   public void end(String JavaDoc transitionName) {
285     if ( (task==null)
286          || (task.getTaskNode()==null)
287          || (task.getTaskNode()==null)
288          || (!task.getTaskNode().hasLeavingTransition(transitionName))
289        ) {
290       throw new NullPointerException JavaDoc("task node does not have leaving transition '"+transitionName+"'");
291     }
292     end(task.getTaskNode().getLeavingTransition(transitionName));
293   }
294
295   /**
296    * marks this task as done and specifies a transition
297    * leaving the task-node for the case that the completion of this
298    * task instances triggers a signal on the token.
299    * If this task leads to a signal on the token, the given transition
300    * name will be used in the signal.
301    * If this task completion does not trigger execution to move on,
302    * the transition is ignored.
303    */

304   public void end(Transition transition) {
305     if (this.end!=null){
306       throw new IllegalStateException JavaDoc("task instance '"+id+"'is already started");
307     }
308     
309     // mark the end of this task instance
310
this.end = new Date JavaDoc();
311
312     // fire the task instance end event
313
if ( (task!=null)
314          && (token!=null)
315        ) {
316       ExecutionContext executionContext = new ExecutionContext(token);
317       task.fireEvent(Event.EVENTTYPE_TASK_END, executionContext);
318     }
319     
320     // log this assignment
321
if (token!=null) {
322       token.addLog(new TaskEndLog(this));
323     }
324     
325     // verify if the end of this task triggers continuation of execution
326
if (isSignalling) {
327       this.isSignalling = false;
328       
329       
330       
331       if ( this.isStartTaskInstance() // ending start tasks always leads to a signal
332
|| ( (task!=null)
333                 && (token!=null)
334                 && (task.getTaskNode()!=null)
335                 && (task.getTaskNode().completionTriggersSignal(this))
336               )
337          ) {
338         
339         if (transition==null) {
340           log.debug("completion of task '"+task.getName()+"' results in taking the default transition");
341           token.signal();
342         } else {
343           log.debug("completion of task '"+task.getName()+"' results in taking transition '"+transition+"'");
344           token.signal(transition);
345         }
346       }
347     }
348   }
349
350   public boolean hasEnded() {
351     return (end!=null);
352   }
353   
354   // comments /////////////////////////////////////////////////////////////////
355

356   public void addComment(String JavaDoc message) {
357     Comment comment = new Comment(message);
358     addComment(comment);
359     if (token!=null) {
360       token.addComment(comment);
361     }
362   }
363
364   public void addComment(Comment comment) {
365     if (comments==null) comments = new ArrayList JavaDoc();
366     comments.add(comment);
367     comment.setTaskInstance(this);
368     comment.setToken(token);
369   }
370   
371   public List JavaDoc getComments() {
372     return comments;
373   }
374  
375   // task form ////////////////////////////////////////////////////////////////
376

377   public List JavaDoc getTaskFormParameters() {
378     List JavaDoc taskFormParameters = null;
379     if ( (task!=null)
380          && (task.getTaskController()!=null)
381        ) {
382       taskFormParameters = task.getTaskController().getTaskFormParameters(this);
383     }
384     return taskFormParameters;
385   }
386   
387   public void submitParameters(Map JavaDoc parameters) {
388     if ( (task!=null)
389          && (task.getTaskController()!=null)
390        ) {
391       task.getTaskController().submitParameters(parameters, this);
392     }
393   }
394   
395   public boolean isLast() {
396     return ( (token!=null)
397              && (taskMgmtInstance!=null)
398              && (! taskMgmtInstance.hasUnfinishedTasks(token))
399            );
400   }
401   
402   /**
403    * is the list of transitions that can be used in the end method
404    * and it is null in case this is not the last task instance.
405    */

406   public List JavaDoc getAvailableTransitions() {
407     List JavaDoc transitions = null;
408     if ( (! isLast())
409          && (token!=null)
410        ) {
411       transitions = new ArrayList JavaDoc(token.getNode().getLeavingTransitions());
412     }
413     return transitions;
414   }
415   
416   // getters and setters //////////////////////////////////////////////////////
417

418   public String JavaDoc getActorId() {
419     return actorId;
420   }
421   public Date JavaDoc getDueDate() {
422     return dueDate;
423   }
424   public void setDueDate(Date JavaDoc dueDate) {
425     this.dueDate = dueDate;
426   }
427   public Date JavaDoc getEnd() {
428     return end;
429   }
430   public void setEnd(Date JavaDoc end) {
431     this.end = end;
432   }
433   public void setCreate(Date JavaDoc create) {
434     this.create = create;
435   }
436   public long getId() {
437     return id;
438   }
439   public void setId(long id) {
440     this.id = id;
441   }
442   public Date JavaDoc getStart() {
443     return start;
444   }
445   public TaskMgmtInstance getTaskMgmtInstance() {
446     return taskMgmtInstance;
447   }
448   public void setTaskMgmtInstance(TaskMgmtInstance taskMgmtInstance) {
449     this.taskMgmtInstance = taskMgmtInstance;
450   }
451   public Token getToken() {
452     return token;
453   }
454   public void setToken(Token token) {
455     this.token = token;
456   }
457   public void setSignalling(boolean isSignalling) {
458     this.isSignalling = isSignalling;
459   }
460   public boolean isSignalling() {
461     return isSignalling;
462   }
463   public boolean isCancelled() {
464     return isCancelled;
465   }
466   public String JavaDoc getName() {
467     return name;
468   }
469   public void setName(String JavaDoc name) {
470     this.name = name;
471   }
472   public boolean isBlocking() {
473     return isBlocking;
474   }
475   public void setBlocking(boolean isBlocking) {
476     this.isBlocking = isBlocking;
477   }
478   public Date JavaDoc getCreate() {
479     return create;
480   }
481   public Task getTask() {
482     return task;
483   }
484   public void setPooledActors(Set JavaDoc pooledActors) {
485     this.pooledActors = pooledActors;
486   }
487   public SwimlaneInstance getSwimlaneInstance() {
488     return swimlaneInstance;
489   }
490   public void setSwimlaneInstance(SwimlaneInstance swimlaneInstance) {
491     this.swimlaneInstance = swimlaneInstance;
492   }
493   public String JavaDoc getPreviousActorId() {
494     return previousActorId;
495   }
496   public int getPriority() {
497     return priority;
498   }
499   public void setPriority(int priority) {
500     this.priority = priority;
501   }
502   
503   private static final Log log = LogFactory.getLog(TaskInstance.class);
504 }
505
Popular Tags