jbpm——api介绍

来源:互联网 发布:mac终端进入目录 编辑:程序博客网 时间:2024/05/18 15:29
创建一个事务,jbpm都是在一个事务中完成的

JbpmContext jbpmContext =
   JbpmConfiguration.getInstance().createJbpmContext();

----中间写点东西

jbpmContext.close();

我们其实可以在web.xml里面配置一个选项,那么我们就不用创建流程和关闭流程了
   也就是
   JbpmContext jc = JbpmConfiguration.getInstance().getCurrentJbpmContext();
   代替 :
   JbpmContext jc = JbpmConfiguration.getInstance().createJbpmContext();
  
   <servlet>
     <servlet-name>CloseJbpmConfigurationServlet</servlet-name>
     <servlet-class>org.jbpm.web.CloseJbpmConfigurationServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
   </servlet>
  
   <filter>
     <filter-name>JbpmContextFilter</filter-name>
     <filter-class>org.jbpm.web.JbpmContextFilter</filter-class>
   </filter>
   <filter-mapping>
   <filter-name>JbpmContextFilter</filter-name>
   <url-pattern>*.jsp</url-pattern>
   </filter-mapping>
  
注意:loadTaskInstance和loadProcessInstance 的工作其实可以调用
jbpmContext.loadTaskInstance(123);
jbpmContext.loadProcessInstance(123);
jbpmContext.save(processInstance);
他会去委托相应的session来完成

-----------Session--------------------------------------------------------------
Session , GraphSession , TaskMgmtSession

GraphSession graphSession = jbpmContext.getGraphSession();
Session session = jbpmContext.getSession();
其中GraphSession对于维护Jbpm的表,因为jbpm的xml对我们来说就是一个图(至少eclipse中是)
而Session是管理jbpm以外的表的

所以graphSession可以部署流程定义(其实就是save到jbpm的表里面嘛)
graphSession.deployProcessDefinition(processDefinition);//部署流程定义,如果已经存在同名的定义,则版本号会自动累加
graphSession.loadProcessDefinition(processDefinitionId);
graphSession.findLastestProcessDefinition("xxx");
graphSession.saveProcessDefinition(pd);
而session可以增删改查普通数据表
session.save(qingjiaForm);
session.load(QingjiaForm.class,Long.parseLong(id));

TaskMgmtSession tackMgmtSession = jbpmContext.getTaskMgmtSession();
这个session是用来和jbpm数据库表中的与工作相关的东西打交道的

//只能获取尚未完成的任务列表
//得到这个用户的所有taskInstance,这个userId就是assigment里面的actor-id
List list = taskMgmtSession.findTaskInstance(userId);
TaskInstance taskInstance = taskMgmtSession.loadTaskInstance(id);



---------------ProcessDefinition----------------------------------------------------------
ProcessDefinition这个对象是拥有xml信息的对象
从文件中拿到
ProcessDefinition processDefinition =
ProcessDefinition.parseXmlResource("org/ministone/training/jbpm/processdefinition.xml");
ProcessDefinition pd = 
ProcessDefinition.parseParZipInputStream(new ZipInputStream(file.getInputStream()));  
从数据库中拿到
ProcessDefinition processDefinition =
graphSession.loadProcessDefinition(processDefinitionId);
ProcessDefinition processDefinition =
graphSession.findLastestProcessDefinition("xxx");
从字符串中拿到
ProcessDefinition processDefinition =
ProcessDefinition.parseXmlString("<xxxx><xxx>xx<xxx>");

pd.getFileDefinition().getBytes(String name); //这个是从数据库中获取文件的字节流,需要传入文件的名字
Map bytesMap = pd.getFileDefinition().getBytesMap();//得到每一个文件
ZipOutputStream zipOutputStream
    = new ZipOutputStream(resp.getOutputStream());
for(Iterator it=bytesMap.keySet().iterator();it.hasNext();){
    String fname = (String)it.next();
    byte[] filebytes = fd.getBytes(fname);
    ZipEntry zipEntry = new ZipEntry(fname); //创建一个zip文件入口
    zipOutputStream.putNextEntry(zipEntry);//使得入口和outputStream相连
    zipOutputStream.write(fileBytes);
    zipOutputStream.closeEntry();
}
zipOutputStream.finish();
zipOutputStream.flush();
zipOutputStream.close();


------------------ProcessInstance---------------------------------------------------------------
ProcessInstance是根据processDefinition给new出来的,他相当于xml的动态部分,
也就是有状态的ProcessInstance

ProcessInstance processInstance =
   new ProcessInstance(processDefinition);
jbpmContext.save(processInstance); //一般是在开始加载流程的时候弄


--------------taskInstance-----------------------------------------
if(taskInstance.getStart()==null)
taskInstance.start(); //标识一个任务的执行开始:任务的开始时间被填充,看成提交申请
//taskInstance.end();//任务结束时间被填充,下一个节点的初始化,前一个任务的结束和下一个节点的开始在一个事物内,可以看成事审批申请
jbpmContext.save(taskInstance);//记住:驱动完成之后还要save


