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 ...
随机推荐
- LINQ,EF联合查询join
public object GetListAdmin() { //return db_C56.Admins // .Where(a => a.Status != "D") ...
- HDU 4237 The Rascal Triangle
The Rascal Triangle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- Java序列化 如何把多个对象存储在一个文件中
/** * 用于保存模板文件,内容包括: * 1,标志位,1 int * 2,版本 1 int * 3,数据头长度 1 int * 4,预留数据头空间 5120 byte * 5,后续数据长度 ...
- HDU 5694 BD String 递归暴力
http://blog.csdn.net/angon823/article/details/51484906 #include <cstdio> #include <iostream ...
- LoadRunner常见问题整理(转)
首先要感谢群友的无私分享,才能得到这篇好的学习资料,整理得太好了,所以收藏保存,方便以后学习. 一:LoadRunner常见问题整理 1.LR 脚本为空的解决方法: 1.去掉ie设置中的第三方支持取消 ...
- uvalive 4973 Ardenia
题意:给出空间两条线段,求距离. 注意输出格式! #include<cstdio> #include<cmath> #include<algorithm> usin ...
- maven 本地setting.xml配置
<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...
- Hdu 5289-Assignment 贪心,ST表
题目: http://acm.hdu.edu.cn/showproblem.php?pid=5289 Assignment Time Limit: 4000/2000 MS (Java/Others) ...
- Ngrok,一款可以帮助你展示网站和联网开发的工具
使用Ngrok的目的就是为了可以让别人通过网络访问到自己本机上的项目 下面是一个简单的使用教程,详细的查看官网英文文档. 第一步: 登录官网:https://ngrok.com/ 注册或者登录 ...
- openstack 在线repo
https://repos.fedorapeople.org/repos/openstack/openstack-kilo/