首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

JBPM惯用操作

2012-12-25 
JBPM常用操作??Jbpm4常用操作文章分类:Java编程?一、流程定义?1.部署流程定义?ProcessEngine processEngine

JBPM常用操作

?

?

Jbpm4常用操作

文章分类:Java编程?

一、流程定义?

1.部署流程定义?

ProcessEngine processEngine = new Configuration().buildProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); 
?

?

例:布署文件中的流程?

//布署当前目录下pd.jpdl.xml文件?

String deploymentId = repositoryService.createDeployment() .addResourceFromClasspath("pd.jpdl.xml").deploy(); 
?

?

例:布署网页上TextArea中的流程?

<form action="jbpm?family168=deploy" method="post"> <textarea name="xml" cols=50 rows=15></textarea> <input type="submit" value="http://footman265.javaeye.com/blog/发布"/> <input type="reset" value="http://footman265.javaeye.com/blog/取消"/> </form> 
?

在后台处理如下:?

String xml = request.getParameter("xml"); repositoryService.createDeployment() .addResourceFromString("process.jpdl.xml", xml).deploy(); 
?

?

2.删除流程定义?

类ProcessDefinition 包含如下属性:?

ID:流程定义ID号?

DeploymentId:流程定义的布署ID号?

Key:关键字?

name:流程名?

version:版本号?

?

数据如下?

ID Key 名称 版本?

hello-1 hello hello 1?

?

//获取类ProcessDefinition的属性ID?

String id = request.getParameter("id");?

//根据流程ID获取流程定义实例?

ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()?

.processDefinitionId(id).uniqueResult();?

//根据流程定义的布署ID号,删除该流程定义?

//注意:jbpm4是不允许直接根据流程定义的ID来直接删除流程定义的,因为还要删除其它配置数据?

repositoryService.deleteDeploymentCascade(pd.getDeploymentId());?

?

3.获取全部流程定义?

根据流程名获取所有流程定义?

List<ProcessDefinition> processDefinitions = repositoryService?

.createProcessDefinitionQuery().orderAsc( ProcessDefinitionQuery.PROPERTY_NAME).list();?

?

还可以根据以下顺序进行排序(org.jbpm.api.ProcessDefinitionQuery)?

public static final java.lang.String PROPERTY_DEPLOYMENT_TIMESTAMP "deployment.timestamp"?

public static final java.lang.String PROPERTY_ID "idProperty.stringValue"?

public static final java.lang.String PROPERTY_KEY "keyProperty.stringValue"?

public static final java.lang.String PROPERTY_NAME "idProperty.objectName"?

public static final java.lang.String PROPERTY_VERSION "versionProperty.longValue"?

?

二、流程实例?

?

1.启动一个流程实例?

1.1根据key启动流程实例?

用户必须为新启动的流程实例分配一个key, 这个key是用户执行的时候定义的且唯一。通常在业务流程领域找到这种key。 比如,一个订单id或者一个保险单号。?

ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", "CL92837");?

?

key可以用来创建流程实例的id, 格式为{process-key}.{execution-id}。 所以上面的代码会创建一个id为 ICL.CL92837的流向 (execution)。?

?

1.2根据数据库主键启动流程实例?

如果没有提供用户定义的key,数据库就会把主键作为key。 这样可以使用如下方式获得id:?

ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL");?

String pid = processInstance.getId();?

最好使用一个用户定义的key。提供给一个用户定义的key, 你可以组合流向的id,而不是执行一个基于流程变量的搜索 - 那种方式太消耗资源了。?

?

1.3根据变量启动流程实例?

为一个新的流程实例启动时就提供一组对象参数。 将这些参数放在variables变量里, 然后可以在流程实例创建和启动时使用。?

Map<String,Object> variables = new HashMap<String,Object>();?

variables.put("customer", "John Doe");?

variables.put("type", "Accident");?

variables.put("amount", new Float(763.74));?

ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", variables);?

?

参见流程定义4-1,把order作为一个流程变量分配给它,启动新流程实例代码如下:?

