2 Replies Latest reply on Apr 23, 2007 11:53 AM by avbentem

    Can I get to the parent process, given a sub-process?

      Sorry, probably simple but I cannot figger it out...

      Can I, given a task in a sub-process, find it's calling <process-state>?

      Looking in the debugger (the process being started through Seam and the taskInstance and processInstance also injected by Seam) I get many null values, such as:

      taskInstance.token.parent == null
      taskInstance.token.isAbleToReactiveParent == true
      processInstance.rootToken == null
      processInstance.superProcessToken == null

      Of course, I can write a query to get it from the database myself (I actually only need read-access). I wonder why table JBPM_TOKEN has NULL in column PARENT_ (jBPM 3.1.4; might simply be obsolete), but the parent token does in fact link to its (active) child using column SUBPROCESSINSTANCE_. In table JPBM_PROCESSINSTANCE the sub process refers to the parent using column SUPERPROCESSTOKEN_. So, surely doable.

      I don't think the definition is important, but it's something like:

      <?xml version="1.0" encoding="UTF-8"?>
      <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="my-process">
       <start-state name="Start">
       <transition name="start" to="MySubProcess" />
       </start-state>
      
       <process-state name="MySubProcess">
       <sub-process name="my-sub-process" binding="late"/>
       <transition name="end" to="End" />
       </process-state>
      
       <end-state name="End" />
      </process-definition>


      <?xml version="1.0" encoding="UTF-8"?>
      <process-definition xmlns="" name="my-sub-process">
       <start-state name="Start survey">
       <transition name="" to="survey" />
       </start-state>
      
       <task-node name="task1">
       <task name="task1">
       ...
       </task>
       <transition name="done" to="End" />
       </task-node>
      
       <end-state name="End" />
      </process-definition>


      Thanks,
      Arjan.

        • 1. Re: Can I get to the parent process, given a sub-process?

          Meanwhile I've found GraphElement#getParents() (and likewise getParentChain), which returns all the parents of a graph element ordered by age.

          List parents = processInstance.getProcessDefinition().getParents();

          To me, it's a bit odd that the parents are retrieved from the process definition, as this would then not take runtime changes into account?

          Like when using an event handler to set the sub-process on runtime -- that would probably change the process definition of that specific process instance, but I doubt these are persisted for each process instance?

          Or when using loops, like when the current process has already been executed 3 times, would one then expect the current process to be found in getParents() 3 times as well?

          Hmmm, maybe getParents() is the way to go in this case (to get the calling <process-state> from within some sub-process I would not care about traversing all the way up to the main process). I'll soon want an overview of the whole history though, so any thoughts are appreciated!

          Thanks,
          Arjan.


          • 2. Re: Can I get to the parent process, given a sub-process?

            GraphElement#getParentChain is documented to return "this graph element plus all the parents ordered by age". However, this does not seem to work when using sub-processes: the parents of the parent process-state(s) are not returned.

            To me, the "ordered by age" in the documentation suggests that getParents/getParentChain return runtime information, knowing about how a specific process got invoked, and thus also returning that information... So, maybe either the documentation can be enhanced to make clear that any super process is not taken into account. Or, if we'd expect the super process(es) to be included as well, then the current implementation has a bug.

            Any ideas on this?

            For example:

            // NOTE: not thoroughly tested
            public String getElementHistory(GraphElement element) {
             StringBuffer s = new StringBuffer();
             List<GraphElement> parentChain = element.getParentChain();
             if (parentChain != null) {
             for (GraphElement parent : parentChain) {
             if (s.length() != 0) {
             s.append(" -> ");
             }
             s.append(parent.getName());
             s.append(" [" + parent.getClass().getSimpleName() + "]");
             }
             }
             return s.toString();
            }

            This prints
            task1 [TaskNode] -> my-sub-process [ProcessDefinition]

            ...when invoked using
            log.info(getElementHistory(taskInstance.getToken().getNode()));

            ...from a task-start event in the example posted earlier in this thread:
            <process-definition xmlns="" name="my-sub-process">
             :
             <task-node name="task1">
             <task name="task1">
             <event type="task-start">
             <action name="taskStart" expression="#{...}" />
             </event>
             ...
             </task>
             :

            Above, it doesn't matter whether my-sub-process is started stand-alone, or by some parent process: the code does not iterate into the parent process.

            Of course, one could use getSuperProcessToken to iterate into the parent process, using the processInstance rather than a token from the taskInstance. Like:
            // NOTE: not thoroughly tested
            public String getProcessHistory(ProcessInstance instance) {
             StringBuffer s = new StringBuffer();
            
             Token superToken = instance.getSuperProcessToken();
             if (superToken != null) {
             ProcessInstance superInstance = superToken.getProcessInstance();
             s.append(getHistory(superInstance));
             }
            
             List<GraphElement> parentChain =
             instance.getProcessDefinition().getParentChain();
             if (parentChain != null) {
             for (GraphElement parent : parentChain) {
             if (s.length() != 0) {
             s.append(" -> ");
             }
             s.append(parent.getName());
             }
             }
             return s.toString();
            }

            For the example posted earlier, when passing the processInstance, this would print:
            my-process -> my-sub-process

            It's a bit harder to get the detailed node information though...

            Arjan.