0 Replies Latest reply on Jul 30, 2009 9:39 AM by asrickard

    Using Context and Command

      I've been trying to work out how to use context functions and the Command system, and need some suggestions/assistance.

      I have a conversation-scoped Seam component "workflowProcessManager" in which I have a list of running processes which is refreshed when the user clicks a commandLink. In the same component I have a function to suspend a ProcessInstance.

      
      @Name("workflowProcessManager")
      @Scope(ScopeType.CONVERSATION)
      public class WorkflowProcessManager {
      
      private JbpmContext context;
      private CommandServiceImpl csi;
      private Boolean showActiveOnly = true;
      
      @DataModel private List<ProcessDefinition> processDefinitions = new Vector<ProcessDefinition>(0);
      @DataModelSelection("processDefinitions") @Out(required=false) private ProcessDefinition currentProcessDefinition;
      
      @DataModel private List<ProcessInstance> runningProcesses = new Vector<ProcessInstance>(0);
      @DataModelSelection("runningProcesses") @Out(required=false) private ProcessInstance currentRunningProcess;
      
      public void init() {
       context = JbpmConfiguration.getInstance().createJbpmContext();
       populateProcessDefinitionList();
       csi = new CommandServiceImpl(context.getJbpmConfiguration());
      }
      
      public void showProcessesForProcessDefinition(ProcessDefinition pd) {
       GetProcessInstancesCommand gpic = new GetProcessInstancesCommand();
      
       if (this.showActiveOnly)
       gpic.setOnlyRunning(true);
       else
       gpic.setOnlyRunning(false);
       gpic.setProcessName(pd.getName());
      
       runningProcesses = (List<ProcessInstance>) csi.execute(gpic);
       System.out.println("ShowProcessesForProcessDefinition: runningProcesses contains " + runningProcesses.size() + " entries.");
      }
      
      public void suspendProcessInstance(Integer id) {
       System.out.println("Suspending process instance " + id);
       ProcessInstance pi = context.getProcessInstance(id);
      
       pi.suspend();
      
       System.out.println("Saving process instance " + id);
       context.save(pi);
      
       //Session session = context.getSession();
       //session.flush();
      
       if (pi.isSuspended()) System.out.println("Process instance is suspended = true");
       else System.out.println("Process instance is suspended = false");
      
       System.out.println("Refreshing processes for definition " + this.currentProcessDefinition.getName());
       showProcessesForProcessDefinition(this.currentProcessDefinition);
      
       for (ProcessInstance p : this.runningProcesses) {
       if (p.isSuspended()) System.out.println("Process instance " + p.getId() + " is suspended = true");
       else System.out.println("Process instance " + p.getId() + " is suspended = false");
       }
      }
      
       public Boolean getShowActiveOnly() {
       return this.showActiveOnly;
       }
       public void setShowActiveOnly(Boolean showActiveOnly) {
       this.showActiveOnly = showActiveOnly;
       }
      
       @SuppressWarnings("unchecked")
       private void populateProcessDefinitionList() {
       processDefinitions = context.getGraphSession().findAllProcessDefinitions();
       }
      
      }
      


      And the guts of the page:
       <rich:panel>
       <f:facet name="header">Process List</f:facet>
      
       <h:panelGrid columns="2" columnClasses="twoColumnTopAligned">
       <h:panelGroup>
       <rich:dataTable value="#{processDefinitions}" var="processDefinition"
       onRowMouseOver="this.style.backgroundColor='#EAEAEA';this.style.cursor='pointer'"
       onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'">
       <rich:column>
       <f:facet name="header">Process Name</f:facet>
       <h:outputText value="#{processDefinition.name}"/>
       </rich:column>
      
       <rich:column>
       <f:facet name="header">Description</f:facet>
       <h:outputText value="#{processDefinition.description}"/>
       </rich:column>
      
       <a:support event="onRowClick" reRender="instanceTable"
       action="#{workflowProcessManager.showProcessesForProcessDefinition(processDefinition)}">
       </a:support>
       </rich:dataTable>
      
       <s:decorate id="showActiveOnlyField" template="/layout/edit.xhtml">
       <ui:define name="label">Show only active processes</ui:define>
       <h:selectBooleanCheckbox id="showActiveOnly" value="#{workflowProcessManager.showActiveOnly}" />
       </s:decorate>
       </h:panelGroup>
      
       <rich:dataTable id="instanceTable" value="#{runningProcesses}" var="processInstance">
       <rich:column>
       <f:facet name="header">Id</f:facet>
       <h:outputText value="#{processInstance.id}"/>
       </rich:column>
       <rich:column>
       <f:facet name="header">Version</f:facet>
       <h:outputText value="#{processInstance.version}"/>
       </rich:column>
      
       <rich:column>
       <f:facet name="header">Status</f:facet>
       <h:outputText value="Finished" rendered="#{processInstance.hasEnded()}"/>
       <h:outputText value="Paused" rendered="#{processInstance.suspended}"/>
       <h:outputText value="Running" rendered="#{!(processInstance.hasEnded() or processInstance.suspended)}"/>
       </rich:column>
      
       <rich:column>
       <f:facet name="header">Current Node</f:facet>
       <h:outputText value="#{processInstance.rootToken.name}"/>
       </rich:column>
      
       <rich:column>
       <f:facet name="header">Actions</f:facet>
       <a:commandLink id="pauseProcessInstance"
       action="#{workflowProcessManager.suspendProcessInstance(processInstance.id)}"
       reRender="instanceTable"
       value="Pause">
       <s:conversationId />
       </a:commandLink>
       #{' '}
       <a:commandLink id="resumeProcessInstance"
       action="#{workflowProcessManager.resumeProcessInstance(processInstance.id)}"
       reRender="instanceTable"
       value="Restart">
       <s:conversationId />
       </a:commandLink>
       #{' '}
       <a:commandLink id="signalProcessInstances"
       action="#{workflowProcessManager.signalProcessInstance(processInstance.id)}"
       reRender="instanceTable"
       value="Signal">
       <s:conversationId />
       </a:commandLink>
       </rich:column>
       </rich:dataTable>
      
       </h:panelGrid>
      
       </rich:panel>
      


      The problem I experience is that the list of running ProcessInstances is not refreshed correctly, unless I add in the hibernate session flush() (commented out in the code above).

      The command service starts up a separate JbpmContext, which I believe is not seeing the results of the suspend() call, and so refreshes the .

      Should I be looking for a problem somewhere in the configuration, and if so where? Or am I using the Jbpm features incorrectly somehow? Or do I need to manually flush like this?

      Any pointers from more experienced people will be much appreciated...