??xml version="1.0" encoding="utf-8" standalone="yes"?>在线免费国产视频,亚洲国产精品久久人人爱蜜臀 ,免费观看在线综合色http://www.aygfsteel.com/xzclog/category/32017.htmlzh-cnSat, 07 Jun 2008 07:15:01 GMTSat, 07 Jun 2008 07:15:01 GMT60向应用程序中加入jBPMlg http://www.aygfsteel.com/xzclog/archive/2006/10/24/76966.htmlxzcxzcTue, 24 Oct 2006 06:18:00 GMThttp://www.aygfsteel.com/xzclog/archive/2006/10/24/76966.htmlhttp://www.aygfsteel.com/xzclog/comments/76966.htmlhttp://www.aygfsteel.com/xzclog/archive/2006/10/24/76966.html#Feedback0http://www.aygfsteel.com/xzclog/comments/commentRss/76966.htmlhttp://www.aygfsteel.com/xzclog/services/trackbacks/76966.html本文介绍怎样把jBPMlgd到Web应用E序中。所需要用到的资源Q可以在jbpm-starters-kit-3.1.2中找到?/div>
一、首先安装jBPM数据库。jBPM是一个停止状态的lgQ需要数据库表持久化保存Q?Q业务程序定义和业务E序实例及相关的工作数据。保障工作流引擎的执行?Q异步系l用数据库表来模拟消息pȝ的功能。需要把消息到数据库表中Q由消息pȝ的命令执行器异步查询和执行。不像专业的消息pȝ那样是远E的。它仅仅使用数据库模拟消息系l?/div>
1Q打开MySQL的命令执行工具Query Browser?/div>
2Q当前选定应用E序的数据库Q如wcms?/div>
3Q导入脚本文Ӟmysql.drop.create.sql
4Q执行该脚本。会在当前数据库中增加jBPM的数据库表?/div>
 
二、导入jBPM所需?jar文g
1Qjbpmlib目录中包含了jBPM所需的全部jar包。包括MySQL的jdbc包?/div>
2Q把它整个复制到应用E序的lib目录下?/div>
3Q应用程序的构徏器\径的“?#8221;中,把这些jar都加q来?/div>
q些classpath下的jar包,都会被该Web应用E序的类载入器蝲入?/div>
 
三、创建config.files和processes目录Qƈ加入classpath的源代码路径
Q一Qconfig.files目录的功?/div>
    q个目录存放jBPM的各c配|文件。放在这里(是classpath层Q的配置文g会取代jBPM的jar包中各处的配|文件?/div>
q里Q由于需要用mysqlQ而不是内|的hsql内存数据库。所以我们提供了一个修改过的配|文Ӟhibernate.cfg.xml。这里提供了Hibernate3的配|?/div>
hibernate.cfg.xml配置文g的部分内?/div>
<hibernate-configuration>
  <session-factory>
    <!-- jdbc connection properties
原来的HSQL配置被注释掉Q用MySQL数据库的配置
  <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
    <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
    <property name="hibernate.connection.url">jdbc:hsqldb:mem:.;sql.enforce_strict_size=true</property>
    <property name="hibernate.connection.username">sa</property>
    <property name="hibernate.connection.password"></property>
          -->
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/wcms</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</property>
Q二Qprocesses目录的功?/div>
q个目录存放process程定义。如QmanageNews\内有3个文件?/div>
在jBPM应用E序导入.par?xml文g?使用相对路径Q如QwithubCMS/processdefinition.xmlQ来定位业务E序定义资源文g?/div>
 
怎样把它们放到classpath下,需要根据不同的环境q行不同的处理?/div>
一、一般JavaE序
    1Q创建config.files和processes目录?/div>
2Q配|构建器路径Q将q?个目录设为到classpath的源代码路径?/div>
q样Q运行时Q会把它们中的内容复制到classpath目录下?/div>
二、Eclipse下的WebE序
我们使用Eclipse自带的功能发布WebE序?/div>
    1Q创建config.files和processes目录?/div>
2Q配|构建器路径Q将q?个目录设为到classpath的源代码路径?/div>
3Q配|classpath,也就?#8220;~省输出文g?#8221;QؓQ?/div>
内容理Q应用程序根路径名)/webapps/WEB-INF/classes
4Q这P在Eclipse~译Ӟ默认是保存即~译Q,把这2个文件夹中的内容复制到classpath下?/div>
5Q然后,使用Eclipse自带的功能,发布该Web应用E序?/div>
Eclipse会把/webapps/文g夹下的所有内容复制到Web服务器下Qƈ且把webapps改名Web应用E序的Eclipse目名字?/div>
q样Q我们的配置Q对于classpath来说也是正确的!Web应用E序可以利地运行?/div>
三、Ant发布的WebE序
可以和上面一栗把q些classpath的源文gQ编译,然后把内部的内容复制到classpath下?/div>
Web目q行时的classpath是classes和lib。当然也需要把jar包都复制到l(f)ib下?/div>
 
