zoukankan      html  css  js  c++  java
  • Fixflow引擎解析(四)(模型)

    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:"开头的

    1 <serviceTask id="javaService" 
    2     name="Java service invocation" 
    3     activiti:class="org.activiti.examples.bpmn.servicetask.ToUpperCaseFieldInjected">
    4     <extensionElements>
    5       <activiti:field name="text" stringValue="Hello World" />
    6   </extensionElements>           
    7 </serviceTask>   

    fixflow引擎的扩展都是以"fixflow:"开头的

     1  <bpmn2:userTask id="UserTask_1" fixflow:taskType="FIXFLOWTASK" name="人工任务">
     2       <bpmn2:extensionElements>
     3         <fixflow:assignPolicyType id="potentialOwner"/>
     4         <fixflow:skipStrategy/>
     5         <fixflow:taskCommand id="HandleCommand_3" name="提交" commandType="submit"/>
     8         <fixflow:expectedExecutionTime/>
     9         <fixflow:formUri>
    10           <fixflow:expression xsi:type="fixflow:Expression" id="Expression_3">DemoServlet?action=startOneTask</fixflow:expression>
    11         </fixflow:formUri>
    12       </bpmn2:extensionElements>
    13       <bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
    14       <bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing>
    15       <bpmn2:potentialOwner id="PotentialOwner_1" fixflow:resourceType="user" fixflow:includeExclusion="INCLUDE"name="所有人">
    16         <bpmn2:resourceAssignmentExpression id="ResourceAssignmentExpression_1">
    17           <bpmn2:formalExpression id="所有人">&quot;fixflow_allusers&quot;</bpmn2:formalExpression>
    18         </bpmn2:resourceAssignmentExpression>
    19       </bpmn2:potentialOwner>
    21  </bpmn2:userTask>

     每个引擎的厂商都会对BPMN2.0官方元素做出扩展,这就导致了流程定义虽然可以在不同的流程产品相互显示,但是想运行起来是不可能的。

    2.BPMN2.0官方关于扩展元素的支持

    可以看到BPMN2.0官方已经提供了扩展元素的存放位置:

     1   <bpmn2:userTask id="UserTask_1" fixflow:taskType="FIXFLOWTASK" name="人工任务">
     2       <bpmn2:extensionElements>
     3         <fixflow:assignPolicyType id="potentialOwner"/>
     4         <fixflow:skipStrategy/>
    12       </bpmn2:extensionElements>
    13   </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

      1 import java.util.List;
      2 
      3 import org.eclipse.bpmn2.BaseElement;
      4 import org.eclipse.bpmn2.Bpmn2Factory;
      5 import org.eclipse.bpmn2.Bpmn2Package;
      6 import org.eclipse.bpmn2.Definitions;
      7 import org.eclipse.bpmn2.ExtensionAttributeValue;
      8 import org.eclipse.bpmn2.RootElement;
      9 import org.eclipse.bpmn2.di.BpmnDiPackage;
     10 import org.eclipse.bpmn2.util.Bpmn2ResourceFactoryImpl;
     11 import org.eclipse.dd.dc.DcPackage;
     12 import org.eclipse.dd.di.DiPackage;
     13 import org.eclipse.emf.common.util.URI;
     14 import org.eclipse.emf.ecore.EPackage;
     15 import org.eclipse.emf.ecore.EReference;
     16 import org.eclipse.emf.ecore.impl.EStructuralFeatureImpl.SimpleFeatureMapEntry;
     17 import org.eclipse.emf.ecore.resource.Resource;
     18 import org.eclipse.emf.ecore.resource.ResourceSet;
     19 import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
     20 import org.eclipse.emf.ecore.util.FeatureMap;
     21 
     22 import com.founder.fix.bpmn2extensions.fixflow.ConnectorInstance;
     23 import com.founder.fix.bpmn2extensions.fixflow.FixFlowFactory;
     24 import com.founder.fix.bpmn2extensions.fixflow.FixFlowPackage;
     25 
     26 
     27 public class test {
     28 
     29     public static void main(String[] args) {
     30         //创建资源集
     31         ResourceSet resourceSet = getResourceSet();
     32         //创建资源
     33         Resource resource = resourceSet.createResource(URI.createURI("SampleProcess.bpmn"));
     34         
     35         
     36         try {
     37             //加载资源
     38             resource.load(null);
     39         } catch (Exception e) {
     40             e.printStackTrace();
     41         }
     42         //获取根元素
     43         Definitions definitions = (Definitions) resource.getContents().get(0).eContents().get(0);
     44         //获取process对象
     45         org.eclipse.bpmn2.Process process=null;
     46         for (RootElement rootElement : definitions.getRootElements()) {
     47             if (rootElement instanceof org.eclipse.bpmn2.Process) {
     48                 process = (org.eclipse.bpmn2.Process) rootElement;                
     49             }
     50         }
     51         
     52         if(process==null){
     53             return;
     54         }
     55         
     56         //设置扩展 EAttribute fixflow:dbid
     57         process.eSet(FixFlowPackage.Literals.DOCUMENT_ROOT__DBID, "SampleProcess_1");
     58         //读取扩展 EAttribute fixflow:dbid
     59         process.eGet(FixFlowPackage.Literals.DOCUMENT_ROOT__DBID);
     60         
     61         
     62         ConnectorInstance connectorInstance=FixFlowFactory.eINSTANCE.createConnectorInstance();
     63         //添加扩展元素
     64         addExtensionElement(process,FixFlowPackage.Literals.DOCUMENT_ROOT__CONNECTOR_INSTANCE,connectorInstance);
     65         //读取扩展元素
     66         getExtensionElementList(ConnectorInstance.class,process,FixFlowPackage.Literals.DOCUMENT_ROOT__CONNECTOR_INSTANCE);
     67         
     68 
     69     }
     70     
     71     /**
     72      * 创建资源集
     73      * @return
     74      */
     75     private static ResourceSet getResourceSet() {
     76         
     77         //以下的方式是脱离Eclipse环境在web下使用EMF的时候使用的方式,Eclipse里使用要简单的多。
     78         
     79         ResourceSet resourceSet = new ResourceSetImpl();
     80         (EPackage.Registry.INSTANCE).put("http://www.omg.org/spec/BPMN/20100524/MODEL", Bpmn2Package.eINSTANCE);
     81         //注意这里的注册没有这个注册是没有办法通过直接获取扩展元素的
     82         (EPackage.Registry.INSTANCE).put("http://www.founderfix.com/fixflow", FixFlowPackage.eINSTANCE);
     83         (EPackage.Registry.INSTANCE).put("http://www.omg.org/spec/DD/20100524/DI", DiPackage.eINSTANCE);
     84         (EPackage.Registry.INSTANCE).put("http://www.omg.org/spec/DD/20100524/DC", DcPackage.eINSTANCE);
     85         (EPackage.Registry.INSTANCE).put("http://www.omg.org/spec/BPMN/20100524/DI", BpmnDiPackage.eINSTANCE);
     86         FixFlowPackage.eINSTANCE.eClass();
     87         FixFlowPackage xxxPackage = FixFlowPackage.eINSTANCE;
     88         EPackage.Registry.INSTANCE.put(xxxPackage.getNsURI(), xxxPackage);
     89         Bpmn2ResourceFactoryImpl ddd = new Bpmn2ResourceFactoryImpl();
     90         //注意这里的注册没有这个注册是没有办法通过直接获取扩展元素的
     91         Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("fixflow", ddd);
     92         resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("bpmn", ddd);
     93         resourceSet.getPackageRegistry().put(xxxPackage.getNsURI(), xxxPackage);
     94         Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("bpmn", ddd);
     95         return resourceSet;
     96     }
     97     
     98     /**
     99      * 读取扩展元素 Element
    100      * @param t 扩展元素的java类型
    101      * @param baseElement 主元素
    102      * @param eReference 引用
    103      * @return
    104      */
    105     @SuppressWarnings("unchecked")
    106     public static <T> List<T> getExtensionElementList( Class<T> t ,BaseElement baseElement,EReference eReference){
    107         
    108         //BPMN2.0官方定义每个BaseElement元素都含有扩展元素ExtensionValues
    109         if (baseElement.getExtensionValues().size() > 0) {
    110             for (ExtensionAttributeValue extensionAttributeValue : baseElement.getExtensionValues()) {
    111                 FeatureMap extensionElements = extensionAttributeValue.getValue();
    112                 Object objectElement = extensionElements.get(eReference, true);
    113                 if (objectElement != null) {
    114 
    115                     List<T> tObjList = (List<T>) objectElement;
    116                     return tObjList;
    117                 
    118 
    119                 }
    120             }
    121         }
    122         
    123         
    124         return (List<T>)null;
    125     }
    126     
    127     /**
    128      * 添加扩展元素
    129      * @param baseElement 主元素
    130      * @param eReference 引用
    131      * @param o 扩展元素对象
    132      * @return
    133      */
    134     public static boolean addExtensionElement(BaseElement baseElement,EReference eReference,Object o){
    135         final FeatureMap.Entry extensionElementEntry = new SimpleFeatureMapEntry((org.eclipse.emf.ecore.EStructuralFeature.Internal) eReference, o);
    136             if(baseElement.getExtensionValues().size() > 0){
    137                 baseElement.getExtensionValues().get(0).getValue().add(extensionElementEntry);
    138             }else{
    139                 ExtensionAttributeValue extensionElement = Bpmn2Factory.eINSTANCE.createExtensionAttributeValue();
    140                 extensionElement.getValue().add(extensionElementEntry);
    141                 baseElement.getExtensionValues().add(extensionElement);
    142             } 
    143         return false;
    144     }
    145 
    146 }
  • 相关阅读:
    什么是首次适应算法,该算法的特点是什么?
    用上、下界防护方法是如何实现界地址保护?在硬件上需要什么支持?
    什么是存储保护?
    什么是静态地址重定位,它需要什么支持?什么是动态地址重定位,他需要什么支持?静态地址重定位与动态地址重定位有什么区别?
    什么是逻辑地址,什么是物理地址,为什么要进行二者的转换工作?
    三个进程共享四个同类资源,这些资源的分配与释放只能一次一个。已知每一个进程最多需要两个资源,试问,该系统会发生死锁吗?为什么?
    试举出一种一种避免死锁的发生的方法,并说明为什么能避免死锁的发生?
    产生死锁的原因是什么?产生死锁的必要条件是什么?
    什么是死锁,试举例说明?
    说出两种一笔调度的算法,并说出这两种移臂调度算法的定义。
  • 原文地址:https://www.cnblogs.com/kenshin1985/p/3545889.html
Copyright © 2011-2022 走看看