Activiti7工作流引擎:在线流程编辑器Activiti Modoler5.x

一:简介

有的时候我们的流程图需要业务人员自己绘制,然后使用自己绘制的流程图,此时就需要一个在线流程图编辑器需要集成到我们的web系统中。Activiti Modoler是Activiti官方推出的在线流程编辑器。

二:pom.xml

<dependency>
	<groupId>org.activitigroupId>
    <artifactId>activiti-explorerartifactId>
    <version>5.22.0version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4jgroupId>
            <artifactId>slf4j-log4j12artifactId>
        exclusion>
    exclusions>
dependency>

<dependency>
    <groupId>org.apache.xmlgraphicsgroupId>
    <artifactId>batik-codecartifactId>
    <version>1.7version>
dependency>

<dependency>
    <groupId>org.apache.xmlgraphicsgroupId>
    <artifactId>batik-cssartifactId>
    <version>1.7version>
dependency>

<dependency>
    <groupId>org.apache.xmlgraphicsgroupId>
    <artifactId>batik-svg-domartifactId>
    <version>1.7version>
dependency>

<dependency>
    <groupId>org.apache.xmlgraphicsgroupId>
    <artifactId>batik-svggenartifactId>
    <version>1.7version>
dependency>

<dependency>
    <groupId>commons-iogroupId>
    <artifactId>commons-ioartifactId>
    <version>2.4version>
dependency>

三:集成前端页面

https://github.com/Activiti/Activiti/tree/5.x 将整个项目下载下来。不同版本的目录结构区别很大,这里使用5.x。

3.1 集成静态文件

  1. 将\modules\activiti-webapp-explorer2\src\main\webapp目录下的diagram-viewer、editor-app 整个目录、modeler.html 放到resources/static目录下。
  2. 将\modules\activiti-webapp-explorer2\src\main\resources\stencilset.json 直接放到resources的根目录下,不需要放在stattc目录下。该文件用于国际化。

Activiti7工作流引擎:在线流程编辑器Activiti Modoler5.x_第1张图片

3.2 适配前端代码

editor-app\app-cfg.js:修改为空

ACTIVITI.CONFIG = {
	'contextRoot' : '',
};

src/main/resources/static/editor-app/configuration/toolbar-default-actions.js

// 该方法改造不是必须的
closeEditor: function(services) {
    // window.location.href = "./";
    if (window.confirm('确定要放弃此次编辑吗?')){
        //1、关闭前对于未点击保存的模型做删除处理
        var modelMetaData = services.$scope.editor.getModelMetaData();
        location.href = "/activiti/model/close/" + modelMetaData.modelId;
        //2、返回上一页面
        window.history.back(-1);
    }
},

$scope.saveAndClose = function () {
	$scope.save(function() {
        // window.location.href = "./";
        window.history.back(-1);//返回上一页面
    });
};

3.3 加载静态资源

WebMvc允许加载静态资源

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    //解决  No mapping for GET 访问静态资源问题
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/")
                .addResourceLocations("classpath:/META-INF/resources/");
    }
}

四:引入Java类

modules/activiti-modeler项目中的StencilsetRestResource.java(模具集Rest资源),ModelEditorJsonRestResource.java(模板编辑),ModelSaveRestResource.java (模型保存) 放在任意包下。

使用下面代码覆盖原来的方法。

/**
 * @author Tijs Rademakers
 */
@RestController
public class ModelSaveRestResource implements ModelDataJsonConstants {

    protected static final Logger LOGGER = LoggerFactory.getLogger(ModelSaveRestResource.class);

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ObjectMapper objectMapper;

    @RequestMapping(value = "/model/{modelId}/save", method = RequestMethod.PUT)
    @ResponseStatus(value = HttpStatus.OK)
    public void saveModel(@PathVariable String modelId, String name, String description, String json_xml,
                          String svg_xml) {
        try {
            Model model = repositoryService.getModel(modelId);

            ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo());

            modelJson.put(MODEL_NAME, name);
            modelJson.put(MODEL_DESCRIPTION, description);
            model.setMetaInfo(modelJson.toString());
            model.setName(name);

            repositoryService.saveModel(model);

            repositoryService.addModelEditorSource(model.getId(), json_xml.getBytes("utf-8"));

            InputStream svgStream = new ByteArrayInputStream(svg_xml.getBytes("utf-8"));
            TranscoderInput input = new TranscoderInput(svgStream);

            PNGTranscoder transcoder = new PNGTranscoder();
            // Setup output
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            TranscoderOutput output = new TranscoderOutput(outStream);

            // Do the transformation
            transcoder.transcode(input, output);
            final byte[] result = outStream.toByteArray();
            repositoryService.addModelEditorSourceExtra(model.getId(), result);
            outStream.close();

        } catch (Exception e) {
            LOGGER.error("Error saving model", e);
            throw new ActivitiException("模型保存失败", e);
        }
    }
}

五:访问Activiti Editor页面

@RestController
@RequestMapping("/activiti")
public class ActivitiController {
    /**
     * 创建模型
     */
    @RequestMapping("/create")
    public void create(HttpServletRequest request, HttpServletResponse response) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            ObjectNode stencilSetNode = objectMapper.createObjectNode();
            stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");

            ObjectNode editorNode = objectMapper.createObjectNode();
            editorNode.put("id", "canvas");
            editorNode.put("resourceId", "canvas");
            editorNode.put("stencilset", stencilSetNode);

            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            RepositoryService repositoryService = processEngine.getRepositoryService();
            Model modelData = repositoryService.newModel();
 
            ObjectNode modelObjectNode = objectMapper.createObjectNode();
            modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, "模型");
            modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
            modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, "模型描述");
            modelData.setMetaInfo(modelObjectNode.toString());
            modelData.setName("我的模型");
            modelData.setKey("myModel");
 
            //保存模型
            repositoryService.saveModel(modelData);
            repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));
            response.sendRedirect(request.getContextPath() + "/modeler.html?modelId=" + modelData.getId());
        } catch (Exception e) {
            System.out.println("创建模型失败:");
        }
    }
}

http://localhost:8080/activiti/create

Activiti7工作流引擎:在线流程编辑器Activiti Modoler5.x_第2张图片

insert into ACT_GE_BYTEARRAY(ID_, REV_, NAME_, BYTES_, DEPLOYMENT_ID_) values ( ?, 1, ?, ?, ? )

update ACT_RE_MODEL set REV_ = ?, NAME_ = ?, KEY_ = ?, CATEGORY_ = ?, LAST_UPDATE_TIME_ = ?, VERSION_ = ?, META_INFO_ = ?, DEPLOYMENT_ID_ = ?, EDITOR_SOURCE_VALUE_ID_ = ?, EDITOR_SOURCE_EXTRA_VALUE_ID_ = ?, TENANT_ID_ = ? 

where ID_ = ? and REV_ = ?

六:汉化

stencilset.json 文件中的内容全部替换成下面内容。