Map<String, Object> variables = new HashMap<String, Object>();?

variables.put("order", new Order("johndoe"));?

ProcessInstance processInstance = executionService.startProcessInstanceByKey("TaskAssignee", variables);?

?

?

?

?

2.根据流程定义,查看流程实例?

根据类ProcessDefinition的属性ID,查看该流程的所有实例?

String pdId = request.getParameter("id");?

return executionService.createProcessInstanceQuery()?

.processDefinitionId(pdId).list();?

?

3.执行实例?

根据类ProcessInstance的属性ID,执行流程实例?

String pid = request.getParameter("pid");?

executionService.signalExecutionById(pid);?

?

四.任务?

假设流程定义4-1如下:?

<process name="TaskAssignee">?

<start>?

<transition to="review" />?

</start>?

<task name="review" assignee="#{order.owner}">?

<transition to="work" />?

</task>?

<task name="review" assignee="johndoe">?

<transition to="wait" />?

</task>?

<state name="wait"/>?

</process>?

?

assignee="johndoe"?

表示任务会被分配给用户ID为"johndoe"的人。?

assignee="#{order.owner}"?

任务被分配给#{order.owner}。表示通过Order对的getOwner()方法会用来获得用户id,该用户负责完成这个任务。?

public class Order implements Serializable {?

String owner; public Order(String owner) {?

this.owner = owner;?

}?

public String getOwner() {?

return owner;?

}?

public void setOwner(String owner) {?

this.owner = owner;?

}?

}?

?

1.获取任务列表?

1.1根据用户ID获取任务列表?

List<Task> taskList = taskService.findPersonalTasks("johndoe");?

?

1.2根据任务候选人或候选组获取任务列表?

任务可能被分配给一组用户。 其中的一个用户应该接受这个任务并完成它。?

candidate-groups:一个使用逗号分隔的组id列表。 所有组内的用户将会成为这个任务的候选人。?

candidate-users:一个使用逗号分隔的用户id列表。 所有的用户将会成为这个任务的候选人。?

例如:?

<task name="review" candidate-groups="sales-dept">?

<transition to="wait" />?

</task>?

假设:sales-dept有两个成员:johndoe和joesmoe?

?

这个任务被创建时,不显示在任何人的个人任务列表中。 下面的任务列表会是空的。?

taskService.getAssignedTasks("johndoe");?

taskService.getAssignedTasks("joesmoe");?

?

分组任务列表中,用户接口必须只接受对这些任务的“接受”操作。?

taskService.takeTask(task.getDbid(), "johndoe");?

当一个用户接受了一个任务,这个任务的分配人就会变成当前用户。任务会从所有候选人的分组任务列表中消失,它会出现在用户的已分配列表中。?

?

1.3在一个列表中显示该某人的所有任务?

包括他的个人任务,候选任务,这时直接用jbpm4提供的api完成不了该功能要求。于是可以使用以下方式进行扩展:?

/**?

* 取得用户的对应的任务列表?

* @param userId?

* @return?

*/?

public List<TaskImpl> getTasksByUserId(String userId){?

AppUser user=(AppUser)getHibernateTemplate().load(AppUser.class, new Long(userId));?

Iterator<AppRole> rolesIt=user.getRoles().iterator();?

StringBuffer groupIds=new StringBuffer();?

int i=0;?

while(rolesIt.hasNext()){?

if(i>0)groupIds.append(",");?

groupIds.append("'"+rolesIt.next().getRoleId().toString()+"'");?

}?

/**?

* select * from `jbpm4_task` task?

left join jbpm4_participation pt on task.`DBID_`=pt.`TASK_`?

where task.`ASSIGNEE_`='1' or ( pt.`TYPE_` = 'candidate' and (pt.`USERID_`='1')?

or pt.`GROUPID_`in ('1'))?

*/?

StringBuffer hqlSb=new StringBuffer();?

hqlSb.append("select task from org.jbpm.pvm.internal.task.TaskImpl task left join task.participations pt where task.assignee=?");?

hqlSb.append(" or (pt.type = 'candidate' and ((pt.userId=?)");?

?

if(user.getRoles().size()>0){?

hqlSb.append(" or (pt.groupId in ("+groupIds.toString()+"))");?

}?

hqlSb.append("))");?

hqlSb.append(" order by task.priority desc");?

?

return findByHql(hqlSb.toString(), new Object[]{userId,userId});?

?

}?

