Activiti源码跟踪之Task表单操作GetTaskFormCmd
2017-11-17 17:00
344 查看
在Activiti中总共有三种表单,动态表单,普通表单和外置表单。本文介绍的是动态表单。
一、FormProperty
Task可以配置属性值,比如有一个审核的任务,对应的流程定义XML代码如下:
其中activiti:formProperty用来定义Task的属性:
支持的表单属性有以下几种:
二、如何去获取在流程定义中定义的表单内容?
TaskFormDataImpl taskFormData = (TaskFormDataImpl) formService.getTaskFormData(taskId);
GetTaskFormCmd的execute方法:
public TaskFormData execute(CommandContext commandContext) {
TaskEntity task = commandContext
.getTaskEntityManager()
.findTaskById(taskId);
if (task == null) {
throw new ActivitiObjectNotFoundException("No task found for taskId '" + taskId +"'", Task.class);
}
if(task.getTaskDefinition() != null) {
TaskFormHandler taskFormHandler = task.getTaskDefinition().getTaskFormHandler();
if (taskFormHandler == null) {
throw new ActivitiException("No taskFormHandler specified for task '" + taskId +"'");
}
return taskFormHandler.createTaskForm(task);
} else {
// Standalone task, no TaskFormData available
return null;
}
}
核心代码再第9行task.getTaskDefinition()获取Task属性
public TaskDefinition getTaskDefinition() {
if (taskDefinition==null && taskDefinitionKey!=null) {
ProcessDefinitionEntity processDefinition = Context
.getProcessEngineConfiguration()
.getDeploymentManager()
.findDeployedProcessDefinitionById(processDefinitionId);
taskDefinition = processDefinition.getTaskDefinitions().get(taskDefinitionKey);
}
return taskDefinition;
}
第6行代码findDeployedProcessDefinitionById,根据processDefinitionId查询流程定义:
public ProcessDefinitionEntity findDeployedProcessDefinitionById(String processDefinitionId) {
if (processDefinitionId == null) {
throw new ActivitiIllegalArgumentException("Invalid process definition id : null");
}
// first try the cache
ProcessDefinitionEntity processDefinition = processDefinitionCache.get(processDefinitionId);
if (processDefinition == null) {
processDefinition = Context.getCommandContext()
.getProcessDefinitionEntityManager()
.findProcessDefinitionById(processDefinitionId);
if (processDefinition == null) {
throw new ActivitiObjectNotFoundException("no deployed process definition found with id '" + processDefinitionId + "'", ProcessDefinition.class);
}
processDefinition = resolveProcessDefinition(processDefinition);
}
return processDefinition;
}
第7行代码变量processDefinitionCache是一个DeploymentCache实例对象,在这里引申一下。
当初始化流程引擎的时候,会执行下面的方法
org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl
buildProcessEngine()--->init()--->initDeployers(),这时候processDefinitionCache会被初始化。那么processDefinitionCache什么时候赋值的呢?processDefinitionCache属于DeploymentCache对象,可以看出应该是在流程部署的时候进行赋值的。可以参考:Activiti源码跟踪之流程部署
接着往下看--》resolveProcessDefinition方法
public ProcessDefinitionEntity resolveProcessDefinition(ProcessDefinitionEntity processDefinition) {
String processDefinitionId = processDefinition.getId();
String deploymentId = processDefinition.getDeploymentId();
processDefinition = processDefinitionCache.get(processDefinitionId);
if (processDefinition==null) {
DeploymentEntity deployment = Context
.getCommandContext()
.getDeploymentEntityManager()
.findDeploymentById(deploymentId);
deployment.setNew(false);
deploy(deployment, null);
processDefinition = processDefinitionCache.get(processDefinitionId);
if (processDefinition==null) {
throw new ActivitiException("deployment '"+deploymentId+"' didn't put process definition '"+processDefinitionId+"' in the cache");
}
}
return processDefinition;
}
如果processDefinitionCache没有流程定义的话,重新部署流程:
deployment.setNew(false);
deploy(deployment, null);
因为部署会把流程定义放在缓存中,所以这个时候再去processDefinitionCache查询流程定义。
根据taskDefinitionKey就可以获取到TaskDefinition
三、如何解析TaskDefinition()
再看下GetTaskFormCmd的execute方法
TaskFormHandler taskFormHandler = task.getTaskDefinition().getTaskFormHandler();
taskFormHandler.createTaskForm(task);
DefaultTaskFormHandler.createTaskForm--->DefaultFormHandler.initializeFormProperties(taskFormData, task.getExecution())。循环DefaultFormHandler的formPropertyHandlers获取到FormProperty。
四:扩展:如何根据ProcessDefinitionId和TaskDefinitionKey获取到表单属性
1、根据processDefinitionId查询流程定义
ProcessDefinitionEntity processDefinition = Context.getProcessEngineConfiguration().getDeploymentManager()
.findDeployedProcessDefinitionById(processDefinitionId);
2、根据TaskDefinitionKey获取Task定义
TaskDefinition taskDefinition = processDefinition.getTaskDefinitions().get(taskDefinitionKey);
3、获取Task表单属性
因为DefaultTaskFormHandler有FormPropertyHandlers属性,所以可以直接从DefaultTaskFormHandler获取FormPropertyHandlers
DefaultTaskFormHandler taskFormHandler = (DefaultTaskFormHandler) taskDefinition.getTaskFormHandler();
然后获取表单属性:
FormService.getTaskFormCmd:查询Task表单。通过源码跟踪,查看如何获取Task表单
一、FormProperty
Task可以配置属性值,比如有一个审核的任务,对应的流程定义XML代码如下:
<userTask id="audit" name="审核"> <extensionElements> <activiti:formProperty id="vendorCode" name="供应商" type="string" expression="1" variable="1" readable="false" required="true"/> <activiti:formProperty id="date" name="时间" type="date" datePattern="MM-dd-yyyy hh:mm"/> <activiti:formProperty id="amount" name="总数" type="long" writable="false" required="true"/> <activiti:formProperty id="is_vip" name="是否会员" type="boolean" writable="false"/> <activiti:formProperty id="approved" name="是否通过" type="enum" required="true"> <activiti:value id="1" name="通过"/> <activiti:value id="2" name="驳回"/> </activiti:formProperty> </extensionElements> </userTask>
其中activiti:formProperty用来定义Task的属性:
public interface FormP 4000 roperty extends Serializable { /** The key used to submit the property in {@link FormService#submitStartFormData(String, java.util.Map)} * or {@link FormService#submitTaskFormData(String, java.util.Map)} */ String getId(); /** The display label */ String getName(); /** Type of the property. */ FormType getType(); /** Optional value that should be used to display in this property */ String getValue(); /** Is this property read to be displayed in the form and made accessible with the methods * {@link FormService#getStartFormData(String)} and {@link FormService#getTaskFormData(String)}. */ boolean isReadable(); /** Is this property expected when a user submits the form? */ boolean isWritable(); /** Is this property a required input field */ boolean isRequired(); }
支持的表单属性有以下几种:
string(org.activiti.engine.impl.form.StringFormType)
long(org.activiti.engine.impl.form.LongFormType)
enum(org.activiti.engine.impl.form.EnumFormType)
date(org.activiti.engine.impl.form.DateFormType)
boolean(org.activiti.engine.impl.form.BooleanFormType)
二、如何去获取在流程定义中定义的表单内容?
TaskFormDataImpl taskFormData = (TaskFormDataImpl) formService.getTaskFormData(taskId);
GetTaskFormCmd的execute方法:
public TaskFormData execute(CommandContext commandContext) {
TaskEntity task = commandContext
.getTaskEntityManager()
.findTaskById(taskId);
if (task == null) {
throw new ActivitiObjectNotFoundException("No task found for taskId '" + taskId +"'", Task.class);
}
if(task.getTaskDefinition() != null) {
TaskFormHandler taskFormHandler = task.getTaskDefinition().getTaskFormHandler();
if (taskFormHandler == null) {
throw new ActivitiException("No taskFormHandler specified for task '" + taskId +"'");
}
return taskFormHandler.createTaskForm(task);
} else {
// Standalone task, no TaskFormData available
return null;
}
}
核心代码再第9行task.getTaskDefinition()获取Task属性
public TaskDefinition getTaskDefinition() {
if (taskDefinition==null && taskDefinitionKey!=null) {
ProcessDefinitionEntity processDefinition = Context
.getProcessEngineConfiguration()
.getDeploymentManager()
.findDeployedProcessDefinitionById(processDefinitionId);
taskDefinition = processDefinition.getTaskDefinitions().get(taskDefinitionKey);
}
return taskDefinition;
}
第6行代码findDeployedProcessDefinitionById,根据processDefinitionId查询流程定义:
public ProcessDefinitionEntity findDeployedProcessDefinitionById(String processDefinitionId) {
if (processDefinitionId == null) {
throw new ActivitiIllegalArgumentException("Invalid process definition id : null");
}
// first try the cache
ProcessDefinitionEntity processDefinition = processDefinitionCache.get(processDefinitionId);
if (processDefinition == null) {
processDefinition = Context.getCommandContext()
.getProcessDefinitionEntityManager()
.findProcessDefinitionById(processDefinitionId);
if (processDefinition == null) {
throw new ActivitiObjectNotFoundException("no deployed process definition found with id '" + processDefinitionId + "'", ProcessDefinition.class);
}
processDefinition = resolveProcessDefinition(processDefinition);
}
return processDefinition;
}
第7行代码变量processDefinitionCache是一个DeploymentCache实例对象,在这里引申一下。
当初始化流程引擎的时候,会执行下面的方法
org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl
buildProcessEngine()--->init()--->initDeployers(),这时候processDefinitionCache会被初始化。那么processDefinitionCache什么时候赋值的呢?processDefinitionCache属于DeploymentCache对象,可以看出应该是在流程部署的时候进行赋值的。可以参考:Activiti源码跟踪之流程部署
接着往下看--》resolveProcessDefinition方法
public ProcessDefinitionEntity resolveProcessDefinition(ProcessDefinitionEntity processDefinition) {
String processDefinitionId = processDefinition.getId();
String deploymentId = processDefinition.getDeploymentId();
processDefinition = processDefinitionCache.get(processDefinitionId);
if (processDefinition==null) {
DeploymentEntity deployment = Context
.getCommandContext()
.getDeploymentEntityManager()
.findDeploymentById(deploymentId);
deployment.setNew(false);
deploy(deployment, null);
processDefinition = processDefinitionCache.get(processDefinitionId);
if (processDefinition==null) {
throw new ActivitiException("deployment '"+deploymentId+"' didn't put process definition '"+processDefinitionId+"' in the cache");
}
}
return processDefinition;
}
如果processDefinitionCache没有流程定义的话,重新部署流程:
deployment.setNew(false);
deploy(deployment, null);
因为部署会把流程定义放在缓存中,所以这个时候再去processDefinitionCache查询流程定义。
根据taskDefinitionKey就可以获取到TaskDefinition
三、如何解析TaskDefinition()
再看下GetTaskFormCmd的execute方法
TaskFormHandler taskFormHandler = task.getTaskDefinition().getTaskFormHandler();
taskFormHandler.createTaskForm(task);
DefaultTaskFormHandler.createTaskForm--->DefaultFormHandler.initializeFormProperties(taskFormData, task.getExecution())。循环DefaultFormHandler的formPropertyHandlers获取到FormProperty。
四:扩展:如何根据ProcessDefinitionId和TaskDefinitionKey获取到表单属性
1、根据processDefinitionId查询流程定义
ProcessDefinitionEntity processDefinition = Context.getProcessEngineConfiguration().getDeploymentManager()
.findDeployedProcessDefinitionById(processDefinitionId);
2、根据TaskDefinitionKey获取Task定义
TaskDefinition taskDefinition = processDefinition.getTaskDefinitions().get(taskDefinitionKey);
3、获取Task表单属性
因为DefaultTaskFormHandler有FormPropertyHandlers属性,所以可以直接从DefaultTaskFormHandler获取FormPropertyHandlers
DefaultTaskFormHandler taskFormHandler = (DefaultTaskFormHandler) taskDefinition.getTaskFormHandler();
public class FormPropertyHandler implements Serializable { private static final long serialVersionUID = 1L; protected String id; protected String name; protected AbstractFormType type; protected boolean isReadable; protected boolean isWritable; protected boolean isRequired; protected String variableName; protected Expression variableExpression; protected Expression defaultExpression; ...... }
然后获取表单属性:
formPropertyHandler.getId(); formPropertyHandler.getName(); formPropertyHandler.getType().getName()
相关文章推荐
- MVVM架构~knockoutjs系列之表单添加(验证)与列表操作源码开放
- 用PHP 的超级变量$_GET 获取 HTML表单(Form) 数据
- jsp处理c for循环中取到每一条信息+get方式提交form表单参数拼接问题
- HTML中Form表单提交时,采用 get和post的区别
- asp.net JS+form表单Post和Get方式提交数据
- activiti designer源码的研究(四) 之servicetask调用webservice(example)
- [转摘]jQuery formValidator表单验证插件开源了!!含API帮助、源码、示例
- ExtJS form表单常用元素操作
- form表单中get和post请求的区别
- 黑马程序员之ASP.NET学习笔记:Form表单中method=“post/get"
- 解决JSP的Form表单提交method=get时乱码
- 原生javascript 表单同步提交和提交前操作 和 document.form.submit() is not a function
- 通过getElementById来取得Form里的表单元素
- 关于请求方式为GET的form表单,action属性后不能带参数的问题
- activiti入门十一(表单的介绍以及formService使用)
- python tornado 简单的form表单操作
- Activiti源码浅析:Activity与Task
- 关于请求方式为GET的form表单,action属性后不能带参数的问题
- Form表单的post 和get跳转区别
- 表单FORM与GET方法的区别