Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素
| Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 |
| Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 |
| Fixflow引擎解析(二)(模型) - BPMN2.0读写 |
| Fixflow引擎解析(一)(介绍) - Fixflow开源流程引擎介绍 |
我们在第一章中介绍了怎么通过EMF读写BPMN2.0官方元素,
第三章中介绍了怎么建立一个简单的EMF模型来读写XML,
在这章里边我们介绍下怎么给BPMN2.0模型注入扩展元素。
1.为什么需要扩展
由于BPMN2.0官方提供的标准不能满足一个引擎需要运行起来的所需的一些元素,所有各个基于BPMN2.0标准的厂商都对BPMN2.0标准进行了自己的扩展。
例如:
activiti引擎的扩展都是以"activiti:"开头的
<serviceTask id="javaService"
name="Java service invocation"
activiti:class="org.activiti.examples.bpmn.servicetask.ToUpperCaseFieldInjected">
<extensionElements>
<activiti:field name="text" stringValue="Hello World" />
</extensionElements>
</serviceTask>
fixflow引擎的扩展都是以"fixflow:"开头的
<bpmn2:userTask id="UserTask_1" fixflow:taskType="FIXFLOWTASK" name="人工任务">
<bpmn2:extensionElements>
<fixflow:assignPolicyType id="potentialOwner"/>
<fixflow:skipStrategy/>
<fixflow:taskCommand id="HandleCommand_3" name="提交" commandType="submit"/>
<fixflow:expectedExecutionTime/>
<fixflow:formUri>
<fixflow:expression xsi:type="fixflow:Expression" id="Expression_3">DemoServlet?action=startOneTask</fixflow:expression>
</fixflow:formUri>
</bpmn2:extensionElements>
<bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
<bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing>
<bpmn2:potentialOwner id="PotentialOwner_1" fixflow:resourceType="user" fixflow:includeExclusion="INCLUDE"name="所有人">
<bpmn2:resourceAssignmentExpression id="ResourceAssignmentExpression_1">
<bpmn2:formalExpression id="所有人">"fixflow_allusers"</bpmn2:formalExpression>
</bpmn2:resourceAssignmentExpression>
</bpmn2:potentialOwner>
</bpmn2:userTask>
每个引擎的厂商都会对BPMN2.0官方元素做出扩展,这就导致了流程定义虽然可以在不同的流程产品相互显示,但是想运行起来是不可能的。
2.BPMN2.0官方关于扩展元素的支持
可以看到BPMN2.0官方已经提供了扩展元素的存放位置:
<bpmn2:userTask id="UserTask_1" fixflow:taskType="FIXFLOWTASK" name="人工任务">
<bpmn2:extensionElements>
<fixflow:assignPolicyType id="potentialOwner"/>
<fixflow:skipStrategy/>
</bpmn2:extensionElements>
</bpmn2:userTask>
"extensionElements" 元素内就用来存放各个厂商自己扩展的元素,"fixflow:"开头的 attribute 就是官网元素本身的属性扩展,
官方也是清楚的,他们给的那点肯定是不够用的,所以就有了上面的扩展,3.0出来了肯定会提供更多支持。
3.扩展 BPMN2.0 EMF模型的思路
Fixflow在读写BPMN2.0模型的时候使用了Eclipse官方提供的EMF模型,扩展元素的最好的方式就是不修改原始Eclipse提供的模型,
采用外部注入的方式修改给EMF模型添加新的元素。我们需要重新建立一个EMF模型来放置Fixflow引擎自己扩展的元素定义,
通过EMF提供的注入方法添加到元素的模型保存中去,下面我们一步步来完成这个过程。
4.创建一个EMF模型
这里我们不再详细介绍创建模型文件的过程,不清楚的请参考第三章创建模型。
下面的截图是 fixflow 的扩展元素模型:

这个扩展模型有些需要注意的地方,模型 整体的 Ns Prefix 和 Ns URI 这个两个属性决定了你扩展元素的名称和命名空间。

Attributes 的设置需要注意的事项。

EReference 引用设置需要主要的地方。

创建完毕生成三个模型文件,并生成对应java代码。