?

2分配任务?

如果在流程定义文件中将任务指定到了个人,则jbpm自动分配给个人。否则需要进行指定?

2.1给用户组的用户分配任务?

流程定义文件:?

<task name="review" candidate-groups="sales-dept">?

<transition to="wait" />?

</task>?

假设:sales-dept有两个成员:johndoe和joesmoe?

?

分组任务列表中,用户接口必须只接受对这些任务的“接受”操作。?

taskService.takeTask(task.getDbid(), "johndoe");?

当一个用户接受了一个任务,这个任务的分配人就会变成当前用户。任务会从所有候选人的分组任务列表中消失,它会出现在用户的已分配列表中。?

?

2.2任务分配处理器分配任务?

一个AssignmentHandler可以通过编程方式来计算 一个任务的分配人和候选人。?

public interface AssignmentHandler extends Serializable {?

void assign(Assignable assignable, OpenExecution execution) throws Exception;?

}?

Assignable是任务和泳道的通用接口。 所以任务分配处理器可以使用在任务, 也可以用在泳道中。?

?

包含任务分配处理器的流程定义4-2如下:?

<process name="TaskAssignmentHandler" xmlns="http://jbpm.org/4.2/jpdl">?

<start g="20,20,48,48">?

<transition to="review" />?

</start>?

<task name="review" g="96,16,127,52">?

<assignment-handler />?

</field>?

</assignment-handler>?

<transition to="wait" />?

</task>?

<state name="wait" g="255,16,88,52" />?

</process>?

?

类AssignTask代码如下:?

public class AssignTask implements AssignmentHandler {?

String assignee;?

public void assign(Assignable assignable, OpenExecution execution) {?

assignable.setAssignee(assignee);?

}?

}?

请注意,默认AssignmentHandler实现可以使用使用流程变量,任何其他Java API可以访问资源,像你的应用数据库来计算分配人和候选人用户和组。?

启动一个TaskAssignmentHandler的新流程实例,会立即让新流程实例运行到任务节点。 一个新review任务被创建,在这个时候 AssignTask的分配处理器被调用。这将设置johndoe为分配人。 所以John Doe将在他自己的任务列表中找到这个任务。?

?

2.3给泳道分配任务?

任务泳道如下面的流程文件4-3:?

<process name="TaskSwimlane" xmlns="http://jbpm.org/4.2/jpdl">?

<swimlane name="sales representative" candidate-groups="sales-dept" />?

<start>?

<transition to="enter order data" />?

</start>?

<task name="enter order data" swimlane="sales representative">?

<transition to="calculate quote"/>?

</task>?

<task name="calculate quote" swimlane="sales representative">?

</task>?

</process>?

?

在这个例子中,我们在身份组件中 创建了下面的信息:?

identityService.createGroup("sales-dept");?

identityService.createUser("johndoe", "johndoe", "John", "Doe");?

identityService.createMembership("johndoe", "sales-dept");?

?

在启动一个新流程实例后,用户johndoe将成为 enter order data的一个候选人。还是像上一个流程候选人例子一样, John Doe可以像这样接收任务:?

taskService.takeTask(task.getDbid(), "johndoe");?

?

接收这个任务将让johndoe成为任务的负责人。 直到任务与泳道sales representative关联, 分配人johndoe也会关联到泳道中作为负责人。接下来,John Doe可以像下面这样完成任务:?

taskService.completeTask(taskDbid);?

?

完成任务会将流程执行到下一个任务, 下一个任务是calculate quote。 这个任务也关联着泳道。因此, 任务会分配给johndoe。

热点排行