您的位置:首页 > 其它

Activiti源码跟踪之Task表单操作GetTaskFormCmd

2017-11-17 17:00 344 查看
在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 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()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: