-
1. Re: HOW: jBPM context propagate to the current Conversation
uesker Sep 16, 2010 9:54 PM (in response to balazska)Hi! This is topic is old but I have the same issue...
How can I solve this? -
2. Re: HOW: jBPM context propagate to the current Conversation
lvdberg Sep 17, 2010 5:52 AM (in response to balazska)Hi,
jBPM will start its own
BPM-conversation
which is basically a long-running conversation, but a problem is that don't have the possibility to join an existing one. The simplest thing is to end a long-running conversation if one is active. This can be done through a description in pages.xml ot programmatically with the Seam conversation component, but you must do that OUTSIDE the bp.method (otherwise it fails the same).Leo
-
3. Re: HOW: jBPM context propagate to the current Conversation
uesker Sep 17, 2010 10:28 AM (in response to balazska)
Leo van den Berg wrote on Sep 17, 2010 05:52:
Hi,
jBPM will start its ownBPM-conversation
which is basically a long-running conversation, but a problem is that don't have the possibility to join an existing one. The simplest thing is to end a long-running conversation if one is active. This can be done through a description in pages.xml ot programmatically with the Seam conversation component, but you must do that OUTSIDE the bp.method (otherwise it fails the same).
LeoHi! Thanks!
-
4. Re: HOW: jBPM context propagate to the current Conversation
uesker Sep 17, 2010 1:26 PM (in response to balazska)Hi!
I forgot that the s:button component does not send forms. So I changed listActivities.xhtml page to
<h:form id="fillIdentificationForm"> <rich:panel> <div align="center"> <f:facet name="header">#{messages['srprocess.fillIdentification.page.title']}</f:facet> <h:outputText value="#{messages['srprocess.fillIdentification.page.description']}"/><br/> <rich:editor value="#{srProtocol.title}" width="640" height="480"/> <h:outputText value="#{messages['srprocess.fillIdentification.page.institution']}"/><br/> <rich:editor value="#{srProtocol.institution}" width="640" height="480"/> <h:outputText value="#{messages['srprocess.fillIdentification.page.authors']}"/><br/> <rich:editor value="#{srProtocol.authors}" width="640" height="480"/> <h:outputText value="#{messages['srprocess.fillIdentification.page.contact']}"/><br/> <rich:editor value="#{srProtocol.contact}" width="640" height="480"/> <h:outputText value="#{messages['srprocess.fillIdentification.page.date']}"/><br/> <rich:calendar value="#{srProtocol.date}" /> <div style="clear:both"/> </div> </rich:panel> <div class="actionButtons"> <h:commandButton value="#{messages['button.done']}" action="#{identificationAction.endFillIdentification}"> <f:param name="taskId" value="#{taskInstance.id}"/> </h:commandButton> <s:button propagation="end" id="cancel" value="#{messages['button.cancel']}" view="/listActivities.xhtml"/> </div>
And listActivities.page.xml to
<page xmlns="http://jboss.com/products/seam/pages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd"> <end-conversation/> </page>
And identificationAction to:
@Name("identificationAction") public class IdentificationAction implements Serializable { /** * */ private static final long serialVersionUID = -6691662478995279240L; @In private StatusMessages statusMessages; @In private SRProtocol srProtocol; public SRProtocol getSrProtocol() { return srProtocol; } public void setSrProtocol(SRProtocol srProtocol) { this.srProtocol = srProtocol; } @StartTask @EndTask(transition="identification done") public String endFillIdentification() { //TODO: work on srProtocol statusMessages.addFromResourceBundle("srprocess.fillidentification.page.sucess"); return "/listActivities.xhtml"; } }
the following exception is thrown
Exception during request processing: Caused by javax.servlet.ServletException with message: "#{identificationAction.endFillIdentification}: java.lang.IllegalStateException: task/process id may not be null"
Thanks!
-
5. Re: HOW: jBPM context propagate to the current Conversation
lvdberg Sep 20, 2010 6:32 AM (in response to balazska)Hi,
do you have any workflow defined, but you need to configure jBPM prior to using it. Meaning you need a processdefintion and configure that in components.xml.
Leo
-
6. Re: HOW: jBPM context propagate to the current Conversation
uesker Sep 20, 2010 2:56 PM (in response to balazska)
Leo van den Berg wrote on Sep 20, 2010 06:32:
Hi,
do you have any workflow defined, but you need to configure jBPM prior to using it. Meaning you need a processdefintion and configure that in components.xml.
LeoHi Leo,
I already did this.
Here is the code inside components.xml
<bpm:jbpm> <bpm:process-definitions> <value>systematicreview.jpdl.xml</value> </bpm:process-definitions> </bpm:jbpm>
The file is located inside ejbModule folder and the content is
<process-definition xmlns="urn:jbpm.org:jpdl-3.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jbpm.org:jpdl-3.2 http://docs.jboss.org/jbpm/xsd/jpdl-3.2.xsd" name="buildProtocol"> <start-state name="create"> <transition name="initiate" to="fill identification"/> </start-state> <task-node name="fill identification"> <task name="identification" description="#{messages['srprocess.fillidentification.description']}"> <assignment pooled-actors="researcher"/> </task> <transition name="identification done" to="fill context"/> </task-node> <task-node name="fill context"> <task name="context" description="#{messages['srprocess.fillcontext.description']}"> <assignment pooled-actors="researcher"/> </task> <transition name="context done" to="fill objectivies"/> </task-node> <task-node name="fill objectivies"> <task name="objectivies" description="#{messages['srprocess.fillobjectivies.description']}"> <assignment pooled-actors="researcher"/> </task> <transition name="objectivies done" to="fill metodology" /> </task-node> <task-node name="fill metodology"> <task name="metodology" description="#{messages['srprocess.choosemetodology.description']}"> <assignment pooled-actors="researcher"/> </task> <transition name="Systematic Review" to="fill meta analysis" /> <transition name="Quasi Systematic Review" to="fill primary question" /> </task-node> <task-node name="fill meta analysis"> <task name="meta analysis" description="#{messages['srprocess.choosemetaanalysis.description']}"> <assignment pooled-actors="researcher"/> </task> <transition name="Yes" to="fill statistics methods" /> <transition name="No" to="fill primary question" /> </task-node> <task-node name="fill statistics methods"> <task name="statistics methods" description="#{messages['srprocess.statisticsmethods.description']}"> <assignment pooled-actors="researcher"/> </task> <transition name="statistics methods done" to="fill primary question" /> </task-node> <task-node name="fill primary question"> <task name="primary question" description="#{messages['srprocess.primaryquestion.description']}"> <assignment pooled-actors="researcher"/> </task> <transition name="primary question" to="download artifacts" /> </task-node> <task-node name="download artifacts"> <task name="artifacts" description="#{messages['srprocess.downloadartifacts.description']}"> <assignment pooled-actors="researcher"/> </task> <transition name="download done" to="end process" /> </task-node> <end-state name="end process"/> </process-definition>
Anything else that I must do?
regards
-
7. Re: HOW: jBPM context propagate to the current Conversation
lvdberg Sep 21, 2010 3:33 AM (in response to balazska)Hi,
where is your process created? In other words where is the
@CreateProcess(definition="yourProcessDefinition")
Leo
-
8. Re: HOW: jBPM context propagate to the current Conversation
uesker Sep 21, 2010 9:50 AM (in response to balazska)Hi Leo,
i don´t use this annotation because I need made a verification before create a process instance.
The code is:@Name("homeAction") @Scope(ScopeType.SESSION) public class HomeAction implements Serializable { /** * */ private static final long serialVersionUID = -4694237049008052171L; @In private Actor actor; @In private StatusMessages statusMessages; @In private JbpmContext jbpmContext; private String idActor; private String idProject; public String getIdActor() { return idActor; } public void setIdActor(String id) { this.idActor = id; } public String getIdProject() { return idProject; } public void setIdProject(String idProject) { this.idProject = idProject; } public boolean isAvaliableToProceed() { return (idActor != null && idProject != null); } public void initializeParams() { if (idActor != null && idProject != null) { actor.setId(idActor); actor.getGroupActorIds().add("researcher"); } else { statusMessages.addFromResourceBundle("initialpage.paramsnotfound.message"); } } public String begin() { GraphSession gs = jbpmContext.getGraphSession(); ProcessDefinition def = gs.findLatestProcessDefinition("buildProtocol"); String processInstanceKey = "pik_" + getIdProject(); ProcessInstance pi = jbpmContext.getProcessInstance(def, processInstanceKey); if (pi == null) { pi = new ProcessInstance(def, null); pi.setKey(processInstanceKey); Token tkn = pi.getRootToken(); tkn.signal(); } else { //When I need to rerun tha app but the process instance was terminated if (pi.getTaskMgmtInstance().getTaskInstances() == null || pi.getTaskMgmtInstance().getTaskInstances().size() < 1) { pi = new ProcessInstance(def, null); pi.setKey(processInstanceKey); Token tkn = pi.getRootToken(); tkn.signal(); } else { pi.resume(); } } return "/listActivities.xhtml"; } }
Maybe the problem is located in listActivities.xhtml
<rich:dataTable value="#{pooledTaskInstanceList}" var="task" rendered="#{not empty pooledTaskInstanceList}"> <rich:column> <f:facet name="header">#{messages['task.processInstanceKey']}</f:facet> #{task.processInstance.key} </rich:column> <rich:column> <f:facet name="header">#{messages['task.name']}</f:facet> #{task.name} </rich:column> <rich:column> <f:facet name="header">#{messages['task.description']}</f:facet> #{task.description} </rich:column> <rich:column> <f:facet name="header">#{messages['task.date']}</f:facet> <h:outputText value="#{task.create}"> <f:convertDateTime pattern="dd/MM/yyyy HH:mm"/> </h:outputText> </rich:column> <rich:column> <s:link action="#{pooledTask.assignToCurrentActor}" value="#{messages['task.assign']}" taskInstance="#{task}" propagation="none"> <a4j:support event="onclick" ajaxSingle="true" reRender="pooledTasks, myTasks"/> </s:link> </rich:column> </rich:dataTable> <rich:spacer height="15px"/> <rich:separator height="10px"/> <rich:spacer height="15px"/> </a4j:outputPanel> <a4j:outputPanel id="myTasks"> <h:outputText value="#{messages['listactivities.mytasks.message']}" rendered="#{not empty taskInstanceList}"/> <h:outputText value="#{messages['srprocess.notasks.messages']}" rendered="#{empty taskInstanceList}"/> <rich:dataTable value="#{taskInstanceList}" var="_task" rendered="#{not empty taskInstanceList}"> <rich:column> <f:facet name="header">#{messages['task.processInstanceKey']}</f:facet> #{_task.processInstance.key} </rich:column> <rich:column> <f:facet name="header">#{messages['task.name']}</f:facet> #{_task.name} </rich:column> <rich:column> <f:facet name="header">#{messages['task.description']}</f:facet> #{_task.description} </rich:column> <rich:column> <f:facet name="header">#{messages['task.date']}</f:facet> <h:outputText value="#{_task.create}"> <f:convertDateTime pattern="dd/MM/yyyy HH:mm"/> </h:outputText> </rich:column> <rich:column> <s:link action="#{pageDecisionHandler.redirectToPage}" taskInstance="#{_task}" value="#{messages['task.execute']}" /> </rich:column> <rich:column> <s:link value="#{messages['task.unassign']}" action="#{pooledTask.unassign}" taskInstance="#{_task}"> <a4j:support event="onclick" ajaxSingle="true" reRender="pooledTasks, myTasks"/> </s:link> </rich:column> </rich:dataTable>
Before execute a task, I need to find out which page to redirect. So I created another component.
@Name("pageDecisionHandler") @Scope(ScopeType.CONVERSATION) public class PageDecisionHandler { @In @Out private TaskInstance taskInstance; @BeginTask(flushMode=FlushModeType.MANUAL) @Begin(join=true) public String redirectToPage() { if (taskInstance != null) { String taskName = taskInstance.getName(); if (taskName.equalsIgnoreCase("identification")) { return "/researchquestion/fillIdentification.xhtml"; } else if (taskName.equalsIgnoreCase("context")) { return "/researchquestion/fillContext.xhtml"; } else if (taskName.equalsIgnoreCase("objectivies")) { return "/researchquestion/fillObjectivies.xhtml"; } else if (taskName.equalsIgnoreCase("metodology")) { return "/researchquestion/methodologicalProcedure.xhtml"; } else if (taskName.equalsIgnoreCase("meta analysis")) { return "/researchquestion/metaAnalysis.xhtml"; } else if (taskName.equals("statistics methods")) { return "/researchquestion/fillStatisticsMethods"; } else if (taskName.equalsIgnoreCase("primary question")) { return "/researchquestion/fillPrimaryQuestion"; } else if (taskName.equalsIgnoreCase("artifacts")) { return "/summarization/generateProtocol.xhtml"; } } return null; } }
The rest of code is presented on messages above
The funny is that if I remove @StarTask from method and place on listActivities.page.xml it´s works. But with that, when I enter on page, the task it´s initiated, something that i´d like to do only when user press the done button.Thanks
-
9. Re: HOW: jBPM context propagate to the current Conversation
lvdberg Sep 21, 2010 10:04 AM (in response to balazska)Hi,
this explains a lot. You can use a method call with params in EL, so you can do something like:
action="#{pageDecisionHandler.redirectToPage(_task)}"
This will give you the task reference directly, so you can interact with jBPM directly and retrieve all task information you need.
I normally use this way to inetact with jBPM and you can use the same approach from within jpdl. So the diffeernt vars can be send directly to bean-methods (processInstance, taskInstance etc.)Leo
-
10. Re: HOW: jBPM context propagate to the current Conversation
uesker Sep 21, 2010 10:28 AM (in response to balazska)
Leo van den Berg wrote on Sep 21, 2010 10:04:
Hi,
this explains a lot. You can use a method call with params in EL, so you can do something like:action="#{pageDecisionHandler.redirectToPage(_task)}"
This will give you the task reference directly, so you can interact with jBPM directly and retrieve all task information you need.
I normally use this way to inetact with jBPM and you can use the same approach from within jpdl. So the diffeernt vars can be send directly to bean-methods (processInstance, taskInstance etc.)
LeoI´m sorry... but when I do that, the value of taskInstance variable on method is null.
package br.ufrj.cos.ese.configuradorrs.session; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Begin; import org.jboss.seam.annotations.FlushModeType; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Out; import org.jboss.seam.annotations.Scope; import org.jboss.seam.annotations.bpm.BeginTask; import org.jbpm.taskmgmt.exe.TaskInstance; @Name("pageDecisionHandler") @Scope(ScopeType.CONVERSATION) public class PageDecisionHandler { @BeginTask(flushMode=FlushModeType.MANUAL) @Begin(join=true) public String redirectToPage(TaskInstance taskInstance) { if (taskInstance != null) { String taskName = taskInstance.getName(); if (taskName.equalsIgnoreCase("identification")) { return "/researchquestion/fillIdentification.xhtml"; } else if (taskName.equalsIgnoreCase("context")) { return "/researchquestion/fillContext.xhtml"; } else if (taskName.equalsIgnoreCase("objectivies")) { return "/researchquestion/fillObjectivies.xhtml"; } else if (taskName.equalsIgnoreCase("metodology")) { return "/researchquestion/methodologicalProcedure.xhtml"; } else if (taskName.equalsIgnoreCase("meta analysis")) { return "/researchquestion/metaAnalysis.xhtml"; } else if (taskName.equals("statistics methods")) { return "/researchquestion/fillStatisticsMethods"; } else if (taskName.equalsIgnoreCase("primary question")) { return "/researchquestion/fillPrimaryQuestion"; } else if (taskName.equalsIgnoreCase("artifacts")) { return "/summarization/generateProtocol.xhtml"; } } return null; } }
-
11. Re: HOW: jBPM context propagate to the current Conversation
lvdberg Sep 21, 2010 10:41 AM (in response to balazska)Hi,
this is a piece of code from a comparable tasklist page.
<a4j:commandLink value="START" action="#{taskFinish.testTask(_task)}" eventsQueue="inputQueue" requestDelay="750" ignoreDupResponses="true" reRender="taskPanel" > <a4j:actionparam name="taskId" value="#{_task.id}" /> </a4j:commandLink>
@Override @TransactionAttribute(TransactionAttributeType.REQUIRED) @Transactional public void testTask(long taskId) { TaskInstance task = jbpmContext.getTaskInstance(taskId); ProcessInstance pi = task.getProcessInstance(); //... A lot of code here task.addComment("Successfully ended task " + task.getName()); task.end(); }
And it works without a problemm
Leo
-
12. Re: HOW: jBPM context propagate to the current Conversation
lvdberg Sep 21, 2010 10:48 AM (in response to balazska)Hi,
My apologies I copied the wrong version:
<a4j:commandLink value="#{messages['workflow_task_resume']}" rendered="#{_task.start != null}" action="#{taskFinish.resumeTask(_task)}" eventsQueue="inputQueue" requestDelay="750" oncomplete="#{rich:component('taskModalPanel')}.show();" ignoreDupResponses="true" reRender="tasks, taskPanel, growl" > <a4j:actionparam name="taskId" value="#{_task.id}" /> </a4j:commandLink> @Transactional @BeginTask(flushMode=FlushModeType.MANUAL) public String resumeTask(TaskInstance task){ String uniqueCode = (String) task.getVariables().get("uniqueCode"); boolean status = infraWebEditAction.selectIncidentByCode(uniqueCode); if (status){ log.info("Resuming task " + task.getName() + " for incident " + uniqueCode ); selector = task.getName(); return "begin"; } else { log.error("Task cannot be started, no incident found"); return "error"; } }
-
13. Re: HOW: jBPM context propagate to the current Conversation
lvdberg Sep 21, 2010 10:54 AM (in response to balazska)And the TaskFinish part:
<a4j:commandButton id="finishButton" image="/images/16/Verify_Document.png" value="#{messages['workflow_task_end']}" action="#{taskFinish.endTask}" eventsQueue="inputQueue" requestDelay="750" oncomplete="#{rich:component('taskModalPanel')}.hide();" ignoreDupResponses="true" reRender="tasks, growl" > <rich:toolTip for="finishButton" styleClass="tooltip"> <h:outputText value="#{messages['workflow_task_finish_tooltip']}" /> </rich:toolTip> </a4j:commandButton>
And the bean:
@Transactional @EndTask public String endTask(){ log.info("Finishing task and closing task window"); infraWebEditAction.saveEvaluationData(); incident = infraWebEditAction.getIncident(); try { trafficIncidentRepository.updateTrafficIncident(incident); } catch (ValidationException e) { e.printStackTrace(); } entityManager.flush(); log.info("Saving evaluation data and ending task"); return "ended"; }
The tasklist basically open a modalpanel with some content and after pressing the end-button th task is closed.
As you can se I use the Taskinstance from the method and (although included) NOT a context var with the task id.
Hopefully this is helpful.
Leo
-
14. Re: HOW: jBPM context propagate to the current Conversation
uesker Sep 22, 2010 10:37 AM (in response to balazska)Hi,
What it´s dificult to understand it´s the transition between PageDecisionHandler.redirectToPage and the page that will start/end the task.
The problem it´s that TaskInstance is not propagated.
I have another examples that it work. The diference it´s that I start the task on pages.xml, like this:
<?xml version="1.0" encoding="UTF-8"?> <page xmlns="http://jboss.com/products/seam/pages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd"> <start-task task-id="#{taskInstance.id}"/> <param name="taskId"/> </page>
On current project, I wish to start and end the task on same method. So, the only thing in pages.xml is
<?xml version="1.0" encoding="UTF-8"?> <page xmlns="http://jboss.com/products/seam/pages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd"> <end-conversation/> <param name="taskId"/> </page>
If I try to do something similar to
<?xml version="1.0" encoding="UTF-8"?> <page xmlns="http://jboss.com/products/seam/pages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd"> <end-conversation/> <begin-task task-id="#{taskInstance.id"} <param name="taskId"/> </page>
An exception is thrown, because the conflict between end-conversation and begin-task.
Maybe I could get the taskId param on url and try to get acess to TaskInstance manually, but I don´t now how can I do this.
regards,
Rafael