11 Replies Latest reply on Dec 12, 2008 9:00 AM by Ronald van Kuijk

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

    Jeff Zheng Newbie

      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?
          Ronald van Kuijk Master

          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

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

            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?
              Mauricio Salatino Master

              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?
                Jeff Zheng Newbie

                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?
                  Jeff Zheng Newbie

                  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?
                    Jeff Zheng Newbie

                    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?
                      Jeff Zheng Newbie

                      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?
                        Ronald van Kuijk Master

                        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?
                          Jeff Zheng Newbie

                          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?
                            Ronald van Kuijk Master

                            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...