| Seam JBPM integration |
| Written by F.Marchioni | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
jBPM provides sophisticated functionality for workflow and task management. In the previous article we've exposed a basic introduction to JBPM. This one focus on Seam and JBPM integration. Seam provides two nice additions to JBPM the first one (which this tutorial is about) is a powerful integration between Seam components + JSF and JBPM, the second one is Page Flow Definition : we'll treat this latter in a separate tutorial as it's simply a different way to describe your application flow and what actions and decisions can happen in each place. How seam integrates with JBPM ?Seam folds business processes into the Seam container by relying on three key coordinators:
Configuring Seam to work with JBPMStep 1 : Add JBPM libraries The JAR file jbpm-3.X.X.jar is required for jBPM and it is located under the lib directory of the Seam distribution. We need to place this JAR file at the root of the EAR and then add a reference to the JAR in the application.xml file. <application> <display-name>Sample JBPM Seam Application</display-name> <module> <web> <web-uri>seamJbpm.war</web-uri> <context-root>/seamJbpm</context-root> </web> </module> <module> <java>jboss-seam.jar</java> </module> <module> <java>jbpm-3.1.2.jar</java> </module> </application> Step 2: Add hibernate config file Step 3: Tell seam which are your process definitions (and pageflows) <bpm:jbpm> <bpm:process-definitions> <value>processDefinition.xml</value> </bpm:process-definitions> </bpm:jbpm>(Besides this you must declare here you pageflows, but we'll explore Page Flows in the next tutorial)
JBPM used in a standalone environment uses its own resource-local transactions when performing persistence operations. However when used in combination with Seam this can lead to transaction conflicts: so you need simply tell JBPM to participate in the global transaction managed by Seam (and not use its own) Add this line to jbpm.cfg.xml file:<jbpm-configuration> <jbpm-context> <service name="persistence"> <factory> <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory"> <field name="isTransactionEnabled"><false/></field> </bean> </factory> </service> <service name="tx" factory="org.jbpm.tx.TxServiceFactory" /> <service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" /> <service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" /> <service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" /> <service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" /> </jbpm-context> </jbpm-configuration> (Also this file will stay in the root of the ear) A Sample application
<process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="simple">
<start-state name="start">
<transition name="trPlaceOrder" to="PlaceOrder" />
</start-state>
<task-node name="PlaceOrder">
<task name="placeOrderTask">
<assignment actor-id="#{actor.id}" />
</task>
<transition name="next" to="Deliver" />
<transition name="cancel" to="error" />
</task-node>
<task-node name="Deliver">
<task name="getFromStock">
<assignment actor-id="#{actor.id}" />
</task>
<transition name="next" to="end" />
<transition name="cancel" to="error" />
</task-node>
<end-state name="error" />
<end-state name="end" />
</process-definition>
Notice the expression #{actor.id}. This is an example of how to inject a seam component into your process definition. In the next module everything will be clear.
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <html> <head> <title>Login</title> </head> <body> Enter your username <f:view> <h:form> <div> <h:inputText value="#{login.user}"/> <h:commandButton value="Login" action="#{login.login}"/> </div> </h:form> </f:view> </body> </html>This is the login Module
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.bpm.Actor;
@Name("login")
public class LoginModule
{
@In private Actor actor;
private String user;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String login()
{
actor.setId(user);
return "/todo.jsp";
}
}
Here's the actor object we've seen before.
<task name="getFromStock">
Believe it or not this little POJO does all the job that is needed to Create a task, and handle @Start and @Stop
import org.jboss.seam.annotations.bpm.CreateProcess;
import org.jboss.seam.annotations.bpm.EndTask;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.bpm.StartTask;
import org.jboss.seam.annotations.*;
import org.jboss.seam.ScopeType;
@Name("orderStock")
public class OrderStock
{
@Out(scope=ScopeType.BUSINESS_PROCESS, required=false)
Long processQuantity;
private int quantity ;
public int getQuantity()
{
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
@CreateProcess(definition="simple")
public void startProcess() {
processQuantity = new Long(getQuantity());
}
@StartTask
@EndTask(transition="next")
public void done() {
}
@StartTask
@EndTask(transition="cancel")
public void cancel() {
}
}
It's most intuitive: the method startProcess will be recalled by JSF to start the JBPM process
@CreateProcess(definition="simple") A last thing: maybe you've noticed the expression: this outjects the process variable processQuantity and makes it available to the view.
Piece n. 4 : the view componentOk so we need a last piece of this puzzle: the view component. this will be a standard JSF page BUT....with special Seam annotations in it:
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://jboss.com/products/seam/taglib" prefix="s"%>
<html>
<body>
<h2>Order system</h2>
<f:view>
<h:form id="list">
<div>
<h:outputText value="There are no order at the moment." rendered="#{empty taskInstancePriorityList}"/>
<h:dataTable value="#{taskInstancePriorityList}"
var="task" rendered="#{not empty taskInstancePriorityList}"
bgcolor="#F1F1F1" border="10">
<h:column>
<f:facet name="header">
<h:outputText value="Created"/>
</f:facet>
<h:outputText value="#{task.taskMgmtInstance.processInstance.start}">
<s:convertDateTime type="date"/>
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{task.name}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Quantity"/>
</f:facet>
<h:outputText value="#{task.variables['processQuantity']}"/>
</h:column>
<h:column>
<s:button action="#{orderStock.done}" taskInstance="#{task}" value="Done"/>
</h:column>
<h:column>
<s:button action="#{orderStock.cancel}" taskInstance="#{task}" value="Cancel"/>
</h:column>
</h:dataTable>
</div>
<div>
<h:messages/>
</div>
</h:form>
<h:form id="new">
<div>
<h:inputText value="#{orderStock.quantity}" />
<h:commandButton value="Enter order quantity" action="#{orderStock.startProcess}"/>
</div>
</h:form>
</f:view>
</body>
</html>
Here's a little explanation to the expression you find in the JSF:
#{taskInstancePriorityList} Loads the Datatable with an array of Tasks #{orderStock.done} Simple invocation of method done So can you see the beauty of Seam ? you have already lots of built-in to manage your process: in a JBPM standalone application you have to request the JBPM Context, query the Task list, fill the Task list in a Collection, feed this collection to JSF...simply to show your task. Packaging your application:Here's a view of your ear file:
Nothing new here, you should already know from the previous tutorial about seam.properties and components.xml. As said before components.xml holds the list of process definition used by this sample. I suggest you when you're beginning your Seam experiments to make use of the build.xml files that come with the distribution examples. There you don't have to worry about where to place your configuration files: they're already configured to go in the right place, just edit them and add classes under "src" and jsp pages ander "view".
Conclusion
JBoss.org Search
Custom Search
Only registered users can write comments!
Powered by !JoomlaComment 3.26
3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved." |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||



What is the Actor ? it's a Seam component that is stored in the session. In general, you should create your actor component when you are logging in to the website. 

