此内容没有您所选择的语言版本。

1.4. Seam and jBPM: the todo list example


jBPM provides sophisticated functionality for workflow and task management. As an example of jBPM's integration with Seam, what follows is a simple "todo list" application. Managing task lists is a core function of jBPM, so little Java is required in this example.

1.4.1. Understanding the code

This example revolves around the jBPM process definition. It also uses two JSPs and two basic JavaBeans. (Session beans are not required here since they would not access the database or have any transactional behavior.) We will start with the process definition:

Example 1.16. todo.jpdl.xml

<process-definition name="todo">
  
  <start-state name="start">                                    
    <transition to="todo"/>
  </start-state>
  
  <task-node name="todo">                                       
    <task name="todo" description="#{todoList.description}">    
      <assignment actor-id="#{actor.id}"/>                      
    </task>
    <transition to="done"/>
  </task-node>
  
  <end-state name="done"/>                                      
  
</process-definition>
Copy to Clipboard Toggle word wrap

1

The <start-state> node represents the logical start of the process. When the process starts, it immediately transitions to the todo node.

2

The <task-node> node represents a wait state, where business process execution pauses, waiting for one or more tasks to be performed.

3

The <task> element defines a task to be performed by a user. Since there is only one task defined on this node, when it is complete, execution resumes, and we transition to the end state. The task gets its description from a Seam component named todoList (one of the JavaBeans).

4

Tasks need to be assigned to a user or group of users when they are created. In this case, the task is assigned to the current user, which we get from a built-in Seam component named actor. Any Seam component may be used to perform task assignment.

5

The <end-state> node defines the logical end of the business process. When execution reaches this node, the process instance is destroyed.
Viewed with the process definition editor provided by JBossIDE, the process definition looks like this:
This document defines our business process as a graph of nodes. This is the simplest possible business process: there is one task to be performed, and when that task is complete, the business process ends.
The first JavaBean handles the login screen, login.jsp. Here, it simply initializes the jBPM actor ID with the actor component. In a real application, it would also need to authenticate the user.

Example 1.17. Login.java

@Name("login")
public class Login {
    @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";
    }
}
Copy to Clipboard Toggle word wrap
Here we see the use of @In to inject the built-in Actor component.
The JSP itself is trivial:

Example 1.18. login.jsp

<%@ 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>
    <h1>Login</h1>
    <f:view>
      <h:form>
        <div>
          <h:inputText value="#{login.user}"/>
          <h:commandButton value="Login" action="#{login.login}"/>
        </div>
      </h:form>
    </f:view>
  </body>
</html>
Copy to Clipboard Toggle word wrap
The second JavaBean is responsible for starting business process instances, and ending tasks.

Example 1.19. TodoList.java

@Name("todoList")
public class TodoList
{
   private String description;                       
   
   public String getDescription()
   {
      return description;
   }

   public void setDescription(String description)
   {
      this.description = description;
   }
   
   @CreateProcess(definition="todo")                 
   public void createTodo() {}
   
   @StartTask @EndTask                               
   public void done() {}

}
Copy to Clipboard Toggle word wrap

1

The description property accepts user input from the JSP page, and exposes it to the process definition, allowing the task description to be set.

2

The Seam @CreateProcess annotation creates a new jBPM process instance for the named process definition.

3

The Seam @StartTask annotation starts work on a task. The @EndTask ends the task, and allows the business process execution to resume.
In a more realistic example, @StartTask and @EndTask would not appear on the same method, because some work would need to be done with the application in order to complete the task.
Finally, the core of the application is in todo.jsp:

Example 1.20. todo.jsp