{
  "title" : "BPMN 2.0标准工具",
  "namespace" : "http://b3mn.org/stencilset/bpmn2.0#",
  "description" : "BPMN process editor",
  "propertyPackages" : [ {
    "name" : "process_idpackage",
    "properties" : [ {
      "id" : "process_id",
      "type" : "String",
      "title" : "流程名称",
      "value" : "process",
      "description" : "流程的特殊唯一的名称标识",
      "popular" : true
    } ]
  }, {
    "name" : "overrideidpackage",
    "properties" : [ {
      "id" : "overrideid",
      "type" : "String",
      "title" : "Id",
      "value" : "",
      "description" : "Unique identifier of the element.",
      "popular" : true
    } ]
  }, {
    "name" : "namepackage",
    "properties" : [ {
      "id" : "name",
      "type" : "String",
      "title" : "名称",
      "value" : "",
      "description" : "元素名称",
      "popular" : true,
      "refToView" : "text_name"
    } ]
  }, {
    "name" : "documentationpackage",
    "properties" : [ {
      "id" : "documentation",
      "type" : "Text",
      "title" : "描述",
      "value" : "",
      "description" : "元素描述",
      "popular" : true
    } ]
  }, {
    "name" : "process_authorpackage",
    "properties" : [ {
      "id" : "process_author",
      "type" : "String",
      "title" : "流程作者",
      "value" : "",
      "description" : "流程定义者姓名",
      "popular" : true
    } ]
  }, {
    "name" : "process_versionpackage",
    "properties" : [ {
      "id" : "process_version",
      "type" : "String",
      "title" : "流程版本",
      "value" : "",
      "description" : "标识文档版本",
      "popular" : true
    } ]
  }, {
    "name" : "process_namespacepackage",
    "properties" : [ {
      "id" : "process_namespace",
      "type" : "String",
      "title" : "目标命名空间",
      "value" : "http://www.activiti.org/processdef",
      "description" : "工作流目标命名空间",
      "popular" : true
    } ]
  }, {
    "name" : "asynchronousdefinitionpackage",
    "properties" : [ {
      "id" : "asynchronousdefinition",
      "type" : "Boolean",
      "title" : "异步",
      "value" : "false",
      "description" : "Define the activity as asynchronous.",
      "popular" : true
    } ]
  }, {
    "name" : "exclusivedefinitionpackage",
    "properties" : [ {
      "id" : "exclusivedefinition",
      "type" : "Boolean",
      "title" : "单独",
      "value" : "false",
      "description" : "Define the activity as exclusive.",
      "popular" : true
    } ]
  }, {
    "name" : "executionlistenerspackage",
    "properties" : [ {
      "id" : "executionlisteners",
      "type" : "multiplecomplex",
      "title" : "执行监听器",
      "value" : "",
      "description" : "Listeners for an activity, process, sequence flow, start and end event.",
      "popular" : true
    } ]
  }, {
    "name" : "tasklistenerspackage",
    "properties" : [ {
      "id" : "tasklisteners",
      "type" : "multiplecomplex",
      "title" : "任务监听器",
      "value" : "",
      "description" : "Listeners for a user task",
      "popular" : true
    } ]
  }, {
    "name" : "eventlistenerspackage",
    "properties" : [ {
      "id" : "eventlisteners",
      "type" : "multiplecomplex",
      "title" : "事件监听器",
      "value" : "",
      "description" : "Listeners for any event happening in the Activiti Engine. It's also possible to rethrow the event as a signal, message or error event",
      "popular" : true
    } ]
  }, {
    "name" : "usertaskassignmentpackage",
    "properties" : [ {
      "id" : "usertaskassignment",
      "type" : "Complex",
      "title" : "代理",
      "value" : "",
      "description" : "Assignment definition for the user task",
      "popular" : true
    } ]
  }, {
    "name" : "formpropertiespackage",
    "properties" : [ {
      "id" : "formproperties",
      "type" : "Complex",
      "title" : "动态表单属性",
      "value" : "",
      "description" : "Definition of the form with a list of form properties",
      "popular" : true
    } ]
  }, {
    "name" : "formkeydefinitionpackage",
    "properties" : [ {
      "id" : "formkeydefinition",
      "type" : "String",
      "title" : "自定义表单",
      "value" : "",
      "description" : "用户任务表单编号",
      "popular" : true
    } ]
  }, {
    "name" : "duedatedefinitionpackage",
    "properties" : [ {
      "id" : "duedatedefinition",
      "type" : "String",
      "title" : "到期日期",
      "value" : "",
      "description" : "用户任务到期时间",
      "popular" : true
    } ]
  }, {
    "name" : "prioritydefinitionpackage",
    "properties" : [ {
      "id" : "prioritydefinition",
      "type" : "String",
      "title" : "优先级",
      "value" : "",
      "description" : "用户任务优先级",
      "popular" : true
    } ]
  }, {
    "name" : "duedatedefinitionpackage",
    "properties" : [ {
      "id" : "duedatedefinition",
      "type" : "String",
      "title" : "到期日期",
      "value" : "",
      "description" : "Due date of the user task.",
      "popular" : true
    } ]
  }, {
    "name" : "servicetaskclasspackage",
    "properties" : [ {
      "id" : "servicetaskclass",
      "type" : "String",
      "title" : "监听类",
      "value" : "",
      "description" : "Class that implements the service task logic.",
      "popular" : true
    } ]
  }, {
    "name" : "servicetaskexpressionpackage",
    "properties" : [ {
      "id" : "servicetaskexpression",
      "type" : "String",
      "title" : "表达式",
      "value" : "",
      "description" : "Service task logic defined with an expression.",
      "popular" : true
    } ]
  }, {
    "name" : "servicetaskdelegateexpressionpackage",
    "properties" : [ {
      "id" : "servicetaskdelegateexpression",
      "type" : "String",
      "title" : "委托表达式",
      "value" : "",
      "description" : "Service task logic defined with a delegate expression.",
      "popular" : true
    } ]
  }, {
    "name" : "servicetaskfieldspackage",
    "properties" : [ {
      "id" : "servicetaskfields",
      "type" : "Complex",
      "title" : "字段",
      "value" : "",
      "description" : "Field extensions",
      "popular" : true
    } ]
  }, {
    "name" : "servicetaskresultvariablepackage",
    "properties" : [ {
      "id" : "servicetaskresultvariable",
      "type" : "String",
      "title" : "Result variable name",
      "value" : "",
      "description" : "Process variable name to store the service task result.",
      "popular" : true
    } ]
  }, {
    "name" : "scriptformatpackage",
    "properties" : [ {
      "id" : "scriptformat",
      "type" : "String",
      "title" : "脚本格式",
      "value" : "",
      "description" : "Script format of the script task.",
      "popular" : true
    } ]
  }, {
    "name" : "scripttextpackage",
    "properties" : [ {
      "id" : "scripttext",
      "type" : "Text",
      "title" : "脚本",
      "value" : "",
      "description" : "Script text of the script task.",
      "popular" : true
    } ]
  }, {
    "name" : "ruletask_rulespackage",
    "properties" : [ {
      "id" : "ruletask_rules",
      "type" : "String",
      "title" : "规则",
      "value" : "",
      "description" : "Rules of the rule task.",
      "popular" : true
    } ]
  }, {
    "name" : "ruletask_variables_inputpackage",
    "properties" : [ {
      "id" : "ruletask_variables_input",
      "type" : "String",
      "title" : "输入变量",
      "value" : "",
      "description" : "Input variables of the rule task.",
      "popular" : true
    } ]
  }, {
    "name" : "ruletask_excludepackage",
    "properties" : [ {
      "id" : "ruletask_exclude",
      "type" : "Boolean",
      "title" : "除外",
      "value" : "false",
      "description" : "Use the rules property as exclusion.",
      "popular" : true
    } ]
  }, {
    "name" : "ruletask_resultpackage",
    "properties" : [ {
      "id" : "ruletask_result",
      "type" : "String",
      "title" : "返回变量",
      "value" : "",
      "description" : "Result variable of the rule task.",
      "popular" : true
    } ]
  }, {
    "name" : "mailtasktopackage",
    "properties" : [ {
      "id" : "mailtaskto",
      "type" : "Text",
      "title" : "接收人",
      "value" : "",
      "description" : "The recipients if the e-mail. Multiple recipients are defined in a comma-separated list.",
      "popular" : true
    } ]
  }, {
    "name" : "mailtaskfrompackage",
    "properties" : [ {
      "id" : "mailtaskfrom",
      "type" : "Text",
      "title" : "发件人",
      "value" : "",
      "description" : "The sender e-mail address. If not provided, the default configured from address is used.",
      "popular" : true
    } ]
  }, {
    "name" : "mailtasksubjectpackage",
    "properties" : [ {
      "id" : "mailtasksubject",
      "type" : "Text",
      "title" : "主题",
      "value" : "",
      "description" : "The subject of the e-mail.",
      "popular" : true
    } ]
  }, {
    "name" : "mailtaskccpackage",
    "properties" : [ {
      "id" : "mailtaskcc",
      "type" : "Text",
      "title" : "转发",
      "value" : "",
      "description" : "The cc's of the e-mail. Multiple recipients are defined in a comma-separated list",
      "popular" : true
    } ]
  }, {
    "name" : "mailtaskbccpackage",
    "properties" : [ {
      "id" : "mailtaskbcc",
      "type" : "Text",
      "title" : "密送",
      "value" : "",
      "description" : "The bcc's of the e-mail. Multiple recipients are defined in a comma-separated list",
      "popular" : true
    } ]
  }, {
    "name" : "mailtasktextpackage",
    "properties" : [ {
      "id" : "mailtasktext",
      "type" : "Text",
      "title" : "内容",
      "value" : "",
      "description" : "The content of the e-mail, in case one needs to send plain none-rich e-mails. Can be used in combination with html, for e-mail clients that don't support rich content. The client will then fall back to this text-only alternative.",
      "popular" : true
    } ]
  }, {
    "name" : "mailtaskhtmlpackage",
    "properties" : [ {
      "id" : "mailtaskhtml",
      "type" : "Text",
      "title" : "Html",
      "value" : "",
      "description" : "A piece of HTML that is the content of the e-mail.",
      "popular" : true
    } ]
  }, {
    "name" : "mailtaskcharsetpackage",
    "properties" : [ {
      "id" : "mailtaskcharset",
      "type" : "String",
      "title" : "Charset",
      "value" : "",
      "description" : "Allows to change the charset of the email, which is necessary for many non-English languages. ",
      "popular" : true
    } ]
  }, {
    "name" : "callactivitycalledelementpackage",
    "properties" : [ {
      "id" : "callactivitycalledelement",
      "type" : "String",
      "title" : "被调用元素",
      "value" : "",
      "description" : "Process reference.",
      "popular" : true
    } ]
  }, {
    "name" : "callactivityinparameterspackage",
    "properties" : [ {
      "id" : "callactivityinparameters",
      "type" : "Complex",
      "title" : "输入参数",
      "value" : "",
      "description" : "Definition of the input parameters",
      "popular" : true
    } ]
  }, {
    "name" : "callactivityoutparameterspackage",
    "properties" : [ {
      "id" : "callactivityoutparameters",
      "type" : "Complex",
      "title" : "输出参数",
      "value" : "",
      "description" : "Definition of the output parameters",
      "popular" : true
    } ]
  }, {
    "name" : "cameltaskcamelcontextpackage",
    "properties" : [ {
      "id" : "cameltaskcamelcontext",
      "type" : "String",
      "title" : "Camel内容",
      "value" : "",
      "description" : "An optional camel context definition, if left empty the default is used.",
      "popular" : true
    } ]
  }, {
    "name" : "muletaskendpointurlpackage",
    "properties" : [ {
      "id" : "muletaskendpointurl",
      "type" : "String",
      "title" : "终端url",
      "value" : "",
      "description" : "A required endpoint url to sent the message to Mule.",
      "popular" : true
    } ]
  }, {
    "name" : "muletasklanguagepackage",
    "properties" : [ {
      "id" : "muletasklanguage",
      "type" : "String",
      "title" : "语言",
      "value" : "",
      "description" : "A required definition for the language to resolve the payload expression, like juel.",
      "popular" : true
    } ]
  }, {
    "name" : "muletaskpayloadexpressionpackage",
    "properties" : [ {
      "id" : "muletaskpayloadexpression",
      "type" : "String",
      "title" : "有效载荷表达式",
      "value" : "",
      "description" : "A required definition for the payload of the message sent to Mule.",
      "popular" : true
    } ]
  }, {
    "name" : "muletaskresultvariablepackage",
    "properties" : [ {
      "id" : "muletaskresultvariable",
      "type" : "String",
      "title" : "返回变量",
      "value" : "",
      "description" : "An optional result variable for the payload returned.",
      "popular" : true
    } ]
  }, {
    "name" : "conditionsequenceflowpackage",
    "properties" : [ {
      "id" : "conditionsequenceflow",
      "type" : "Complex",
      "title" : "流转条件",
      "value" : "",
      "description" : "The condition of the sequence flow",
      "popular" : true
    } ]
  }, {
    "name" : "defaultflowpackage",
    "properties" : [ {
      "id" : "defaultflow",
      "type" : "Boolean",
      "title" : "默认流转",
      "value" : "false",
      "description" : "Define the sequence flow as default",
      "popular" : true,
      "refToView" : "default"
    } ]
  }, {
    "name" : "conditionalflowpackage",
    "properties" : [ {
      "id" : "conditionalflow",
      "type" : "Boolean",
      "title" : "Conditional flow",
      "value" : "false",
      "description" : "Define the sequence flow with a condition",
      "popular" : true
    } ]
  }, {
    "name" : "timercycledefinitionpackage",
    "properties" : [ {
      "id" : "timercycledefinition",
      "type" : "String",
      "title" : "循环时间(例:R3/PT10H)",
      "value" : "",
      "description" : "Define the timer with a ISO-8601 cycle.",
      "popular" : true
    } ]
  }, {
    "name" : "timerdatedefinitionpackage",
    "properties" : [ {
      "id" : "timerdatedefinition",
      "type" : "String",
      "title" : "开始时间(ISO-8601)",
      "value" : "",
      "description" : "Define the timer with a ISO-8601 date definition.",
      "popular" : true
    } ]
  }, {
    "name" : "timerdurationdefinitionpackage",
    "properties" : [ {
      "id" : "timerdurationdefinition",
      "type" : "String",
      "title" : "持续时间(例:PT5M)",
      "value" : "",
      "description" : "Define the timer with a ISO-8601 duration.",
      "popular" : true
    } ]
  }, {
    "name" : "timerenddatedefinitionpackage",
    "properties" : [ {
      "id" : "timerenddatedefinition",
      "type" : "String",
      "title" : "结束时间(ISO-8601)",
      "value" : "",
      "description" : "Define the timer with a ISO-8601 duration.",
      "popular" : true
    } ]
  }, {
    "name" : "messagerefpackage",
    "properties" : [ {
      "id" : "messageref",
      "type" : "String",
      "title" : "消息引用",
      "value" : "",
      "description" : "Define the message name.",
      "popular" : true
    } ]
  }, {
    "name" : "signalrefpackage",
    "properties" : [ {
      "id" : "signalref",
      "type" : "String",
      "title" : "信号引用",
      "value" : "",
      "description" : "Define the signal name.",
      "popular" : true
    } ]
  }, {
    "name" : "errorrefpackage",
    "properties" : [ {
      "id" : "errorref",
      "type" : "String",
      "title" : "错误引用",
      "value" : "",
      "description" : "Define the error name.",
      "popular" : true
    } ]
  }, {
    "name" : "cancelactivitypackage",
    "properties" : [ {
      "id" : "cancelactivity",
      "type" : "Boolean",
      "title" : "取消活动",
      "value" : "true",
      "description" : "Should the activity be cancelled",
      "popular" : true,
      "refToView" : [ "frame", "frame2" ]
    } ]
  }, {
    "name" : "initiatorpackage",
    "properties" : [ {
      "id" : "initiator",
      "type" : "String",
      "title" : "发起人",
      "value" : "",
      "description" : "Initiator of the process.",
      "popular" : true
    } ]
  }, {
    "name" : "textpackage",
    "properties" : [ {
      "id" : "text",
      "type" : "String",
      "title" : "Text",
      "value" : "",
      "description" : "The text of the text annotation.",
      "popular" : true,
      "refToView" : "text"
    } ]
  }, {
    "name" : "multiinstance_typepackage",
    "properties" : [ {
      "id" : "multiinstance_type",
      "type" : "kisbpm-multiinstance",
      "title" : "多实例类型",
      "value" : "None",
      "description" : "Repeated activity execution (parallel or sequential) can be displayed through different loop types",
      "popular" : true,
      "refToView" : "multiinstance"
    } ]
  }, {
    "name" : "multiinstance_cardinalitypackage",
    "properties" : [ {
      "id" : "multiinstance_cardinality",
      "type" : "String",
      "title" : "基数(多实例)",
      "value" : "",
      "description" : "Define the cardinality of multi instance.",
      "popular" : true
    } ]
  }, {
    "name" : "multiinstance_collectionpackage",
    "properties" : [ {
      "id" : "multiinstance_collection",
      "type" : "String",
      "title" : "集合(多实例)",
      "value" : "",
      "description" : "Define the collection for the multi instance.",
      "popular" : true
    } ]
  }, {
    "name" : "multiinstance_variablepackage",
    "properties" : [ {
      "id" : "multiinstance_variable",
      "type" : "String",
      "title" : "元素变量(多实例)",
      "value" : "",
      "description" : "Define the element variable for the multi instance.",
      "popular" : true
    } ]
  }, {
    "name" : "multiinstance_conditionpackage",
    "properties" : [ {
      "id" : "multiinstance_condition",
      "type" : "String",
      "title" : "完成条件(多实例)",
      "value" : "",
      "description" : "Define the completion condition for the multi instance.",
      "popular" : true
    } ]
  }, {
    "name" : "isforcompensationpackage",
    "properties" : [ {
      "id" : "isforcompensation",
      "type" : "Boolean",
      "title" : "是否为补偿",
      "value" : "false",
      "description" : "一个标志,标识是否这个活动的目的是为了补偿.",
      "popular" : true,
      "refToView" : "compensation"
    } ]
  }, {
    "name" : "sequencefloworderpackage",
    "properties" : [ {
      "id" : "sequencefloworder",
      "type" : "Complex",
      "title" : "流动顺序",
      "value" : "",
      "description" : "Order outgoing sequence flows.",
      "popular" : true
    } ]
  }, {
    "name" : "signaldefinitionspackage",
    "properties" : [ {
      "id" : "signaldefinitions",
      "type" : "multiplecomplex",
      "title" : "信号定义",
      "value" : "",
      "description" : "Signal definitions",
      "popular" : true
    } ]
  }, {
    "name" : "messagedefinitionspackage",
    "properties" : [ {
      "id" : "messagedefinitions",
      "type" : "multiplecomplex",
      "title" : "消息定义",
      "value" : "",
      "description" : "Message definitions",
      "popular" : true
    } ]
  }, {
    "name" : "istransactionpackage",
    "properties" : [ {
      "id" : "istransaction",
      "type" : "Boolean",
      "title" : "是否事务处理子过程",
      "value" : "false",
      "description" : "A flag that identifies whether this sub process is of type transaction.",
      "popular" : true,
      "refToView" : "border"
    } ]
  }, {
    "name" : "terminateAllpackage",
    "properties" : [ {
      "id" : "terminateAll",
      "type" : "Boolean",
      "title" : "终止全部",
      "value" : "false",
      "description" : "Enable to terminate the process instance",
      "popular" : true
    } ]
  } ],
  "stencils" : [ {
    "type" : "node",
    "id" : "BPMNDiagram",
    "title" : "BPMN-Diagram",
    "description" : "A BPMN 2.0 diagram.",
    "view" : "\n\n  \n  \n    \n    \n    \t\n  \n",
    "icon" : "diagram.png",
    "groups" : [ "Diagram" ],
    "mayBeRoot" : true,
    "hide" : true,
    "propertyPackages" : [ "process_idpackage", "namepackage", "documentationpackage", "process_authorpackage", "process_versionpackage", "process_namespacepackage", "executionlistenerspackage", "eventlistenerspackage", "signaldefinitionspackage", "messagedefinitionspackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ ]
  }, {
    "type" : "node",
    "id" : "StartNoneEvent",
    "title" : "事件",
    "description" : "A start event without a specific trigger",
    "view" : "\n\n  \n  \n  \t\n  \n  \n    \n\t\n  \n",
    "icon" : "startevent/none.png",
    "groups" : [ "启动事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "initiatorpackage", "formkeydefinitionpackage", "formpropertiespackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "Startevents_all", "StartEventsMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "StartTimerEvent",
    "title" : "定时事件",
    "description" : "A start event with a timer trigger",
    "view" : "\n\n  \n  \n  \t\n  \n  \n    \n    \n    \n    \n   \n\t\n  \n",
    "icon" : "startevent/timer.png",
    "groups" : [ "启动事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "timercycledefinitionpackage", "timerdatedefinitionpackage", "timerdurationdefinitionpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "Startevents_all", "StartEventsMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "StartSignalEvent",
    "title" : "信号事件",
    "description" : "A start event with a signal trigger",
    "view" : "\n\n  \n  \n  \t\n  \n  \n\n    \n    \n    \n\t\n  \n",
    "icon" : "startevent/signal.png",
    "groups" : [ "启动事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "signalrefpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "Startevents_all", "StartEventsMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "StartMessageEvent",
    "title" : "消息事件",
    "description" : "A start event with a message trigger",
    "view" : "\n\n  \n  \n  \t\n  \n  \n    \n    \n    \n    \n    \n\t\n  \n",
    "icon" : "startevent/message.png",
    "groups" : [ "启动事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "messagerefpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "Startevents_all", "StartEventsMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "StartErrorEvent",
    "title" : "异常事件",
    "description" : "A start event that catches a thrown BPMN error",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n    \n    \n    \n\t\n  \n",
    "icon" : "startevent/error.png",
    "groups" : [ "启动事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "errorrefpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "Startevents_all", "StartEventsMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "UserTask",
    "title" : "用户活动",
    "description" : "分配给特定人的任务 ",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\t\n\t\n  \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\n\t\n\t\t\n\t\n  \n",
    "icon" : "activity/list/type.user.png",
    "groups" : [ "活动列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "usertaskassignmentpackage", "formkeydefinitionpackage", "duedatedefinitionpackage", "prioritydefinitionpackage", "formpropertiespackage", "tasklistenerspackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "ServiceTask",
    "title" : "服务任务",
    "description" : "An automatic task with service logic",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\n\t\n  \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n  \n",
    "icon" : "activity/list/type.service.png",
    "groups" : [ "活动列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "servicetaskclasspackage", "servicetaskexpressionpackage", "servicetaskdelegateexpressionpackage", "servicetaskfieldspackage", "servicetaskresultvariablepackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "ScriptTask",
    "title" : "脚本任务",
    "description" : "An automatic task with script logic",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\n  \n\t\n\t\t\n\t\n\t\n\t\t\n\t\n\t\n\n\t\n\t\t\n\t\n  \n",
    "icon" : "activity/list/type.script.png",
    "groups" : [ "活动列表" ],
    "propertyPackages" : [ "scriptformatpackage", "scripttextpackage", "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "BusinessRule",
    "title" : "规则任务",
    "description" : "An automatic task with rule logic",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n  \t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n    \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n  \n",
    "icon" : "activity/list/type.business.rule.png",
    "groups" : [ "活动列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "ruletask_rulespackage", "ruletask_variables_inputpackage", "ruletask_excludepackage", "ruletask_resultpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "ReceiveTask",
    "title" : "接受任务",
    "description" : "An task that waits for a signal",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n\t\n\t\n\t\t\n\t\t\n    \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n  \n",
    "icon" : "activity/list/type.receive.png",
    "groups" : [ "活动列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "ManualTask",
    "title" : "手工任务",
    "description" : "An automatic task with no logic",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n\t\n\t\n\t\t\n\t\t\n    \n    \t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n  \n",
    "icon" : "activity/list/type.manual.png",
    "groups" : [ "活动列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "MailTask",
    "title" : "邮件任务",
    "description" : "An mail task",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n\t\n\t\n\t\t\n\t\t\n    \n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n  \n",
    "icon" : "activity/list/type.send.png",
    "groups" : [ "活动列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "mailtasktopackage", "mailtaskfrompackage", "mailtasksubjectpackage", "mailtaskccpackage", "mailtaskbccpackage", "mailtasktextpackage", "mailtaskhtmlpackage", "mailtaskcharsetpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "CamelTask",
    "title" : "Camel任务",
    "description" : "An task that sends a message to Camel",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\n  \n\t\n\t\t\n\t\n\t\n\t\t\n\t\n\t\n\n\t\n\t\t\n\t\n  \n",
    "icon" : "activity/list/type.camel.png",
    "groups" : [ "活动列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "cameltaskcamelcontextpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "MuleTask",
    "title" : "Mule任务",
    "description" : "An task that sends a message to Mule",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\n  \n\t\n\t\t\n\t\n\t\n\t\t\n\t\n\t\n\n\t\n\t\t\n\t\n  \n",
    "icon" : "activity/list/type.mule.png",
    "groups" : [ "活动列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "muletaskendpointurlpackage", "muletasklanguagepackage", "muletaskpayloadexpressionpackage", "muletaskresultvariablepackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "SendTask",
    "title" : "Send task",
    "description" : "An task that sends a message",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n\t\n\t\n\t\t\n\t\t\n    \n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n  \n",
    "icon" : "activity/list/type.send.png",
    "groups" : [ "活动列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "SubProcess",
    "title" : "子流程",
    "description" : "子流程范围",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n    \n\t\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\n\t\n\t\t\n\t\n  \n",
    "icon" : "activity/expanded.subprocess.png",
    "groups" : [ "结构列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "istransactionpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "sequence_start", "sequence_end", "all" ]
  }, {
    "type" : "node",
    "id" : "EventSubProcess",
    "title" : "事件子流程",
    "description" : "一个事件周期的子流程",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n\t\n\t\n    \t\n\t\t\n    \t\n\t\n\t\n  \n",
    "icon" : "activity/event.subprocess.png",
    "groups" : [ "结构列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "all" ]
  }, {
    "type" : "node",
    "id" : "CallActivity",
    "title" : "调用活动",
    "description" : "一个调用活动",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n\t\n    \n\t\n\t\t\n\t\t\n    \n\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\n\n\t\n\t\t\n\t\n  \n",
    "icon" : "activity/task.png",
    "groups" : [ "结构列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "callactivitycalledelementpackage", "callactivityinparameterspackage", "callactivityoutparameterspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "Activity", "sequence_start", "sequence_end", "all" ]
  }, {
    "type" : "node",
    "id" : "ExclusiveGateway",
    "title" : "互斥网关",
    "description" : "一个选择的网关",
    "view" : "\n\n  \n  \n    \n  \t\t\t\t\t\n  \n  \n    \n    \n      \n      \n    \n\t\n\t\n\t\n  \n\n",
    "icon" : "gateway/exclusive.databased.png",
    "groups" : [ "网关列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "sequencefloworderpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "GatewaysMorph", "sequence_end", "all" ]
  }, {
    "type" : "node",
    "id" : "ParallelGateway",
    "title" : "并行网关",
    "description" : "一个并行的网关",
    "view" : "\n\n   \n  \n    \n  \n  \n    \n    \n    \n\t\n\t\n  \n\n",
    "icon" : "gateway/parallel.png",
    "groups" : [ "网关列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "sequencefloworderpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "GatewaysMorph", "sequence_end", "all" ]
  }, {
    "type" : "node",
    "id" : "InclusiveGateway",
    "title" : "包容性网关",
    "description" : "一个包容性网关",
    "view" : "\n\n  \n    \n  \n  \n\n    \n    \n    \n\t\n\t\n  \n\n",
    "icon" : "gateway/inclusive.png",
    "groups" : [ "网关列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "sequencefloworderpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "GatewaysMorph", "sequence_end", "all" ]
  }, {
    "type" : "node",
    "id" : "EventGateway",
    "title" : "事件网关",
    "description" : "一个事件网关",
    "view" : "\n\n  \n    \n  \n  \n   \n  \t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\n\t\n\t\n\t\n\t\n  \t\n\t\n\n",
    "icon" : "gateway/eventbased.png",
    "groups" : [ "网关列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "sequencefloworderpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "GatewaysMorph", "sequence_end", "all" ]
  }, {
    "type" : "node",
    "id" : "BoundaryErrorEvent",
    "title" : "边界错误事件",
    "description" : "一个捕捉BPMN异常的边界事件",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n    \n    \n    \n    \n\t\n  \n",
    "icon" : "catching/error.png",
    "groups" : [ "边界事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "errorrefpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "BoundaryEventsMorph", "IntermediateEventOnActivityBoundary" ]
  }, {
    "type" : "node",
    "id" : "BoundaryTimerEvent",
    "title" : "定时边界事件",
    "description" : "一个定时触发的边界事件",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n    \n    \t\n    \n    \n    \n    \n    \n    \n    \t\n\t\n  \n",
    "icon" : "catching/timer.png",
    "groups" : [ "边界事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "timercycledefinitionpackage", "timerdatedefinitionpackage", "timerdurationdefinitionpackage", "timerenddatedefinitionpackage", "cancelactivitypackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "BoundaryEventsMorph", "IntermediateEventOnActivityBoundary" ]
  }, {
    "type" : "node",
    "id" : "BoundarySignalEvent",
    "title" : "边界信号事件",
    "description" : "一个信号触发的边界事件",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n    \n    \t\n    \n    \n    \n    \n\t\n\t\n  \n",
    "icon" : "catching/signal.png",
    "groups" : [ "边界事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "signalrefpackage", "cancelactivitypackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "BoundaryEventsMorph", "IntermediateEventOnActivityBoundary" ]
  }, {
    "type" : "node",
    "id" : "BoundaryMessageEvent",
    "title" : "边界消息事件",
    "description" : "一个边界消息事件",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n    \n    \t\n    \n    \t\n    \n    \n    \n\t\n\t\t\n\t\n\t\n\t\n  \n",
    "icon" : "catching/message.png",
    "groups" : [ "边界事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "messagerefpackage", "cancelactivitypackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "BoundaryEventsMorph", "IntermediateEventOnActivityBoundary" ]
  }, {
    "type" : "node",
    "id" : "BoundaryCancelEvent",
    "title" : "边界取消事件",
    "description" : "一个边界取消事件",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n  \n    \n    \n    \n    \n\t\n  \n",
    "icon" : "catching/cancel.png",
    "groups" : [ "边界事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "BoundaryEventsMorph", "IntermediateEventOnActivityBoundary" ]
  }, {
    "type" : "node",
    "id" : "BoundaryCompensationEvent",
    "title" : "边界修正事件",
    "description" : "一个边界修正事件",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n\t\n    \n    \n    \n    \n    \n\t\n \n",
    "icon" : "catching/compensation.png",
    "groups" : [ "边界事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "BoundaryEventsMorph", "IntermediateEventOnActivityBoundary", "all" ]
  }, {
    "type" : "node",
    "id" : "CatchTimerEvent",
    "title" : "中间定时器捕获事件",
    "description" : "定时器触发的中间捕获事件",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n    \n    \t\n    \n    \n    \n    \n    \n    \n    \t\n\t\n  \n",
    "icon" : "catching/timer.png",
    "groups" : [ "中间捕获事件列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "timercycledefinitionpackage", "timerdatedefinitionpackage", "timerdurationdefinitionpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "sequence_end", "CatchEventsMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "CatchSignalEvent",
    "title" : "中间信号捕获事件",
    "description" : "信号触发的捕获事件",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n    \n    \t\n    \n    \n    \n    \n\t\n\t\n  \n",
    "icon" : "catching/signal.png",
    "groups" : [ "中间捕获事件列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "signalrefpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "sequence_end", "CatchEventsMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "CatchMessageEvent",
    "title" : "中间消息捕获事件",
    "description" : "一个消息触发的中间捕获事件",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n    \n    \t\n    \n    \t\n    \n    \n    \n\t\n\t\t\n\t\n\t\n\t\n  \n",
    "icon" : "catching/message.png",
    "groups" : [ "中间捕获事件列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "messagerefpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "sequence_start", "sequence_end", "CatchEventsMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "ThrowNoneEvent",
    "title" : "中间抛出事件",
    "description" : "无触发器的中间抛出事件",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n  \n    \n    \n\t\n  \n",
    "icon" : "throwing/none.png",
    "groups" : [ "中间抛出事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "ThrowEventsMorph", "sequence_start", "sequence_end", "all" ]
  }, {
    "type" : "node",
    "id" : "ThrowSignalEvent",
    "title" : "信号中间抛出事件",
    "description" : "一个信号触发的中间抛出事件",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n    \n    \n    \n\t\n  \n",
    "icon" : "throwing/signal.png",
    "groups" : [ "中间抛出事件" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "signalrefpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "ThrowEventsMorph", "sequence_start", "sequence_end", "all" ]
  }, {
    "type" : "node",
    "id" : "EndNoneEvent",
    "title" : "结束任务",
    "description" : "一个无触发器的结束任务",
    "view" : "\n\n  \n  \n  \t\n  \n  \n    \n\t\n  \n",
    "icon" : "endevent/none.png",
    "groups" : [ "结束任务列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "EndEventsMorph", "sequence_end", "all" ]
  }, {
    "type" : "node",
    "id" : "EndErrorEvent",
    "title" : "结束错误任务",
    "description" : "An end event that throws an error event",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n    \n    \n    \n\t\n  \n",
    "icon" : "endevent/error.png",
    "groups" : [ "结束任务列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "errorrefpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "EndEventsMorph", "sequence_end", "all" ]
  }, {
    "type" : "node",
    "id" : "EndCancelEvent",
    "title" : "结束取消任务",
    "description" : "A cancel end event",
    "view" : "\n\n  \n  \n  \t\n  \n  \n    \n    \n    \n\t\n  \n",
    "icon" : "endevent/cancel.png",
    "groups" : [ "结束任务列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "EndEventsMorph", "sequence_end", "all" ]
  }, {
    "type" : "node",
    "id" : "EndTerminateEvent",
    "title" : "终结任务",
    "description" : "A terminate end event",
    "view" : "\n\n  \n  \n  \t\n  \n  \n    \n    \n    \n\t\n  \n",
    "icon" : "endevent/terminate.png",
    "groups" : [ "结束任务列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "executionlistenerspackage", "terminateAllpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "EndEventsMorph", "sequence_end", "all" ]
  }, {
    "type" : "node",
    "id" : "Pool",
    "title" : "池",
    "description" : "A pool to stucture the process definition",
    "view" : "\n\n  \n  \n  \t\n  \t\n  \t\n  \t\n  \t\n  \n  \n    \n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t  \t\n  \t\n    \n    \n\t\n\t\n\t\n\t\n    \n    \n  \n",
    "icon" : "swimlane/pool.png",
    "groups" : [ "泳道列表" ],
    "layout" : [ {
      "type" : "layout.bpmn2_0.pool"
    } ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "process_idpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "canContainArtifacts", "all" ]
  }, {
    "type" : "node",
    "id" : "Lane",
    "title" : "泳道",
    "description" : "A lane to stucture the process definition",
    "view" : "\n\n  \n  \n  \n     \n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n  \t\t\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n    \n\t\n  \n",
    "icon" : "swimlane/lane.png",
    "groups" : [ "泳道列表" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "PoolChild", "canContainArtifacts", "all" ]
  }, {
    "type" : "edge",
    "id" : "SequenceFlow",
    "title" : "顺序流",
    "description" : "顺序流定义活动的执行顺序",
    "view" : "\r\n\r\n\t\r\n\t  \t\r\n\t  \t\t\r\n\t\t\t\r\n\t  \t\r\n\t  \t\r\n\t  \t\t\r\n\t  \t\r\n\t\r\n\t\r\n\t\t\r\n\t\t\r\n\t\r\n",
    "icon" : "connector/sequenceflow.png",
    "groups" : [ "连接对象" ],
    "layout" : [ {
      "type" : "layout.bpmn2_0.sequenceflow"
    } ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "conditionsequenceflowpackage", "executionlistenerspackage", "defaultflowpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "ConnectingObjectsMorph", "all" ]
  }, {
    "type" : "edge",
    "id" : "MessageFlow",
    "title" : "消息流",
    "description" : "Message flow to connect elements in different pools.",
    "view" : "\r\n\r\n\t\r\n\t\t\r\n\t  \t\t\r\n\t  \t\t\r\n\t  \t\r\n\r\n\t  \t\r\n\t  \t\t\r\n\t  \t\r\n\t\r\n\t\r\n\t    \r\n\t\t\r\n\t\r\n",
    "icon" : "connector/messageflow.png",
    "groups" : [ "连接对象" ],
    "layout" : [ {
      "type" : "layout.bpmn2_0.sequenceflow"
    } ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "ConnectingObjectsMorph", "all" ]
  }, {
    "type" : "edge",
    "id" : "Association",
    "title" : "注释",
    "description" : "连接一个注释到指定元素",
    "view" : "\r\n\r\n\t\r\n\t    \r\n\t\t\r\n\t\r\n",
    "icon" : "connector/association.undirected.png",
    "groups" : [ "连接对象" ],
    "layout" : [ {
      "type" : "layout.bpmn2_0.sequenceflow"
    } ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "ConnectingObjectsMorph", "all" ]
  }, {
    "type" : "edge",
    "id" : "DataAssociation",
    "title" : "日期注释",
    "description" : "连接一个日期注释到指定元素",
    "view" : "\r\n\r\n\t\r\n\t  \t\r\n\t  \t\t\r\n\t  \t\r\n\t\r\n\t\r\n\t    \r\n\t\t\r\n\t\r\n",
    "icon" : "connector/association.unidirectional.png",
    "groups" : [ "连接对象" ],
    "layout" : [ {
      "type" : "layout.bpmn2_0.sequenceflow"
    } ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "ConnectingObjectsMorph", "all" ]
  }, {
    "type" : "node",
    "id" : "TextAnnotation",
    "title" : "文本注释",
    "description" : "连接一个文本注释到指定元素",
    "view" : "\n\n  \n  \n  \t\n  \n  \n  \n  \n    \n    \n\t\n  \n",
    "icon" : "artifact/text.annotation.png",
    "groups" : [ "加工" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "textpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "all" ]
  }, {
    "type" : "node",
    "id" : "DataStore",
    "title" : "Data store",
    "description" : "Reference to a data store.",
    "view" : "\r\n\r\n\t\r\n\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\r\n\t\r\n\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t \t\r\n\t\t\r\n\t\t\t \r\n\t\r\n\r\n",
    "icon" : "dataobject/data.store.png",
    "groups" : [ "Artifacts" ],
    "propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage" ],
    "hiddenPropertyPackages" : [ ],
    "roles" : [ "all" ]
  } ],
  "rules" : {
    "cardinalityRules" : [ {
      "role" : "Startevents_all",
      "incomingEdges" : [ {
        "role" : "SequenceFlow",
        "maximum" : 0
      } ]
    }, {
      "role" : "Endevents_all",
      "outgoingEdges" : [ {
        "role" : "SequenceFlow",
        "maximum" : 0
      } ]
    } ],
    "connectionRules" : [ {
      "role" : "SequenceFlow",
      "connects" : [ {
        "from" : "sequence_start",
        "to" : [ "sequence_end" ]
      } ]
    }, {
      "role" : "Association",
      "connects" : [ {
        "from" : "sequence_start",
        "to" : [ "TextAnnotation" ]
      }, {
        "from" : "sequence_end",
        "to" : [ "TextAnnotation" ]
      }, {
        "from" : "TextAnnotation",
        "to" : [ "sequence_end" ]
      }, {
        "from" : "BoundaryCompensationEvent",
        "to" : [ "sequence_end" ]
      }, {
        "from" : "TextAnnotation",
        "to" : [ "sequence_start" ]
      }, {
        "from" : "BoundaryCompensationEvent",
        "to" : [ "sequence_start" ]
      } ]
    }, {
      "role" : "DataAssociation",
      "connects" : [ {
        "from" : "sequence_start",
        "to" : [ "DataStore" ]
      }, {
        "from" : "sequence_end",
        "to" : [ "DataStore" ]
      }, {
        "from" : "DataStore",
        "to" : [ "sequence_end" ]
      }, {
        "from" : "DataStore",
        "to" : [ "sequence_start" ]
      } ]
    }, {
      "role" : "IntermediateEventOnActivityBoundary",
      "connects" : [ {
        "from" : "Activity",
        "to" : [ "IntermediateEventOnActivityBoundary" ]
      } ]
    } ],
    "containmentRules" : [ {
      "role" : "BPMNDiagram",
      "contains" : [ "all" ]
    }, {
      "role" : "SubProcess",
      "contains" : [ "sequence_start", "sequence_end", "from_task_event", "to_task_event", "EventSubProcess", "TextAnnotation", "DataStore" ]
    }, {
      "role" : "EventSubProcess",
      "contains" : [ "sequence_start", "sequence_end", "from_task_event", "to_task_event", "TextAnnotation", "DataStore" ]
    }, {
      "role" : "Pool",
      "contains" : [ "Lane" ]
    }, {
      "role" : "Lane",
      "contains" : [ "sequence_start", "sequence_end", "EventSubProcess", "TextAnnotation", "DataStore" ]
    } ],
    "morphingRules" : [ {
      "role" : "ActivitiesMorph",
      "baseMorphs" : [ "UserTask" ],
      "preserveBounds" : true
    }, {
      "role" : "GatewaysMorph",
      "baseMorphs" : [ "ExclusiveGateway" ]
    }, {
      "role" : "StartEventsMorph",
      "baseMorphs" : [ "StartNoneEvent" ]
    }, {
      "role" : "EndEventsMorph",
      "baseMorphs" : [ "StartNoneEvent" ]
    }, {
      "role" : "CatchEventsMorph",
      "baseMorphs" : [ "CatchTimerEvent" ]
    }, {
      "role" : "ThrowEventsMorph",
      "baseMorphs" : [ "ThrowNoneEvent" ]
    }, {
      "role" : "BoundaryEventsMorph",
      "baseMorphs" : [ "ThrowNoneEvent" ]
    }, {
      "role" : "BoundaryCompensationEvent",
      "baseMorphs" : [ "BoundaryCompensationEvent" ]
    }, {
      "role" : "TextAnnotation",
      "baseMorphs" : [ "TextAnnotation" ]
    }, {
      "role" : "DataStore",
      "baseMorphs" : [ "DataStore" ]
    } ]
  }
}

七:controller

/**
 * 工作流-模型管理
 */
@RestController
@RequestMapping("/activiti/model")
public class ActivitiModelController {
    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ActivitiModelServiceImpl activitiModelService;

    /**
     * 查询列表
     */
    @RequestMapping(value = "/page", method = RequestMethod.GET)
    public List<Model> page(@RequestParam(value = "map") String map, @PageableDefault(value = 20) Pageable pageable) {
        Map reqMap = JSON.parseObject(map, Map.class);
        List<Model> list = activitiModelService.page(reqMap, pageable);
        return list;
    }


    /**
     * 创建模型
     */
    @RequestMapping(value = "/create" , method = RequestMethod.GET)
    public void create(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Model model = activitiModelService.create();
        response.sendRedirect(request.getContextPath() + "/modeler.html?modelId=" + model.getId());
    }

    /**
     * 根据ID查询
     *
     * @param id
     * @param request
     * @param response
     */

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public void findById(@PathVariable(value = "id") String id, HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.sendRedirect(request.getContextPath() + "/modeler.html?modelId=" + id);
    }

    /**
     * 物理删除
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public Boolean del(@PathVariable(value = "id") String id) {
        repositoryService.deleteModel(id);
        return true;
    }

    /**
     * 关闭本次操作
     * @param id
     * @param response
     */
    @RequestMapping(value = "/close/{id}", method = RequestMethod.GET)
    public void close(@PathVariable(value = "id") String id, HttpServletResponse response) {
        Model model = repositoryService.getModel(id);
        if (model != null && !model.hasEditorSourceExtra()) {
            repositoryService.deleteModel(id);
        }
    }

    /**
     * 发布
     *
     * @param id
     */
    @RequestMapping(value = "/deploy/{id}", method = RequestMethod.PUT)
    public boolean deploy(@PathVariable(value = "id") String id) throws IOException {
        return activitiModelService.deploy(id);
    }
}
/**
 * Service - 工作流模板
 */
@Service
public class ActivitiModelServiceImpl {
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 分页查询
     *
     * @param reqMap
     * @param pageable
     * @return
     */
    public List<Model> page(Map reqMap, Pageable pageable) {
        ModelQuery modelQuery = repositoryService.createModelQuery().notDeployed().latestVersion().orderByLastUpdateTime().desc();
        String _likeName = (String) reqMap.get("name$like");
        String _name = (String) reqMap.get("name");
        String _id = (String) reqMap.get("id");
        String _key = (String) reqMap.get("key");

        if (StringUtils.isNoneBlank(_likeName)) {
            modelQuery.modelNameLike(_likeName);
        }

        if (StringUtils.isNoneBlank(_name)) {
            modelQuery.modelName(_name);
        }

        if (StringUtils.isNoneBlank(_id)) {
            modelQuery.modelId(_id);
        }

        if (StringUtils.isNoneBlank(_key)) {
            modelQuery.modelKey(_key);
        }

        modelQuery.modelTenantId(null);

        List<Model> models = modelQuery.listPage(pageable.getPageNumber(), pageable.getPageSize());
        return models;
    }

    /**
     * 创建模型
     *
     * @return
     */
    public Model create() throws UnsupportedEncodingException {
        //初始化一个空模型
        Model model = repositoryService.newModel();

        //设置一些默认信息
        String name = "流程-" + System.currentTimeMillis();
        String description = "";
        int revision = 1;
        String key = null;

        ObjectNode modelNode = objectMapper.createObjectNode();
        modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);
        modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
        modelNode.put(ModelDataJsonConstants.MODEL_REVISION, revision);

        model.setName(name);
        model.setKey(key);
        model.setMetaInfo(modelNode.toString());
        model.setTenantId(null);//设置租户

        repositoryService.saveModel(model);
        String id = model.getId();

        //完善ModelEditorSource
        ObjectNode editorNode = objectMapper.createObjectNode();
        editorNode.put("id", "canvas");
        editorNode.put("resourceId", "canvas");
        ObjectNode stencilSetNode = objectMapper.createObjectNode();
        stencilSetNode.put("namespace",
                "http://b3mn.org/stencilset/bpmn2.0#");
        editorNode.put("stencilset", stencilSetNode);

        repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));

        return model;
    }

    /**
     * 部署
     *
     * @param id
     * @return
     */
    @Transactional
    public boolean deploy(String id) throws IOException {
        Model modelData = repositoryService.getModel(id);
        BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
        JsonNode editor = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
        BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editor);

        //一、校验模型正确性
        //创建模型校验器工厂
        ProcessValidatorFactory processValidatorFactory = new ProcessValidatorFactory();
        //创建默认模型校验器
        ProcessValidator processValidator = processValidatorFactory.createDefaultProcessValidator();
        //加入自定义校验器
        List<ValidatorSet> validatorSets = processValidator.getValidatorSets();
        //①、模型完整性校验器
        ValidatorSet modelIntegrityValidatorSet = new ValidatorSet("验证模型完整性");
        modelIntegrityValidatorSet.addValidator(new ModelIntegrityValidator());
        validatorSets.add(modelIntegrityValidatorSet);
        Collections.reverse(validatorSets);

        //进行模型校验
        List<ValidationError> validate = processValidator.validate(bpmnModel);

        //如果校验错误集合长度大于1,则说明校验出错,遍历打印出错信息
        if (validate.size() >= 1) {
            for (ValidationError validationError : validate) {
                Assert.isTrue(false, validationError.getProblem());
            }
        }

        //二、部署
        BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
        byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel);

        String processName = modelData.getName();
        if (!StringUtils.endsWith(processName, IConstant.BPMN20)) {
            processName += IConstant.BPMN20;
        }
        Deployment deployment = repositoryService.createDeployment()
                .name(modelData.getName())
                .key(modelData.getKey())
                .addBytes(processName, bpmnBytes)
                .deploy();

        //2、保存模型部署信息
        modelData.setDeploymentId(deployment.getId());
        repositoryService.saveModel(modelData);

        //3、设置流程分类
        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).list();
        for (ProcessDefinition processDefinition : list) {
            repositoryService.setProcessDefinitionCategory(processDefinition.getId(), modelData.getCategory());
        }

        return list.size() > 0;
    }
}

源码下载

八:参考文章

  • https://www.codenong.com/cs103628022/
  • https://blog.csdn.net/shizhesx/article/details/118360564

你可能感兴趣的:(工作流在线编辑器)