最后,在内容管理\webapps\WEB-INF\jbpm\下放|那2个目录。ƈ把它们设为classpath的源路径?/div>
目标classpath路径是内容管理\webapps\WEB-INF\classes?/div>
 
 
四、测试jBPM和数据库
建立test源文件夹。提供一个junit试c?org.jbpm.test.db.HelloWorldDbTest?/span>
q个cM用字W串定义了一个简单的业务E序Q然后在数据库上完整的执行它?/div>
执行该单元测试。在应用E序的数据库中的2个表Q?/div>
SELECT * FROM jbpm_processdefinition j;
SELECT * FROM jbpm_processinstance j;
应该有数据?/div>
 
    xQjBPMlg成功地加入到Web应用E序中了Q?/div>
附录QHelloWorldDbTest.java源代?/div>
package org.jbpm.test.db;
import java.util.List;
import junit.framework.TestCase;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.db.GraphSession;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
public class HelloWorldDbTest extends TestCase {
 
  static JbpmConfiguration jbpmConfiguration = null;
  static {
    // An example configuration file such as this can be found in
    // 'src/config.files'.  Typically the configuration information is in the
    // resource file 'jbpm.cfg.xml', but here we pass in the configuration
    // information as an XML string.
   
    // First we create a JbpmConfiguration statically.  One JbpmConfiguration
    // can be used for all threads in the system, that is why we can safely
    // make it static.
   /**
    *单例对象?br />    *JbpmConfiguration能够被系l中所有线E所使用?br />    *jbpm.cfg.xmlq个命名方式和Hibernate配置文g的命名方式一致?br />    *
    */
    jbpmConfiguration = JbpmConfiguration.parseXmlString(
      "<jbpm-configuration>" +
     
      // A jbpm-context mechanism separates the jbpm core
      // engine from the services that jbpm uses from
      // the environment.
      /*jbpm-context机制在环境中把jbpm核心引擎和jbpm使用的服务分开?br />       * 持久化服务是jbpm核心引擎使用的一个服务?br />       *
       * */
     
      "  <jbpm-context>" +
      "    <service name='persistence' " +
      "             factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />" +
      "  </jbpm-context>" +
     
      // Also all the resource files that are used by jbpm are
      // referenced from the jbpm.cfg.xml
      /*
       *stringQ配|了所有jbpm使用的资源文件的路径?br />       * */
     
      "  <string name='resource.hibernate.cfg.xml' " +
      "          value='hibernate.cfg.xml' />" +
      "  <string name='resource.business.calendar' " +
      "          value='org/jbpm/calendar/jbpm.business.calendar.properties' />" +
      "  <string name='resource.default.modules' " +
      "          value='org/jbpm/graph/def/jbpm.default.modules.properties' />" +
      "  <string name='resource.converter' " +
      "          value='org/jbpm/db/hibernate/jbpm.converter.properties' />" +
      "  <string name='resource.action.types' " +
      "          value='org/jbpm/graph/action/action.types.xml' />" +
      "  <string name='resource.node.types' " +
      "          value='org/jbpm/graph/node/node.types.xml' />" +
      "  <string name='resource.varmapping' " +
      "          value='org/jbpm/context/exe/jbpm.varmapping.xml' />" +
      "</jbpm-configuration>"
    );
  }
 
  public void setUp() {
   //创徏数据库表
    //jbpmConfiguration.createSchema();
  }
 
