5 Replies Latest reply on Nov 7, 2006 10:22 AM by jpuro

    foreach ActionHandler

    corfian

      I'm trying to learn jBPM by modeling a simple process. After reading the documentation and/or forum posts, it is not yet clear to me how I could model a foreach node ActionHandler.

      In other words, I'm trying to implement an action handler which is able to fetch, let's say, an ArrayList from the process execution context and for each item contained in the list instance, I want to execute a certain group of nodes in the process ....

      Can anyone please suggest something.. I'm really lost.

      Regards
      Slavikos

        • 1. Re: foreach ActionHandler
          jim.mcmaster

          I wrote a custom fork handler that does this. Instead of forking off a single child token for each outgoing transition, it forks off a child token for each element in the list for each transition. I use it with a single outgoing transition, so the effect should be what you describe. The code is a simple modifcation of the sample at http://wiki.jboss.org/wiki/attach?page=ForEachForkActionHandler%2FForEachForkActionHandler.java. I do not have it at home, but could send it to you on Monday if you want.

          • 2. Re: foreach ActionHandler
            corfian

            Jim, thanks for you answer. I'm aware of the handler you are refering to. It was the base for my first solution, which currently seems to work, but I'm not sure if I use jBPM's API correctly ...

            My handler look's like :

            public void execute(ExecutionContext executionContext) throws Exception {
             Token this_token = executionContext.getToken();
             Node this_node = executionContext.getNode();
             // fetch the XML document on which
             // we are about to iterate
             String xmlDocument = (String)executionContext.getVariable(inputVariable);
             XmlObject xmlObject = XmlObject.Factory.parse(xmlDocument);
             XmlCursor cursor = xmlObject.newCursor();
             cursor.toFirstChild();
             cursor.push();
             // apply an XPath
             cursor.selectPath(repeatingElement);
             // iterate on selections
             while(cursor.toNextSelection()) {
             executionContext.getContextInstance().setVariable(iterationVariable, cursor.getTextValue(), this_token);
             // execute the "foreach" body
             this_node.leave(executionContext, "iterate");
             }
             // no more items left, leave the foreach iteration
             this_node.leave(executionContext, NO_MORE_ITERATION);
            }
            


            My testing process definition look's like:

            <node name="user iterator">
             <action class="xxxx.xxxx.ForEachAction">
             <inputVariable>users</inputVariable>
             <iterationVariable>a_user</iterationVariable>
             <repeatingElement>$this//name</repeatingElement>
             </action>
             <transition name="iterate" to="process_user"></transition>
             <transition name="finish-iteration" to="end_of_user_iteration"></transition>
            </node>
            
            <node name="process_user">
             <script>
             <expression>System.err.println("I'm processing user : "+a_user)</expression>
             </script>
             <transition name="" to="end_of_user_iteration"></transition>
            </node>
            
            <join name="end_of_user_iteration">
             <transition name="" to="end1"></transition>
            </join>


            The outcome of the process execution is the expected. I'm just not sure if the usage of the API is correct, especially in the part where I use the node instance to specify the execution path.

            What do you think ? Is it valid ?

            Regards
            Slavikos

            • 3. Re: foreach ActionHandler
              enazareno

              Hi Slavikos,

              If I am not mistaken, I think this might give you unexpected results regarding the state of the workflow. There is only one path of execution in this case, the root token. Once the first iteration finishes, the current node is already the join node (end_of_user_iteration), thus the next iteration in the for each might not transition properly. I might be wrong, so need to check this out.

              I don't know if I got what you are trying to achieve, but the way I was doing was quite different. I had several process running concurrently, and I created child tokens for each. I made a fork and each child process was created on the fly, and root token continued execution only when all processes met at the join. There were several child tokens so my root token reflected the correct state.

              But anyway, if it worked for you, then that's fine.

              Regards,

              Elmo

              • 4. Re: foreach ActionHandler

                 

                "jim.mcmaster" wrote:
                I wrote a custom fork handler that does this. Instead of forking off a single child token for each outgoing transition, it forks off a child token for each element in the list for each transition. I use it with a single outgoing transition, so the effect should be what you describe. The code is a simple modifcation of the sample at http://wiki.jboss.org/wiki/attach?page=ForEachForkActionHandler%2FForEachForkActionHandler.java. I do not have it at home, but could send it to you on Monday if you want.


                I looked at the example. I understand the inner for loop around the collection. What I don't understand is why there is a loop around the transitions. Is it because you want to automatically do a foreach on every transition out of the node?

                • 5. Re: foreach ActionHandler
                  jpuro

                  Has either way been proven or disproven as a working method for replicating a foreach control statement in JBPM? It seems like the first example posted in this should work, but I'm wondering if you run into transaction or other issues since JBPM works with a database.