5.读写扩展元素
下面的代码就是在web环境下读写BPMN2.0模型扩展元素的代码:
模型文件下载地址: SampleProcess.bpmn.7z
import java.util.List; import org.eclipse.bpmn2.BaseElement;
import org.eclipse.bpmn2.Bpmn2Factory;
import org.eclipse.bpmn2.Bpmn2Package;
import org.eclipse.bpmn2.Definitions;
import org.eclipse.bpmn2.ExtensionAttributeValue;
import org.eclipse.bpmn2.RootElement;
import org.eclipse.bpmn2.di.BpmnDiPackage;
import org.eclipse.bpmn2.util.Bpmn2ResourceFactoryImpl;
import org.eclipse.dd.dc.DcPackage;
import org.eclipse.dd.di.DiPackage;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.impl.EStructuralFeatureImpl.SimpleFeatureMapEntry;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.FeatureMap; import com.founder.fix.bpmn2extensions.fixflow.ConnectorInstance;
import com.founder.fix.bpmn2extensions.fixflow.FixFlowFactory;
import com.founder.fix.bpmn2extensions.fixflow.FixFlowPackage; public class test { public static void main(String[] args) {
//创建资源集
ResourceSet resourceSet = getResourceSet();
//创建资源
Resource resource = resourceSet.createResource(URI.createURI("SampleProcess.bpmn")); try {
//加载资源
resource.load(null);
} catch (Exception e) {
e.printStackTrace();
}
//获取根元素
Definitions definitions = (Definitions) resource.getContents().get(0).eContents().get(0);
//获取process对象
org.eclipse.bpmn2.Process process=null;
for (RootElement rootElement : definitions.getRootElements()) {
if (rootElement instanceof org.eclipse.bpmn2.Process) {
process = (org.eclipse.bpmn2.Process) rootElement;
}
} if(process==null){
return;
} //设置扩展 EAttribute fixflow:dbid
process.eSet(FixFlowPackage.Literals.DOCUMENT_ROOT__DBID, "SampleProcess_1");
//读取扩展 EAttribute fixflow:dbid
process.eGet(FixFlowPackage.Literals.DOCUMENT_ROOT__DBID); ConnectorInstance connectorInstance=FixFlowFactory.eINSTANCE.createConnectorInstance();
//添加扩展元素
addExtensionElement(process,FixFlowPackage.Literals.DOCUMENT_ROOT__CONNECTOR_INSTANCE,connectorInstance);
//读取扩展元素
getExtensionElementList(ConnectorInstance.class,process,FixFlowPackage.Literals.DOCUMENT_ROOT__CONNECTOR_INSTANCE); } /**
* 创建资源集
* @return
*/
private static ResourceSet getResourceSet() { //以下的方式是脱离Eclipse环境在web下使用EMF的时候使用的方式,Eclipse里使用要简单的多。 ResourceSet resourceSet = new ResourceSetImpl();
(EPackage.Registry.INSTANCE).put("http://www.omg.org/spec/BPMN/20100524/MODEL", Bpmn2Package.eINSTANCE);
//注意这里的注册没有这个注册是没有办法通过直接获取扩展元素的
(EPackage.Registry.INSTANCE).put("http://www.founderfix.com/fixflow", FixFlowPackage.eINSTANCE);
(EPackage.Registry.INSTANCE).put("http://www.omg.org/spec/DD/20100524/DI", DiPackage.eINSTANCE);
(EPackage.Registry.INSTANCE).put("http://www.omg.org/spec/DD/20100524/DC", DcPackage.eINSTANCE);
(EPackage.Registry.INSTANCE).put("http://www.omg.org/spec/BPMN/20100524/DI", BpmnDiPackage.eINSTANCE);
FixFlowPackage.eINSTANCE.eClass();
FixFlowPackage xxxPackage = FixFlowPackage.eINSTANCE;
EPackage.Registry.INSTANCE.put(xxxPackage.getNsURI(), xxxPackage);
Bpmn2ResourceFactoryImpl ddd = new Bpmn2ResourceFactoryImpl();
//注意这里的注册没有这个注册是没有办法通过直接获取扩展元素的
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("fixflow", ddd);
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("bpmn", ddd);
resourceSet.getPackageRegistry().put(xxxPackage.getNsURI(), xxxPackage);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("bpmn", ddd);
return resourceSet;
} /**
* 读取扩展元素 Element
* @param t 扩展元素的java类型
* @param baseElement 主元素
* @param eReference 引用
* @return
*/
@SuppressWarnings("unchecked")
public static <T> List<T> getExtensionElementList( Class<T> t ,BaseElement baseElement,EReference eReference){ //BPMN2.0官方定义每个BaseElement元素都含有扩展元素ExtensionValues
if (baseElement.getExtensionValues().size() > 0) {
for (ExtensionAttributeValue extensionAttributeValue : baseElement.getExtensionValues()) {
FeatureMap extensionElements = extensionAttributeValue.getValue();
Object objectElement = extensionElements.get(eReference, true);
if (objectElement != null) { List<T> tObjList = (List<T>) objectElement;
return tObjList; }
}
} return (List<T>)null;
} /**
* 添加扩展元素
* @param baseElement 主元素
* @param eReference 引用
* @param o 扩展元素对象
* @return
*/
public static boolean addExtensionElement(BaseElement baseElement,EReference eReference,Object o){
final FeatureMap.Entry extensionElementEntry = new SimpleFeatureMapEntry((org.eclipse.emf.ecore.EStructuralFeature.Internal) eReference, o);
if(baseElement.getExtensionValues().size() > 0){
baseElement.getExtensionValues().get(0).getValue().add(extensionElementEntry);
}else{
ExtensionAttributeValue extensionElement = Bpmn2Factory.eINSTANCE.createExtensionAttributeValue();
extensionElement.getValue().add(extensionElementEntry);
baseElement.getExtensionValues().add(extensionElement);
}
return false;
} }
Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素的更多相关文章
- Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件
Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...
- Fixflow引擎解析(二)(模型) - BPMN2.0读写
Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...
- Fixflow引擎解析(一)(介绍) - Fixflow开源流程引擎介绍
Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...
- Fixflow引擎解析(五)(内核) - 基于Token驱动的引擎内核运转原理
Fixflow内核运转图v1.0(beta) 未完待续.........
- Cesium案例解析(四)——3DModels模型加载
目录 1. 概述 2. 代码 3. 解析 4. 参考 1. 概述 Cesium自带的3D Models示例,展示了如何加载glTF格式三维模型数据.glTF是为WebGL量身定制的数据格式,在网络环境 ...
- 批处理引擎MapReduce编程模型
批处理引擎MapReduce编程模型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. MapReduce是一个经典的分布式批处理计算引擎,被广泛应用于搜索引擎索引构建,大规模数据处理 ...
- Alink漫谈(四) : 模型的来龙去脉
Alink漫谈(四) : 模型的来龙去脉 目录 Alink漫谈(四) : 模型的来龙去脉 0x00 摘要 0x01 模型 1.1 模型包含内容 1.2 Alink的模型文件 0x02 流程图 0x03 ...
- jQuery 2.0.3 源码分析Sizzle引擎解析原理
jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...
- Js引擎解析执行 阅读笔记
Js引擎解析执行 阅读笔记 一篇阅读笔记 http://km.oa.com/group/2178/articles/show/145691?kmref=search&from_page=1&a ...
随机推荐
- Spring AOP前置通知和后置通知
Spring AOP AspectJ:Java社区里最完整最流行的AOP框架 在Spring2.0以上的版本中,可以使用基于AspectJ注解或基于XML配置的AOP 在Spring中启用Aspect ...
- Oracle 给表添加主键和使ID自增、触发器、创建结构一样的表
1.关于主键:在建表时指定primary key字句即可:create table test( id number(6) primary key, name varchar2(30));如果是对于已经 ...
- 开源项目ets_cache分析
1 背景 当在程序中,有大量的数据需要读写,数据库的响应会延迟,甚至阻塞.缓存可以缓解对数据库访问的压力,而且在内存中数据的读写要比读写硬盘上的数据快. 2 目的 ets_cache是用erlang实 ...
- MD5加密帮助类
using System; using System.Collections.Generic; using System.Text; namespace AIMSCommon { /// <su ...
- 《深入Java虚拟机学习笔记》- 第7章 类型的生命周期/对象在JVM中的生命周期
一.类型生命周期的开始 如图所示 初始化时机 所有Java虚拟机实现必须在每个类或接口首次主动使用时初始化: 以下几种情形符合主动使用的要求: 当创建某个类的新实例时(或者通过在字节码中执行new指令 ...
- HDU 1560 DNA sequence DFS
题意:找到一个最短的串,使得所有给出的串是它的子序列,输出最短的串的长度,然后发现这个串最长是40 分析:从所给串的最长长度开始枚举,然后对于每个长度,暴力深搜,枚举当前位是哪一个字母,注意剪枝 注: ...
- tomcat 容器中的UML架构图
- 【暑假】[实用数据结构]UVAlive 3026 Period
UVAlive 3026 Period 题目: Period Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld ...
- jQuery遍历多层json数据
1.json与jsonp的区别(待查) 2.要遍历的数据如下: {"status": "ok", "code": 200, "da ...
- OpenCV - Operations on Arrays 对数组(矩阵)的一些操作
Function (函数名) Use (函数用处) add 矩阵加法,A+B的更高级形式,支持mask scaleAdd 矩阵加法,一个带有缩放因子dst(I) = scale * src1(I) + ...