--------------------创建数据库---------------------------------------
JbpmConfiguration.getInstance().createSchema(); //创建数据库

JbpmConfiguration.getInstance().dropSchema();

pi.signal(); 与 ti.end()的区别
  
   联系: 他们都是调用了rootToken.signal()方法,
   区别: ti.end()里面有这样一段代码
   this.end = Clock.getCurrentTime(); //这个是对时间做了处理
   而我们取代办任务列表的时候List list = taskMgmtSession.findTaskInstance(userId);
   他的依据是if(end == null){获取}他不管流程的位置的

-----------------xml----------------------------------------------------
<process-definition name="qingjia" >
<start-state name="start-state1">
<transition to="fillform"></transition>
</start-state >
    <task-node name="fillform">
       <task name="fill form">
       <assignment actor-id="1"></assignment> //这种形式,那么这个工作fill form只固定这一个人来处理
       </task>
       <transition to="mgr audit"></transition>
    </task-node>
<task-node name="mgr audit">
       <task name="mgr audit">
       <assignment actor-id="2"></assignment> //这种形式,那么这个工作fill form只固定这一个人来处理
       </task>
       <transition to="end-state"></transition>
    </task-node>
    <end-state name="end-state"></end-state>
</process-definition>
  
  
流程角色 swimlane
<swimlane name="starter">
<assignment actor-id="1"/>
</swimlane>
  然后
  <task name="fill form">
       <assignment actor-id="1"></assignment> //这种形式,那么这个工作fill form只固定这一个人来处理
   </task>
   就可以变成
   <task name="fill form" swimlane="starter"> 
   </task> 
  
   用变量传递参与者id
   <task-node name="collectform">
   <task>
      <assignment class="com.zwz.UserIdAssigmentHandler" /> ---通过这个类和上一个参数来动态加载这个actor-id
      <assignment actor-id="#{userid}"/>
   </task>
   <transition name="auditfork" to="auditfork" />
   </task-node>
  
   Handler 实现
   public class UserIdAssigmentHandler implements AssignmentHandler{
       public void assign(Assignable assignable,ExecutionContext executionContext){
        // String actorid = (String)executionContext.getVariable("userid");
        String currentActorId = (String)executionContext.getProcessInstance().getContextInstance().getVariable("currentId");
        //先得到当前的id,然后再通过业务逻辑,找到相应的处理者,然后设置进去
         assignable.setActorId(this.getRealActorId(currentActorId)); //把我们需要的actor-id放进去
      
       }
   }
  
    String currentActorId = (String)executionContext.getProcessInstance().getContextInstance().getVariable("currentId");
    这一句依赖于上一个页面有:
    taskInstance.getProcessInstance().getContextInstance().setVariable("currentId","34");
   
    <task>
      <assignment actor-id="#{userid}"/>
   </task>
   这样也可以
   但是在到达这个tack前需要设置
   pi.getContextInstance().setVariable("userid",xxx);
   这样的话,assignement的执行者就会被自动赋值上
  
  
   List list = ti.getTask().getTaskNode().getLeavingTransitions();
   这个可以得到TaskNode的所有trans,因为有时候会有多个trans

-----------------------------------------------------------------------
--------------节点介绍-----------------------------------
   start-state  这个节点可以指定task 但是不能指定task里面的actor
   public TaskInstance createStartTaskInstance()
    {
        TaskInstance taskInstance = null;
        Task startTask = taskMgmtDefinition.getStartTask();
        if(startTask != null)
        {
            Token rootToken = processInstance.getRootToken();
            ExecutionContext executionContext = new ExecutionContext(rootToken);
            taskInstance = createTaskInstance(startTask, executionContext);
            taskInstance.setActorId(SecurityHelper.getAuthenticatedActorId()); //这里actorId被覆盖了
        }
        return taskInstance;
    }
    那么如何设置这个被认证过的id呢?
    jbpmContext.setActorId((String)session.getAttribute("actorId"));
    TaskInstance ti = pi.getTaskMgmtInstance().createStartTaskInstance();//这里就得到了在start里面的任务
    ti.start();
    ti.end(); //一般第一个start节点就是做些初始化准备工作,所以连续的start,end
   
    在start-state里面还可以指定swimlane,而且这个swimlane都不用写assigment,因为这个任务的执行者也是通过set进去的
    <swimlane name="starter"></swimlane> 这样就可以直接用
    <start-state name="start-state1">
       <task name="填申请单" swimlane="starter" ></task>
<transition to="fillform"></transition>
</start-state >


---------------------------------------------
jbpm.cfg.xml
<jbpm-configuration>
<string name="jbpm.files.dir" value="d:/" />  ---这个配置意思是把流程定义存到指定的目录下面而不是数据库中
</jbpm-configuration>

原创粉丝点击