  public void tearDown() {
   //删除数据库表
    //jbpmConfiguration.dropSchema();
  }
  public void testSimplePersistence() {
    // Between the 3 method calls below, all data is passed via the
    // database.  Here, in this unit test, these 3 methods are executed
    // right after each other because we want to test a complete process
    // scenario情节.  But in reality, these methods represent different
    // requests to a server.
   
    // Since we start with a clean, empty in-memory database, we have to
    // deploy the process first.  In reality, this is done once by the
    // process developer.
   /**
    *  q个Ҏ(gu)把业务处理定义通过Hibernate保存到数据库中?br />    */
    deployProcessDefinition();
    // Suppose we want to start a process instance (=process execution)
    // when a user submits a form in a web application...
    /*假设当一个用h交一个表单时Q我们要开始一个业务处理的实例/执行?br />     * q可以在Action中执行处理?br />     */
    processInstanceIsCreatedWhenUserSubmitsWebappForm();
    // Then, later, upon the arrival of an asynchronous message the
    // execution must continue.
    /*
     * 然后Q直到异步消息来刎ͼ才l执行业务处理实例的余下的工作流E?br />     * */
    theProcessInstanceContinuesWhenAnAsyncMessageIsReceived();
  }
  public void deployProcessDefinition() {
    // This test shows a process definition and one execution
    // of the process definition.  The process definition has
    // 3 nodes: an unnamed start-state, a state 's' and an
    // end-state named 'end'.
   /*
    * q个Ҏ(gu)把业务处理定义通过Hibernate保存到数据库中?br />    *
    * */
    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
      "<process-definition name='hello world'>" +
      "  <start-state name='start'>" +
      "    <transition to='s' />" +
      "  </start-state>" +
      "  <state name='s'>" +
      "    <transition to='end' />" +
      "  </state>" +
      "  <end-state name='end' />" +
      "</process-definition>"
    );
    // Lookup the pojo persistence context-builder that is configured above
    JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
    try {
      // Deploy the process definition in the database
      jbpmContext.deployProcessDefinition(processDefinition);
    } finally {
      // Tear down the pojo persistence context.
      // This includes flush the SQL for inserting the process definition 
      // to the database.
     /*
      * 关闭jbpm上下文。删除pojo持久化上下文?br />      * q包括刷新SQL来真正的把业务处理定义插入到数据库中?br />      * */
      jbpmContext.close();
    }
  }
  public void processInstanceIsCreatedWhenUserSubmitsWebappForm() {
    // The code in this method could be inside a struts-action
    // or a JSF managed bean.
    // Lookup the pojo persistence context-builder that is configured above
    JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
    try {
/*
 * 图表会话Q是图表定义/业务处理定义 相关的数据库层面的会话。应该也是一个Hibernate会话?br /> * 可以从JBpm上下文这个数据库----业务处理定义、实例等 得到 业务处理定义会话?br /> *
 * */
      GraphSession graphSession = jbpmContext.getGraphSession();
      //从数据库中根据业务处理定义的名字得到一个业务处理定义?br />      ProcessDefinition processDefinition =
          graphSession.findLatestProcessDefinition("hello world");
   
      // With the processDefinition that we retrieved from the database, we
      // can create an execution of the process definition just like in the
      // hello world example (which was without persistence).
      /*
       * 创徏业务处理定义的一个实例?br />       *
       * */
      ProcessInstance processInstance =
          new ProcessInstance(processDefinition);
     
      Token token = processInstance.getRootToken();
      assertEquals("start", token.getNode().getName());
      // Let's start the process execution
      token.signal();
      // Now the process is in the state 's'.
      assertEquals("s", token.getNode().getName());
     
      // Now the processInstance is saved in the database.  So the
      // current state of the execution of the process is stored in the
      // database.
      /*
       * 执行一步工作流E后Q用jbpmContext保存q个业务处理实例q数据库?br />       *    所以现在就把业务处理实例的执行状态也保存q了数据库?br />       *  因ؓQ业务处理定义的实例  q个cM是一个Modelc,用于理一个业务处理定义的执行的所有信息,
       *  是一个多例模式的Model?br />       *
       * */
      jbpmContext.save(processInstance);
      // The method below will get the process instance back out
      // of the database and resume execution by providing another
      // external signal.
    } finally {
      // Tear down the pojo persistence context.
      jbpmContext.close();
    }
  }
  public void theProcessInstanceContinuesWhenAnAsyncMessageIsReceived() {
    // The code in this method could be the content of a message driven bean.
    //q个Ҏ(gu)可能在消息驱动Beanq个q程业务代理cM?br />    // Lookup the pojo persistence context-builder that is configured above
    JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
    try {
      GraphSession graphSession = jbpmContext.getGraphSession();
      // First, we need to get the process instance back out of the database.
      // There are several options to know what process instance we are dealing
      // with here.  The easiest in this simple test case is just to look for
      // the full list of process instances.  That should give us only one
      // result.  So let's look up the process definition.
     
      ProcessDefinition processDefinition =
          graphSession.findLatestProcessDefinition("hello world");
      // Now, we search for all process instances of this process definition.
      /*
       * Ҏ(gu)业务处理定义的id得到数据库中所有的业务处理实例。这表明Q数据库中应该存?张表
       * 它们?#160; 一对多  的关pR?br />       *
       * */
      List processInstances =
          graphSession.findProcessInstances(processDefinition.getId());
     
      // Because we know that in the context of this unit test, there is
      // only one execution.  In real life, the processInstanceId can be
      // extracted from the content of the message that arrived or from
      // the user making a choice.
      ProcessInstance processInstance =
          (ProcessInstance) processInstances.get(0);
     
      // Now we can continue the execution.  Note that the processInstance
      // delegates signals to the main path of execution (=the root token).
      processInstance.signal();
      // After this signal, we know the process execution should have
      // arrived in the end-state.
      assertTrue(processInstance.hasEnded());
     
      // Now we can update the state of the execution in the database
      jbpmContext.save(processInstance);
    } finally {
      // Tear down the pojo persistence context.
      jbpmContext.close();
    }
  }
}
 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1346877



xzc 2006-10-24 14:18 发表评论
]]> վ֩ģ壺 | ٲ| Ӵ| ޭ| | | ̩| | | | ˳| ƫ| ͼ| | | ½| ½| ׯ| | ʯ| ũ| | ʯ| | | ڰ| | ̫| Ǩ| Ϫ| | | | Ȫ| Դ| | ͭ| ɽ| ذ| | |