Activiti源码跟踪之Task表单操作GetTaskFormCmd
来源:互联网 发布:axure iphone组件 mac 编辑:程序博客网 时间:2024/04/29 21:10
在Activiti中总共有三种表单,动态表单,普通表单和外置表单。本文介绍的是动态表单。
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 FormProperty 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()
- Activiti源码跟踪之Task表单操作GetTaskFormCmd
- Activiti源码跟踪之模型Model操作
- Activiti源码跟踪之流程部署
- Activiti源码浅析:Activity与Task
- Activiti源码浅析:Activity与Task
- 跟踪activiti创建流程引擎源码
- activiti源码笔记之deploy
- activiti 源码笔记之startProcess
- activiti 源码笔记之startProcess
- activiti 源码笔记之startProcess
- activiti学习之task与execution的关系
- ForkJoin源码分析之Task
- Spark源码分析之Task
- activiti自定义流程之自定义表单(二):创建表单
- activiti自定义流程之自定义表单(二):创建表单
- ACTIVITI 源码研究之命令模式执行
- activiti源码解读之心得整编
- ACTIVITI 源码研究之命令模式执行
- CCF 学生排队(Java),用集合求解。
- 获取本地时间
- 自定义View-滑动开关
- mysql 定时排除 用户 非正常 out
- ListView在工程中的详细应用(简易记账本)
- Activiti源码跟踪之Task表单操作GetTaskFormCmd
- Git学习-->GitLab如何屏蔽掉注册功能?
- List<T>泛型集合根据对象的某一属性排序
- Linux 压缩,解压缩,打包指令
- 基于ODBC的MFC与sql_server2008r2连接教程和错误解决方法
- 如何解决安卓上羊角符只显示一横的问题
- linux下profile和bashrc区别 + Linux中的权限
- Mybatis_HelloWorld 快速入门
- 我的第一篇博客