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="所有人">&quot;fixflow_allusers&quot;</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元素的更多相关文章

  1. Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件

    Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...

  2. Fixflow引擎解析(二)(模型) - BPMN2.0读写

    Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...

  3. Fixflow引擎解析(一)(介绍) - Fixflow开源流程引擎介绍

    Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...

  4. Fixflow引擎解析(五)(内核) - 基于Token驱动的引擎内核运转原理

    Fixflow内核运转图v1.0(beta) 未完待续.........

  5. Cesium案例解析(四)——3DModels模型加载

    目录 1. 概述 2. 代码 3. 解析 4. 参考 1. 概述 Cesium自带的3D Models示例,展示了如何加载glTF格式三维模型数据.glTF是为WebGL量身定制的数据格式,在网络环境 ...

  6. 批处理引擎MapReduce编程模型

    批处理引擎MapReduce编程模型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. MapReduce是一个经典的分布式批处理计算引擎,被广泛应用于搜索引擎索引构建,大规模数据处理 ...

  7. Alink漫谈(四) : 模型的来龙去脉

    Alink漫谈(四) : 模型的来龙去脉 目录 Alink漫谈(四) : 模型的来龙去脉 0x00 摘要 0x01 模型 1.1 模型包含内容 1.2 Alink的模型文件 0x02 流程图 0x03 ...

  8. jQuery 2.0.3 源码分析Sizzle引擎解析原理

    jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...

  9. Js引擎解析执行 阅读笔记

    Js引擎解析执行 阅读笔记 一篇阅读笔记 http://km.oa.com/group/2178/articles/show/145691?kmref=search&from_page=1&a ...

随机推荐

  1. LINQ,EF联合查询join

    public object GetListAdmin() { //return db_C56.Admins //   .Where(a => a.Status != "D") ...

  2. HDU 4237 The Rascal Triangle

    The Rascal Triangle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  3. Java序列化 如何把多个对象存储在一个文件中

    /** * 用于保存模板文件,内容包括: * 1,标志位,1 int * 2,版本   1 int * 3,数据头长度 1 int * 4,预留数据头空间  5120 byte * 5,后续数据长度  ...

  4. HDU 5694 BD String 递归暴力

    http://blog.csdn.net/angon823/article/details/51484906 #include <cstdio> #include <iostream ...

  5. LoadRunner常见问题整理(转)

    首先要感谢群友的无私分享,才能得到这篇好的学习资料,整理得太好了,所以收藏保存,方便以后学习. 一:LoadRunner常见问题整理 1.LR 脚本为空的解决方法: 1.去掉ie设置中的第三方支持取消 ...

  6. uvalive 4973 Ardenia

    题意:给出空间两条线段,求距离. 注意输出格式! #include<cstdio> #include<cmath> #include<algorithm> usin ...

  7. maven 本地setting.xml配置

    <?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...

  8. Hdu 5289-Assignment 贪心,ST表

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=5289 Assignment Time Limit: 4000/2000 MS (Java/Others) ...

  9. Ngrok,一款可以帮助你展示网站和联网开发的工具

      使用Ngrok的目的就是为了可以让别人通过网络访问到自己本机上的项目 下面是一个简单的使用教程,详细的查看官网英文文档. 第一步: 登录官网:https://ngrok.com/   注册或者登录 ...

  10. openstack 在线repo

    https://repos.fedorapeople.org/repos/openstack/openstack-kilo/