﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-XZC.Log-随笔分类-BPM</title><link>http://www.blogjava.net/xzclog/category/32017.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 07 Jun 2008 07:15:01 GMT</lastBuildDate><pubDate>Sat, 07 Jun 2008 07:15:01 GMT</pubDate><ttl>60</ttl><item><title>向应用程序中加入jBPM组件 </title><link>http://www.blogjava.net/xzclog/archive/2006/10/24/76966.html</link><dc:creator>xzc</dc:creator><author>xzc</author><pubDate>Tue, 24 Oct 2006 06:18:00 GMT</pubDate><guid>http://www.blogjava.net/xzclog/archive/2006/10/24/76966.html</guid><wfw:comment>http://www.blogjava.net/xzclog/comments/76966.html</wfw:comment><comments>http://www.blogjava.net/xzclog/archive/2006/10/24/76966.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xzclog/comments/commentRss/76966.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzclog/services/trackbacks/76966.html</trackback:ping><description><![CDATA[		<div style="TEXT-INDENT: 24pt">本文介绍怎样把jBPM组件添加到Web应用程序中。所需要用到的资源，可以在jbpm-starters-kit-3.1.2中找到。</div>
		<div>一、首先安装jBPM数据库。jBPM是一个停止状态的组件，需要数据库表持久化保存：1）业务程序定义和业务程序实例及相关的工作流数据。保障工作流引擎的执行。2）异步系统使用数据库表来模拟消息系统的功能。需要把消息到数据库表中，由消息系统的命令执行器异步查询和执行。不像专业的消息系统那样是远程的。它仅仅使用数据库模拟消息系统。</div>
		<div>1，打开MySQL的命令执行工具Query Browser。</div>
		<div>2，当前选定应用程序的数据库，如wcms。</div>
		<div>3，导入脚本文件：mysql.drop.create.sql</div>
		<div>4，执行该脚本。会在当前数据库中增加jBPM的数据库表。</div>
		<div>&#160;</div>
		<div>二、导入jBPM所需的.jar文件</div>
		<div>1，jbpmlib目录中包含了jBPM所需的全部jar包。包括MySQL的jdbc包。</div>
		<div>2，把它整个复制到应用程序的lib目录下。</div>
		<div>3，应用程序的构建器路径的&#8220;库&#8221;中，把这些jar都加进来。</div>
		<div style="TEXT-INDENT: 24pt">这些classpath下的jar包，都会被该Web应用程序的类载入器载入。</div>
		<div>&#160;</div>
		<div>三、创建config.files和processes目录，并加入classpath的源代码路径</div>
		<div style="TEXT-INDENT: 24pt">（一）config.files目录的功能</div>
		<div>
				<span>&#160;&#160;&#160; </span>这个目录存放jBPM的各类配置文件。放在这里（就是classpath顶层）的配置文件会取代jBPM的jar包中各处的配置文件。</div>
		<div style="TEXT-INDENT: 24pt">这里，由于需要使用mysql，而不是内置的hsql内存数据库。所以我们提供了一个修改过的配置文件：hibernate.cfg.xml。这里提供了Hibernate3的配置。</div>
		<div style="TEXT-INDENT: 24pt">hibernate.cfg.xml配置文件的部分内容</div>
		<div style="TEXT-INDENT: 24pt">
		</div>
		<div style="TEXT-INDENT: 24pt">&lt;hibernate-configuration&gt;<br />&#160; &lt;session-factory&gt;</div>
		<div style="TEXT-INDENT: 24pt">&#160;&#160;&#160; &lt;!-- jdbc connection properties</div>
		<div style="TEXT-INDENT: 24pt">原来的HSQL配置被注释掉，使用MySQL数据库的配置<br />&#160; &lt;property name="hibernate.dialect"&gt;org.hibernate.dialect.HSQLDialect&lt;/property&gt;<br />&#160;&#160;&#160; &lt;property name="hibernate.connection.driver_class"&gt;org.hsqldb.jdbcDriver&lt;/property&gt;<br />&#160;&#160;&#160; &lt;property name="hibernate.connection.url"&gt;jdbc:hsqldb:mem:.;sql.enforce_strict_size=true&lt;/property&gt;<br />&#160;&#160;&#160; &lt;property name="hibernate.connection.username"&gt;sa&lt;/property&gt;<br />&#160;&#160;&#160; &lt;property name="hibernate.connection.password"&gt;&lt;/property&gt;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;--&gt;<br />&#160;&#160;&#160; &lt;property name="hibernate.dialect"&gt;org.hibernate.dialect.MySQLInnoDBDialect&lt;/property&gt;<br />&#160;&#160;&#160; &lt;property name="hibernate.connection.driver_class"&gt;com.mysql.jdbc.Driver&lt;/property&gt;<br />&#160;&#160;&#160; &lt;property name="hibernate.connection.url"&gt;jdbc:mysql://localhost:3306/wcms&lt;/property&gt;<br />&#160;&#160;&#160; &lt;property name="hibernate.connection.username"&gt;root&lt;/property&gt;<br />&#160;&#160;&#160; &lt;property name="hibernate.connection.password"&gt;root&lt;/property&gt;</div>
		<div style="TEXT-INDENT: 24pt">
		</div>
		<div style="TEXT-INDENT: 24pt">
		</div>
		<div style="TEXT-INDENT: 24pt">
		</div>
		<div style="TEXT-INDENT: 24pt">
		</div>
		<div style="TEXT-INDENT: 24pt">（二）processes目录的功能</div>
		<div style="TEXT-INDENT: 24pt">这个目录存放process流程定义。如：manageNews\内有3个文件。</div>
		<div style="TEXT-INDENT: 24pt">在jBPM应用程序导入.par或.xml文件时,使用相对路径（如：withubCMS/processdefinition.xml）来定位业务程序定义资源文件。</div>
		<div>&#160;</div>
		<div style="TEXT-INDENT: 24pt">怎样把它们放到classpath下，需要根据不同的环境进行不同的处理。</div>
		<div style="TEXT-INDENT: 24pt">一、一般Java程序</div>
		<div>
				<span>&#160;&#160;&#160; 1</span>，创建config.files和processes目录。</div>
		<div style="TEXT-INDENT: 24pt">2，配置构建器路径，将这2个目录设为到classpath的源代码路径。</div>
		<div style="TEXT-INDENT: 24pt">这样，运行时，会把它们中的内容复制到classpath目录下。</div>
		<div style="TEXT-INDENT: 24pt">二、Eclipse下的Web程序</div>
		<div style="TEXT-INDENT: 24pt">我们使用Eclipse自带的功能发布Web程序。</div>
		<div>
				<span>&#160;&#160;&#160; 1</span>，创建config.files和processes目录。</div>
		<div style="TEXT-INDENT: 24pt">2，配置构建器路径，将这2个目录设为到classpath的源代码路径。</div>
		<div style="TEXT-INDENT: 24pt">3，配置classpath,也就是&#8220;缺省输出文件夹&#8221;，为：</div>
		<div style="TEXT-INDENT: 24pt">内容管理（应用程序根路径名）/webapps/WEB-INF/classes</div>
		<div style="TEXT-INDENT: 24pt">4，这样，在Eclipse编译时（默认是保存即编译），把这2个文件夹中的内容复制到classpath下。</div>
		<div style="TEXT-INDENT: 24pt">5，然后，使用Eclipse自带的功能，发布该Web应用程序。</div>
		<div style="TEXT-INDENT: 24pt">Eclipse会把/webapps/文件夹下的所有内容复制到Web服务器下，并且把webapps改名为该Web应用程序的Eclipse项目名字。</div>
		<div style="TEXT-INDENT: 24pt">这样，我们的配置，对于classpath来说也是正确的！Web应用程序可以顺利地运行。</div>
		<div style="TEXT-INDENT: 24pt">三、Ant发布的Web程序</div>
		<div style="TEXT-INDENT: 24pt">可以和上面一样。把这些classpath的源文件，编译，然后把内部的内容复制到classpath下。</div>
		<div style="TEXT-INDENT: 24pt">Web项目运行时的classpath是classes和lib。当然也需要把jar包都复制到lib下。</div>
		<div style="TEXT-INDENT: 24pt">&#160;</div>
		<div style="TEXT-INDENT: 24pt">最后，在内容管理\webapps\WEB-INF\jbpm\下放置那2个目录。并把它们设为classpath的源路径。</div>
		<div style="TEXT-INDENT: 24pt">目标classpath路径是内容管理\webapps\WEB-INF\classes。</div>
		<div>&#160;</div>
		<div style="TEXT-INDENT: 24pt">&#160;</div>
		<div>四、测试jBPM和数据库</div>
		<div style="TEXT-INDENT: 24pt">建立test源文件夹。提供一个junit测试类:org.jbpm.test.db.<span style="FONT-SIZE: 10pt; BACKGROUND: silver">HelloWorldDbTest</span><span style="FONT-SIZE: 10pt; BACKGROUND: silver">。</span></div>
		<div style="TEXT-INDENT: 24pt">这个类使用字符串定义了一个简单的业务程序，然后在数据库上完整的执行它。</div>
		<div style="TEXT-INDENT: 24pt">执行该单元测试。在应用程序的数据库中的2个表：</div>
		<div style="TEXT-INDENT: 24pt">SELECT * FROM jbpm_processdefinition j;</div>
		<div style="TEXT-INDENT: 24pt">SELECT * FROM jbpm_processinstance j;</div>
		<div style="TEXT-INDENT: 24pt">应该有数据。</div>
		<div>&#160;</div>
		<div>
				<span>&#160;&#160;&#160; </span>至此，jBPM组件就成功地加入到Web应用程序中了！</div>
		<div>
		</div>
		<div>附录：HelloWorldDbTest.java源代码</div>
		<div>package org.jbpm.test.db;</div>
		<div>import java.util.List;</div>
		<div>import junit.framework.TestCase;</div>
		<div>import org.jbpm.JbpmConfiguration;<br />import org.jbpm.JbpmContext;<br />import org.jbpm.db.GraphSession;<br />import org.jbpm.graph.def.ProcessDefinition;<br />import org.jbpm.graph.exe.ProcessInstance;<br />import org.jbpm.graph.exe.Token;</div>
		<div>public class HelloWorldDbTest extends TestCase {<br />&#160; <br />&#160; static JbpmConfiguration jbpmConfiguration = null; </div>
		<div>&#160; static {<br />&#160;&#160;&#160; // An example configuration file such as this can be found in <br />&#160;&#160;&#160; // 'src/config.files'.&#160; Typically the configuration information is in the <br />&#160;&#160;&#160; // resource file 'jbpm.cfg.xml', but here we pass in the configuration <br />&#160;&#160;&#160; // information as an XML string.<br />&#160;&#160;&#160; <br />&#160;&#160;&#160; // First we create a JbpmConfiguration statically.&#160; One JbpmConfiguration<br />&#160;&#160;&#160; // can be used for all threads in the system, that is why we can safely <br />&#160;&#160;&#160; // make it static.<br />&#160;&#160; /**<br />&#160;&#160;&#160; *单例对象。<br />&#160;&#160;&#160; *JbpmConfiguration能够被系统中所有线程所使用。<br />&#160;&#160;&#160; *jbpm.cfg.xml这个命名方式和Hibernate配置文件的命名方式一致。<br />&#160;&#160;&#160; *<br />&#160;&#160;&#160; */</div>
		<div>&#160;&#160;&#160; jbpmConfiguration = JbpmConfiguration.parseXmlString(<br />&#160;&#160;&#160;&#160;&#160; "&lt;jbpm-configuration&gt;" +<br />&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; // A jbpm-context mechanism separates the jbpm core <br />&#160;&#160;&#160;&#160;&#160; // engine from the services that jbpm uses from <br />&#160;&#160;&#160;&#160;&#160; // the environment. <br />&#160;&#160;&#160;&#160;&#160; /*jbpm-context机制在环境中把jbpm核心引擎和jbpm使用的服务分开。<br />&#160;&#160;&#160;&#160;&#160;&#160; * 持久化服务是jbpm核心引擎使用的一个服务。<br />&#160;&#160;&#160;&#160;&#160;&#160; * <br />&#160;&#160;&#160;&#160;&#160;&#160; * */<br />&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;jbpm-context&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160;&#160;&#160; &lt;service name='persistence' " +<br />&#160;&#160;&#160;&#160;&#160; "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' /&gt;" + <br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;/jbpm-context&gt;" +<br />&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; // Also all the resource files that are used by jbpm are <br />&#160;&#160;&#160;&#160;&#160; // referenced from the jbpm.cfg.xml<br />&#160;&#160;&#160;&#160;&#160; /*<br />&#160;&#160;&#160;&#160;&#160;&#160; *string，配置了所有jbpm使用的资源文件的路径。<br />&#160;&#160;&#160;&#160;&#160;&#160; * */<br />&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;string name='resource.hibernate.cfg.xml' " +<br />&#160;&#160;&#160;&#160;&#160; "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; value='hibernate.cfg.xml' /&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;string name='resource.business.calendar' " +<br />&#160;&#160;&#160;&#160;&#160; "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; value='org/jbpm/calendar/jbpm.business.calendar.properties' /&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;string name='resource.default.modules' " +<br />&#160;&#160;&#160;&#160;&#160; "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; value='org/jbpm/graph/def/jbpm.default.modules.properties' /&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;string name='resource.converter' " +<br />&#160;&#160;&#160;&#160;&#160; "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; value='org/jbpm/db/hibernate/jbpm.converter.properties' /&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;string name='resource.action.types' " +<br />&#160;&#160;&#160;&#160;&#160; "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; value='org/jbpm/graph/action/action.types.xml' /&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;string name='resource.node.types' " +<br />&#160;&#160;&#160;&#160;&#160; "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; value='org/jbpm/graph/node/node.types.xml' /&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;string name='resource.varmapping' " +<br />&#160;&#160;&#160;&#160;&#160; "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; value='org/jbpm/context/exe/jbpm.varmapping.xml' /&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&lt;/jbpm-configuration&gt;"<br />&#160;&#160;&#160; );<br />&#160; }<br />&#160; <br />&#160; public void setUp() {<br />&#160;&#160; //创建数据库表<br />&#160;&#160;&#160; //jbpmConfiguration.createSchema();<br />&#160; }<br />&#160; <br />&#160; public void tearDown() {<br />&#160;&#160; //删除数据库表<br />&#160;&#160;&#160; //jbpmConfiguration.dropSchema();<br />&#160; }</div>
		<div>&#160; public void testSimplePersistence() {<br />&#160;&#160;&#160; // Between the 3 method calls below, all data is passed via the <br />&#160;&#160;&#160; // database.&#160; Here, in this unit test, these 3 methods are executed<br />&#160;&#160;&#160; // right after each other because we want to test a complete process<br />&#160;&#160;&#160; // scenario情节.&#160; But in reality, these methods represent different <br />&#160;&#160;&#160; // requests to a server.<br />&#160;&#160;&#160; <br />&#160;&#160;&#160; // Since we start with a clean, empty in-memory database, we have to <br />&#160;&#160;&#160; // deploy the process first.&#160; In reality, this is done once by the <br />&#160;&#160;&#160; // process developer.<br />&#160;&#160; /**<br />&#160;&#160;&#160; *&#160; 这个方法把业务处理定义通过Hibernate保存到数据库中。<br />&#160;&#160;&#160; */<br />&#160;&#160;&#160; deployProcessDefinition();</div>
		<div>&#160;&#160;&#160; // Suppose we want to start a process instance (=process execution)<br />&#160;&#160;&#160; // when a user submits a form in a web application...<br />&#160;&#160;&#160; /*假设当一个用户提交一个表单时，我们要开始一个业务处理的实例/执行。<br />&#160;&#160;&#160;&#160; * 这可以在Action中执行处理。<br />&#160;&#160;&#160;&#160; */<br />&#160;&#160;&#160; processInstanceIsCreatedWhenUserSubmitsWebappForm();</div>
		<div>&#160;&#160;&#160; // Then, later, upon the arrival of an asynchronous message the <br />&#160;&#160;&#160; // execution must continue.<br />&#160;&#160;&#160; /*<br />&#160;&#160;&#160;&#160; * 然后，直到异步消息来到，才继续执行业务处理实例的余下的工作流程。<br />&#160;&#160;&#160;&#160; * */<br />&#160;&#160;&#160; theProcessInstanceContinuesWhenAnAsyncMessageIsReceived();<br />&#160; }</div>
		<div>&#160; public void deployProcessDefinition() {<br />&#160;&#160;&#160; // This test shows a process definition and one execution <br />&#160;&#160;&#160; // of the process definition.&#160; The process definition has <br />&#160;&#160;&#160; // 3 nodes: an unnamed start-state, a state 's' and an <br />&#160;&#160;&#160; // end-state named 'end'.<br />&#160;&#160; /*<br />&#160;&#160;&#160; * 这个方法把业务处理定义通过Hibernate保存到数据库中。<br />&#160;&#160;&#160; * <br />&#160;&#160;&#160; * */<br />&#160;&#160;&#160; ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(<br />&#160;&#160;&#160;&#160;&#160; "&lt;process-definition name='hello world'&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;start-state name='start'&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160;&#160;&#160; &lt;transition to='s' /&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;/start-state&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;state name='s'&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160;&#160;&#160; &lt;transition to='end' /&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;/state&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&#160; &lt;end-state name='end' /&gt;" +<br />&#160;&#160;&#160;&#160;&#160; "&lt;/process-definition&gt;"<br />&#160;&#160;&#160; );</div>
		<div>&#160;&#160;&#160; // Lookup the pojo persistence context-builder that is configured above<br />&#160;&#160;&#160; JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();<br />&#160;&#160;&#160; try {<br />&#160;&#160;&#160;&#160;&#160; // Deploy the process definition in the database <br />&#160;&#160;&#160;&#160;&#160; jbpmContext.deployProcessDefinition(processDefinition);</div>
		<div>&#160;&#160;&#160; } finally {<br />&#160;&#160;&#160;&#160;&#160; // Tear down the pojo persistence context.<br />&#160;&#160;&#160;&#160;&#160; // This includes flush the SQL for inserting the process definition&#160; <br />&#160;&#160;&#160;&#160;&#160; // to the database.<br />&#160;&#160;&#160; &#160;/*<br />&#160;&#160;&#160; &#160; * 关闭jbpm上下文。删除pojo持久化上下文。<br />&#160;&#160;&#160; &#160; * 这包括刷新SQL来真正的把业务处理定义插入到数据库中。<br />&#160;&#160;&#160; &#160; * */<br />&#160;&#160;&#160;&#160;&#160; jbpmContext.close();<br />&#160;&#160;&#160; }<br />&#160; }</div>
		<div>&#160; public void processInstanceIsCreatedWhenUserSubmitsWebappForm() {<br />&#160;&#160;&#160; // The code in this method could be inside a struts-action <br />&#160;&#160;&#160; // or a JSF managed bean. </div>
		<div>&#160;&#160;&#160; // Lookup the pojo persistence context-builder that is configured above<br />&#160;&#160;&#160; JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();<br />&#160;&#160;&#160; try {<br />/*<br />&#160;* 图表会话，是图表定义/业务处理定义 相关的数据库层面的会话。应该也是一个Hibernate会话。<br />&#160;* 可以从JBpm上下文这个数据库----业务处理定义、实例等 得到 业务处理定义会话。<br />&#160;* <br />&#160;* */<br />&#160;&#160;&#160;&#160;&#160; GraphSession graphSession = jbpmContext.getGraphSession();<br />&#160;&#160;&#160;&#160;&#160; //从数据库中根据业务处理定义的名字得到一个业务处理定义。<br />&#160;&#160;&#160;&#160;&#160; ProcessDefinition processDefinition = <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; graphSession.findLatestProcessDefinition("hello world");<br />&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; // With the processDefinition that we retrieved from the database, we <br />&#160;&#160;&#160;&#160;&#160; // can create an execution of the process definition just like in the <br />&#160;&#160;&#160;&#160;&#160; // hello world example (which was without persistence).<br />&#160;&#160;&#160;&#160;&#160; /*<br />&#160;&#160;&#160;&#160;&#160;&#160; * 创建业务处理定义的一个实例。<br />&#160;&#160;&#160;&#160;&#160;&#160; * <br />&#160;&#160;&#160;&#160;&#160;&#160; * */<br />&#160;&#160;&#160;&#160;&#160; ProcessInstance processInstance = <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; new ProcessInstance(processDefinition);<br />&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; Token token = processInstance.getRootToken(); <br />&#160;&#160;&#160;&#160;&#160; assertEquals("start", token.getNode().getName());<br />&#160;&#160;&#160;&#160;&#160; // Let's start the process execution<br />&#160;&#160;&#160;&#160;&#160; token.signal();<br />&#160;&#160;&#160;&#160;&#160; // Now the process is in the state 's'.<br />&#160;&#160;&#160;&#160;&#160; assertEquals("s", token.getNode().getName());<br />&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; // Now the processInstance is saved in the database.&#160; So the <br />&#160;&#160;&#160;&#160;&#160; // current state of the execution of the process is stored in the <br />&#160;&#160;&#160;&#160;&#160; // database. <br />&#160;&#160;&#160;&#160;&#160; /*<br />&#160;&#160;&#160;&#160;&#160;&#160; * 执行一步工作流程后，使用jbpmContext保存这个业务处理实例进数据库。<br />&#160;&#160;&#160;&#160;&#160;&#160; *&#160;&#160;&#160; 所以现在就把业务处理实例的执行状态也保存进了数据库。<br />&#160;&#160;&#160;&#160;&#160;&#160; *&#160; 因为，业务处理定义的实例&#160; 这个类也是一个Model类，用于管理一个业务处理定义的执行的所有信息，<br />&#160;&#160;&#160;&#160;&#160;&#160; *&#160; 是一个多例模式的Model。<br />&#160;&#160;&#160;&#160;&#160;&#160; * <br />&#160;&#160;&#160;&#160;&#160;&#160; * */<br />&#160;&#160;&#160;&#160;&#160; jbpmContext.save(processInstance);<br />&#160;&#160;&#160;&#160;&#160; // The method below will get the process instance back out <br />&#160;&#160;&#160;&#160;&#160; // of the database and resume execution by providing another <br />&#160;&#160;&#160;&#160;&#160; // external signal.</div>
		<div>&#160;&#160;&#160; } finally {<br />&#160;&#160;&#160;&#160;&#160; // Tear down the pojo persistence context.<br />&#160;&#160;&#160;&#160;&#160; jbpmContext.close();<br />&#160;&#160;&#160; }<br />&#160; }</div>
		<div>&#160; public void theProcessInstanceContinuesWhenAnAsyncMessageIsReceived() {<br />&#160;&#160;&#160; // The code in this method could be the content of a message driven bean.<br />&#160;&#160;&#160; //这个方法可能在消息驱动Bean这个远程业务代理类中。<br />&#160;&#160;&#160; // Lookup the pojo persistence context-builder that is configured above<br />&#160;&#160;&#160; JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();<br />&#160;&#160;&#160; try {</div>
		<div>&#160;&#160;&#160;&#160;&#160; GraphSession graphSession = jbpmContext.getGraphSession();<br />&#160;&#160;&#160;&#160;&#160; // First, we need to get the process instance back out of the database.<br />&#160;&#160;&#160;&#160;&#160; // There are several options to know what process instance we are dealing <br />&#160;&#160;&#160;&#160;&#160; // with here.&#160; The easiest in this simple test case is just to look for <br />&#160;&#160;&#160;&#160;&#160; // the full list of process instances.&#160; That should give us only one <br />&#160;&#160;&#160;&#160;&#160; // result.&#160; So let's look up the process definition.<br />&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; ProcessDefinition processDefinition = <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; graphSession.findLatestProcessDefinition("hello world");</div>
		<div>&#160;&#160;&#160;&#160;&#160; // Now, we search for all process instances of this process definition.<br />&#160;&#160;&#160;&#160;&#160; /*<br />&#160;&#160;&#160;&#160;&#160;&#160; * 根据业务处理定义的id得到数据库中所有的业务处理实例。这表明，数据库中应该存在2张表<br />&#160;&#160;&#160;&#160;&#160;&#160; * 它们是&#160; 一对多&#160; 的关系。<br />&#160;&#160;&#160;&#160;&#160;&#160; * <br />&#160;&#160;&#160;&#160;&#160;&#160; * */<br />&#160;&#160;&#160;&#160;&#160; List processInstances = <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; graphSession.findProcessInstances(processDefinition.getId());<br />&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; // Because we know that in the context of this unit test, there is <br />&#160;&#160;&#160;&#160;&#160; // only one execution.&#160; In real life, the processInstanceId can be <br />&#160;&#160;&#160;&#160;&#160; // extracted from the content of the message that arrived or from <br />&#160;&#160;&#160;&#160;&#160; // the user making a choice.<br />&#160;&#160;&#160;&#160;&#160; ProcessInstance processInstance = <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (ProcessInstance) processInstances.get(0);<br />&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; // Now we can continue the execution.&#160; Note that the processInstance<br />&#160;&#160;&#160;&#160;&#160; // delegates signals to the main path of execution (=the root token).<br />&#160;&#160;&#160;&#160;&#160; processInstance.signal();</div>
		<div>&#160;&#160;&#160;&#160;&#160; // After this signal, we know the process execution should have <br />&#160;&#160;&#160;&#160;&#160; // arrived in the end-state.<br />&#160;&#160;&#160;&#160;&#160; assertTrue(processInstance.hasEnded());<br />&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; // Now we can update the state of the execution in the database<br />&#160;&#160;&#160;&#160;&#160; jbpmContext.save(processInstance);</div>
		<div>&#160;&#160;&#160; } finally {<br />&#160;&#160;&#160;&#160;&#160; // Tear down the pojo persistence context.<br />&#160;&#160;&#160;&#160;&#160; jbpmContext.close();<br />&#160;&#160;&#160; }<br />&#160; }<br />}<br /></div>&#160;<br /><br /><p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1346877</p> <img src ="http://www.blogjava.net/xzclog/aggbug/76966.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzclog/" target="_blank">xzc</a> 2006-10-24 14:18 <a href="http://www.blogjava.net/xzclog/archive/2006/10/24/76966.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>