一、前言
现在越来越多的公司开始使用工作流,但是却因为官方界面的问题,考虑用户不会操作,要自行设计工作流的画图界面,实现客户画图,保存启动xxx审批流程的功能,诸如钉钉的审批流程种类就有不下50种,要灵活的实现客户的需求是现在我们要解决的问题,从而产生了问题就是,不用工作流的画图界面怎么生成工作流图呢?
首先我们要知道工作流图的本质是xml,本质是xml拼接,如果是简单的功能问题,我们可以利用自定义流程来实现,就是类封装的形式,本文是博主自行设计的方法,利用type,id,value等将工作流图保存为标准的工作流xml格式。然后重点是要保存为a.bpmn20.xml这样的命名方式,对后期的使用更为方便哦。
本文真实可行,近期还测试过(2018/03/23),放心舔包,最近超迷刺激战场的。。。。。哈哈
二、
2.1 XML拼接的基本方法
/**
* Created by xuhy on 2018/1/18.
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* XML元素类
* @author xuhy
*/
public class Element {
private String name; //元素名
private String nodeText = ""; //文本值
private Map<String,String> property = new HashMap<String,String>(); //属性
private boolean isleaf = true; //是否子节点
private List<Element> child = new ArrayList<Element>(); //子节点
public Element(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNodeText() {
return nodeText;
}
public void setNodeText(String nodeText) {
this.nodeText = nodeText;
}
public Map<String, String> getProperty() {
return property;
}
public void setProperty(Map<String, String> property) {
this.property = property;
}
public boolean isIsleaf() {
return isleaf;
}
//这个方法应该屏蔽
public void setIsleaf(boolean isleaf) {
this.isleaf = isleaf;
}
public List<Element> getChild() {
return child;
}
public void setChild(List<Element> child) {
this.child = child;
if(this.isleaf && this.child.size() > 0){
this.isleaf = false;
}
}
/**
* 添加属性
* @param key
* @param value
*/
public void addProperty(String key,String value){
this.property.put(key, value);
}
/**
* 添加子节点
* @param el
*/
public void addChild(Element el){
this.child.add(el);
if(this.isleaf && this.child.size() > 0){
this.isleaf = false;
}
}
}
2.2
/**
* XMl工具类
* @author xhy
*/
public class XmlUtil {
static String lt = "<";
static String ltEnd = "</";
static String rt = ">";
static String rhtEnd = "/>";
static String quotes = "\"";
static String equal = "=";
static String blank = " ";
public static String elementToXml(Element el){
StringBuffer result = new StringBuffer();
//元素开始
result.append(lt).append(el.getName());
//判断是否有属性
if(el.getProperty() != null && el.getProperty().size() > 0 ){
Iterator iter = el.getProperty().keySet().iterator();
while (iter.hasNext()) {
String key = String.valueOf(iter.next());
String value = el.getProperty().get(key);
result.append(blank).append(key).append(equal)
.append(quotes).append(value).append(quotes).append(blank);
}
}
result.append(rt);//结束标记
/*
* 判断是否是叶子节点
* 是叶子节点,添加节点内容
* 不是叶子节点,循环添加子节点
*/
if(el.isIsleaf()){
result.append(el.getNodeText());
}else{
for(Element element :el.getChild()){
result.append(elementToXml(element));
}
}
//元素结束
result.append(ltEnd).append(el.getName()).append(rt);
return result.toString();
}
}
2.3
关于枚举类是从官方那边把所有类型数据取过来,改成枚举类的。没把我写的累死了,太多了,虽然有些用不到,但是还是放着吧。
/**
* Created by xuhy on 2018/1/19.
*/
public enum bpmnEnum {
OTHER_XMLNS(10010,"xmlns"),
PROCESS(10011,"process"),
BPMN2_NAMESPACE(10011, "http://www.omg.org/spec/BPMN/20100524/MODEL"),
XSI_NAMESPACE(10012, "http://www.w3.org/2001/XMLSchema-instance"),
XSI_PREFIX(10013, "xsi"),
SCHEMA_NAMESPACE(10014, "http://www.w3.org/2001/XMLSchema"),
XSD_PREFIX(10015, "xsd"),
TTYPE_LANGUAGE_ATTRIBUTE(10016, "typeLanguage"),
XPATH_NAMESPACE(10017, "http://www.w3.org/1999/XPath"),
EXPRESSION_LANGUAGE_ATTRIBUTE(10018, "expressionLanguage"),
PROCESS_NAMESPACE(10019, "http://www.activiti.org/test"),
TARGET_NAMESPACE_ATTRIBUTE(10010, "targetNamespace"),
ACTIVITI_EXTENSIONS_NAMESPACE(1000, "http://activiti.org/bpmn"),
ACTIVITI_EXTENSIONS_PREFIX(1001, "activiti"),
BPMNDI_NAMESPACE(1002, "http://www.omg.org/spec/BPMN/20100524/DI"),