<%@ 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>
  <head>
    <title>Todo List</title>
  </head>
  <body>
    <h1>Todo List</h1>
    <f:view>
      <h:form id="list">
        <div>
          <h:outputText value="There are no todo items." 
                        rendered="#{empty taskInstanceList}"/>
          <h:dataTable value="#{taskInstanceList}" var="task" 
                       rendered="#{not empty taskInstanceList}">
            <h:column>
              <f:facet name="header">
                <h:outputText value="Description"/>
              </f:facet>
              <h:inputText value="#{task.description}"/>
            </h:column>
            <h:column>
              <f:facet name="header">
                <h:outputText value="Created"/>
              </f:facet>
              <h:outputText value=
                            "#{task.taskMgmtInstance.processInstance.start}">
                <f:convertDateTime type="date"/>
              </h:outputText>
            </h:column>
            <h:column>
              <f:facet name="header">
                <h:outputText value="Priority"/>
              </f:facet>
              <h:inputText value="#{task.priority}" style="width: 30"/>
            </h:column>
            <h:column>
              <f:facet name="header">
                <h:outputText value="Due Date"/>
              </f:facet>
              <h:inputText value="#{task.dueDate}" style="width: 100">
                <f:convertDateTime type="date" dateStyle="short"/>
              </h:inputText>
            </h:column>
            <h:column>
              <s:button value="Done" action="#{todoList.done}" 
                        taskInstance="#{task}"/>
            </h:column>
          </h:dataTable>
        </div>
        <div>
          <h:messages/>
        </div>
        <div>
          <h:commandButton value="Update Items" action="update"/>
        </div>
      </h:form>
      <h:form id="new">
        <div>
          <h:inputText value="#{todoList.description}"/>
          <h:commandButton value="Create New Item" 
                           action="#{todoList.createTodo}"/>
        </div>
      </h:form>
    </f:view>
  </body>
</html>
Copy to Clipboard Toggle word wrap
For simplicity's sake, we will look at this once section at a time.
The page renders a list of tasks, which it retrieves from a built-in Seam component named taskInstanceList. The list is defined inside a JSF form.

Example 1.21. todo.jsp (taskInstanceList)

<h:form id="list">
  <div>
    <h:outputText value="There are no todo items." 
                  rendered="#{empty taskInstanceList}"/>
    <h:dataTable value="#{taskInstanceList}" var="task" 
                 rendered="#{not empty taskInstanceList}">
      ...
    </h:dataTable>
  </div>
</h:form>
Copy to Clipboard Toggle word wrap
Each element of the list is an instance of the jBPM class TaskInstance. The following code displays certain properties for every task in the list. Input controls are used for description, priority, and due date to allow users to update these values.

Example 1.22. TaskInstance List Properties

<h:column>
  <f:facet name="header">
    <h:outputText value="Description"/>
  </f:facet>
  <h:inputText value="#{task.description}"/>
</h:column>
<h:column>
  <f:facet name="header">
    <h:outputText value="Created"/>
  </f:facet>
  <h:outputText value="#{task.taskMgmtInstance.processInstance.start}">
    <f:convertDateTime type="date"/>
  </h:outputText>
</h:column>
<h:column>
  <f:facet name="header">
    <h:outputText value="Priority"/>
  </f:facet>
  <h:inputText value="#{task.priority}" style="width: 30"/>
</h:column>
<h:column>
  <f:facet name="header">
    <h:outputText value="Due Date"/>
  </f:facet>
  <h:inputText value="#{task.dueDate}" style="width: 100">
    <f:convertDateTime type="date" dateStyle="short"/>
  </h:inputText>
</h:column>
Copy to Clipboard Toggle word wrap

Note

Seam provides a default JSF date converter for converting a string into a date, so no converter is necessary for the field bound to #{task.dueDate}.
This button ends the task by calling the action method annotated @StartTask @EndTask. It passes the task ID to Seam as a request parameter:
<h:column> 
  <s:button value="Done" action="#{todoList.done}" 
            taskInstance="#{task}"/>
</h:column>
			
			
			

Copy to Clipboard Toggle word wrap
Note that this uses a Seam <s:button> JSF control from the seam-ui.jar package. This button updates the properties of the tasks. When the form is submitted, Seam and jBPM will make any changes to the tasks persistent. There is no need for any action listener method:
 <h:commandButton value="Update Items" action="update"/>
Copy to Clipboard Toggle word wrap
A second form on the page creates new items with the action method annotated @CreateProcess.
 <h:form id="new">
   <div> 
      <h:inputText value="#{todoList.description}"/> 
      <h:commandButton value="Create New Item" 
         action="#{todoList.createTodo}"/>
    </div> 
</h:form>
Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat