11 Replies Latest reply on Dec 12, 2008 9:00 AM by kukeltje

    how to implement co-sign a task by several person?

      i want to set co-signer from web page, and set it to a task-node as actor.
      The rule can be: one/all/majority of co-signer approved, the task finishes.
      how to implement?

        • 1. Re: how to implement co-sign a task by several person?
          kukeltje

          By modelling that in your process. e.g. Make two parallel tasks, where a variable is set when one approves or disapproves and use that value somewhere in a decisionhandler and go either back to the initial tasks (e.g. if the co-signer disapproves) or continue the process if both approve.

          Be a little creative... lots of things are possible

          • 2. Re: how to implement co-sign a task by several person?

            can you give a example?

            • 3. Re: how to implement co-sign a task by several person?

              I have an entity in my system that relates the the active process. As part of that entity, I can store a list of actors.

              In a scenario where I have multiple approvers I simply keep track of who has approved, and don't leave the node until all approvers have approved.

              Just one example of the creativity kukeltje mentioned. lol

              • 4. Re: how to implement co-sign a task by several person?
                salaboy21

                Yes, also you can create a task-node that contains multiple tasks for approval And make this taks-node wait for all the task complete to signal the process.
                Also you can create a fork/join situation giving more flexibility!

                • 5. Re: how to implement co-sign a task by several person?

                  I have made a example.

                  Process Definition like this, i want to co-sign in 'approval' task node. And define 2 action in it.
                  The dynamic task creation is ok, but sth wrong with CosignTaskEndHandler

                  could you give advice?

                  <?xml version="1.0" encoding="UTF-8"?>

                  <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="simple">
                  <start-state name="start">


                  </start-state>

                  <task-node name="create">








                  </task-node>





                  <task-node name="approval" create-tasks="false" signal="last-wait">











                  </task-node>



                  About to finish!




                  <end-state name="end"></end-state>
                  </process-definition>

                  CosignActionHandler.java
                  public class CosignActionHandler implements ActionHandler {

                  private static final long serialVersionUID = 1L;
                  private static final Log log = LogFactory.getLog(CosignActionHandler.class);

                  public void execute(ExecutionContext context) throws Exception {

                  List approveNameList = (List)context.getVariable("approvedName");
                  log.info(approveNameList.size());
                  Token token = context.getToken();
                  TaskMgmtInstance tmi = context.getTaskMgmtInstance();
                  TaskNode taskNode = (TaskNode) context.getNode();
                  Task task = taskNode.getTask("approvalTask");
                  for(int i=0; i<approveNameList.size(); i++){
                  String appName = (String)approveNameList.get(i);
                  tmi.createTaskInstance(task, token).setActorId(appName);
                  log.info("appName:" + appName +" task created");
                  }
                  }
                  }


                  CosignTaskEndHandler.java
                  public class CosignTaskEndHandler implements ActionHandler {

                  private static final long serialVersionUID = 1L;
                  private static final Log log = LogFactory.getLog(CosignTaskEndHandler.class);

                  public void execute(ExecutionContext context) throws Exception {
                  boolean isDisapprove = true;
                  log.info("isDisapprove:"+isDisapprove);
                  if (isDisapprove) {
                  TaskMgmtInstance tmi = context.getTaskMgmtInstance();
                  TaskInstance ti = context.getTaskInstance();
                  final String actorId = ti.getActorId();
                  Collection c = tmi.getSignallingTasks(context);

                  for (Iterator it = c.iterator(); it.hasNext();) {
                  TaskInstance task = (TaskInstance) it.next();
                  if (!(actorId.equals(task.getActorId())) && (!task.hasEnded())) {
                  task.end("write");
                  }
                  }
                  }
                  }
                  }

                  • 6. Re: how to implement co-sign a task by several person?

                    sorry, the example as below.
                    to make the code clear for you , i post it again.
                    please help me to have a look, whats the problem.
                    especially in CosignTaskEndHandler.
                    Thanks a lot!

                    <?xml version="1.0" encoding="UTF-8"?>
                    <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="simple">
                     <start-state name="start">
                     <transition to="create">
                     </transition>
                     </start-state>
                     <task-node name="create">
                     <task name="createTask">
                     <controller>
                     <variable name="approvedName"></variable>
                     </controller>
                     <assignment class="com.sample.assignment.DealAssignment">
                     </assignment>
                     </task>
                     <transition to="message"></transition>
                     </task-node>
                    
                     <state name="message">
                     <transition to="approval"></transition>
                     </state>
                    
                     <task-node name="approval" create-tasks="false" signal="last-wait">
                     <event type="node-enter">
                     <action name="approvalAction" class="com.sample.action.CosignActionHandler">
                     </action>
                     </event>
                     <event type="task-end">
                     <action
                     class="com.sample.action.CosignTaskEndHandler">
                     </action>
                     </event>
                     <task name="approvalTask">
                     </task>
                     <transition to="write"></transition>
                     </task-node>
                    
                     <node name="write">
                     <action name="action" class="com.sample.action.MessageActionHandler">
                     <message>About to finish!</message>
                     </action>
                     <transition to="end"></transition>
                     </node>
                    
                    
                     <end-state name="end"></end-state>
                    </process-definition>
                    


                    CosignActionHandler.java
                    public class CosignActionHandler implements ActionHandler {
                    
                     private static final long serialVersionUID = 1L;
                     private static final Log log = LogFactory.getLog(CosignActionHandler.class);
                    
                     public void execute(ExecutionContext context) throws Exception {
                    
                     List approveNameList = (List)context.getVariable("approvedName");
                     log.info(approveNameList.size());
                     Token token = context.getToken();
                     TaskMgmtInstance tmi = context.getTaskMgmtInstance();
                     TaskNode taskNode = (TaskNode) context.getNode();
                     Task task = taskNode.getTask("approvalTask");
                     for(int i=0; i<approveNameList.size(); i++){
                     String appName = (String)approveNameList.get(i);
                     tmi.createTaskInstance(task, token).setActorId(appName);
                     log.info("appName:" + appName +" task created");
                     }
                    
                     }
                    
                    }
                    


                    CosignTaskEndHandler.java
                    public class CosignTaskEndHandler implements ActionHandler {
                    
                     private static final long serialVersionUID = 1L;
                     private static final Log log = LogFactory.getLog(CosignTaskEndHandler.class);
                    
                     public void execute(ExecutionContext context) throws Exception {
                     boolean isDisapprove = true;
                     log.info("isDisapprove:"+isDisapprove);
                     if (isDisapprove) {
                     TaskMgmtInstance tmi = context.getTaskMgmtInstance();
                     TaskInstance ti = context.getTaskInstance();
                     final String actorId = ti.getActorId();
                     Collection c = tmi.getSignallingTasks(context);
                    
                     for (Iterator it = c.iterator(); it.hasNext();) {
                     TaskInstance task = (TaskInstance) it.next();
                     if (!(actorId.equals(task.getActorId())) && (!task.hasEnded())) {
                     task.end("write");
                     }
                     }
                     }
                     }
                    }
                    


                    • 7. Re: how to implement co-sign a task by several person?

                      Based on codes mentioned above, i have been confused by this problem for several days, who can tell me how to write 'task-end' action.
                      Test the process, i always get this error:

                      org.jbpm.JbpmException: this token is locked by token[0]
                       at org.jbpm.graph.exe.Token.signal(Token.java:182)
                       at org.jbpm.graph.exe.Token.signal(Token.java:140)
                       at org.jbpm.taskmgmt.exe.TaskInstance.end(TaskInstance.java:479)
                       at org.jbpm.taskmgmt.exe.TaskInstance.end(TaskInstance.java:393)
                       at com.sample.action.CosignTaskEndHandler.execute(CosignTaskEndHandler.java:37)
                       at org.jbpm.graph.def.Action.execute(Action.java:122)
                       at org.jbpm.graph.def.GraphElement.executeAction(GraphElement.java:259)
                       at org.jbpm.graph.def.GraphElement.executeActions(GraphElement.java:215)
                       at org.jbpm.graph.def.GraphElement.fireAndPropagateEvent(GraphElement.java:185)
                       at org.jbpm.graph.def.GraphElement.fireAndPropagateEvent(GraphElement.java:198)
                       at org.jbpm.graph.def.GraphElement.fireEvent(GraphElement.java:169)
                       at org.jbpm.taskmgmt.exe.TaskInstance.end(TaskInstance.java:452)
                       at org.jbpm.taskmgmt.exe.TaskInstance.end(TaskInstance.java:393)
                       at com.sample.action.CosignTaskEndHandler.execute(CosignTaskEndHandler.java:37)
                       at org.jbpm.graph.def.Action.execute(Action.java:122)
                       at org.jbpm.graph.def.GraphElement.executeAction(GraphElement.java:259)
                       at org.jbpm.graph.def.GraphElement.executeActions(GraphElement.java:215)
                       at org.jbpm.graph.def.GraphElement.fireAndPropagateEvent(GraphElement.java:185)
                       at org.jbpm.graph.def.GraphElement.fireAndPropagateEvent(GraphElement.java:198)
                       at org.jbpm.graph.def.GraphElement.fireEvent(GraphElement.java:169)
                       at org.jbpm.taskmgmt.exe.TaskInstance.end(TaskInstance.java:452)
                       at org.jbpm.taskmgmt.exe.TaskInstance.end(TaskInstance.java:393)
                       at com.sample.SimpleProcessTest.testSimpleProcess(SimpleProcessTest.java:59)
                       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                       at java.lang.reflect.Method.invoke(Method.java:585)
                       at junit.framework.TestCase.runTest(TestCase.java:154)
                       at junit.framework.TestCase.runBare(TestCase.java:127)
                       at junit.framework.TestResult$1.protect(TestResult.java:106)
                       at junit.framework.TestResult.runProtected(TestResult.java:124)
                       at junit.framework.TestResult.run(TestResult.java:109)
                       at junit.framework.TestCase.run(TestCase.java:118)
                       at junit.framework.TestSuite.runTest(TestSuite.java:208)
                       at junit.framework.TestSuite.run(TestSuite.java:203)
                       at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
                       at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
                       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
                       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
                       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
                       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
                      
                      


                      • 8. Re: how to implement co-sign a task by several person?

                        i am confused about this problem for 1 week.

                        I can create several tasks in a task node,
                        if one task is denied, quit the task node, no matter other task result.
                        How can it implement?

                        I add this in task-node,

                        <event type="task-end">
                         <action
                         class="com.sample.action.CosignTaskEndHandler">
                         </action>
                        </event>
                        


                        but awlays get a error like this:
                        org.jbpm.JbpmException: this token is locked by token[0]

                        Can anyone help me??

                        • 9. Re: how to implement co-sign a task by several person?
                          kukeltje

                          Can you make a unit test with these actionhandlers embedded as innerclasses and the processdefinition embedded as a string? Fill some variables as well. Then I can check what happens

                          • 10. Re: how to implement co-sign a task by several person?

                            problem resolved.
                            I just added the red code, the process runs.

                            public class CosignTaskEndHandler implements ActionHandler {
                            
                             private static final long serialVersionUID = 1L;
                             private static final Log log = LogFactory
                             .getLog(CosignTaskEndHandler.class);
                            
                             /**
                             * all approvers must agree, otherwise end
                             */
                            
                             public void execute(ExecutionContext context) throws Exception {
                            
                             Boolean isDisapprove = (Boolean) context.getTaskInstance().getVariable(
                             "isDisapprove");
                             log.info("isDisapprove:" + isDisapprove);
                            
                             Token token = context.getToken();
                             TaskMgmtInstance tmi = context.getTaskMgmtInstance();
                             Collection<TaskInstance> unfinishedTasks = tmi
                             .getSignallingTasks(context);
                            
                             if (isDisapprove != null) {
                             if (isDisapprove == true) {
                             for (TaskInstance unfinishedTaskInstance : unfinishedTasks) {
                            
                             if (!unfinishedTaskInstance.hasEnded()) {
                             log.info(unfinishedTaskInstance.getActorId());
                             unfinishedTaskInstance.setSignalling(false); unfinishedTaskInstance.end();
                             }
                             }
                             }
                             }
                            
                             }
                            
                            
                            
                            
                            
                            
                            
                            }
                            


                            • 11. Re: how to implement co-sign a task by several person?
                              kukeltje

                              Yep... that sounds really plausible... sorry I did not come up with this solution.

                              Would be nice if you could make a small wiki page with this example in it...