(1).创建 BpmnXMLConverter

// 资源文件
InputStream is = UserTaskTest.class.getClassLoader().getResource("user-task.bpmn").openStream();
// 对资源文件进行wrapper
InputStreamSource inputStreamProvider = new InputStreamSource(is);
// 创建BpmnXMLConverter对象
BpmnXMLConverter converter = new BpmnXMLConverter();
// 解析InputStream转换成:BpmnModel
BpmnModel model = converter.convertToBpmnModel(inputStreamProvider, true, false, "UTF-8");

(2).BpmnXMLConverter 源码

public class BpmnXMLConverter implements BpmnXMLConstants {
    // field
    // 实例化一系列元素解析器
    
    // key   : xml中的节点,比如:startEvent
    // value : 对应的处理器
    protected static Map<String, BaseBpmnXMLConverter> convertersToBpmnMap = new HashMap<String, BaseBpmnXMLConverter>(); 
    
    // key   : 解析xml节点之后,对应的载体(实体)
   // value :
    protected static Map<Class<? extends BaseElement>, BaseBpmnXMLConverter> convertersToXMLMap = new HashMap<Class<? extends BaseElement>, BaseBpmnXMLConverter>();

    //元素解析器添加过程
    static {
    // events
    addConverter(new EndEventXMLConverter());
    addConverter(new StartEventXMLConverter());

    // tasks
    addConverter(new BusinessRuleTaskXMLConverter());
    addConverter(new ManualTaskXMLConverter());
    addConverter(new ReceiveTaskXMLConverter());
    addConverter(new ScriptTaskXMLConverter());
    addConverter(new ServiceTaskXMLConverter());
    addConverter(new SendTaskXMLConverter());
    addConverter(new UserTaskXMLConverter());
    addConverter(new TaskXMLConverter());
    addConverter(new CallActivityXMLConverter());

    // gateways
    addConverter(new EventGatewayXMLConverter());
    addConverter(new ExclusiveGatewayXMLConverter());
    addConverter(new InclusiveGatewayXMLConverter());
    addConverter(new ParallelGatewayXMLConverter());
    addConverter(new ComplexGatewayXMLConverter());

    // connectors
    addConverter(new SequenceFlowXMLConverter());

    // catch, throw and boundary event
    addConverter(new CatchEventXMLConverter());
    addConverter(new ThrowEventXMLConverter());
    addConverter(new BoundaryEventXMLConverter());

    // artifacts
    addConverter(new TextAnnotationXMLConverter());
    addConverter(new AssociationXMLConverter());

    // data store reference
    addConverter(new DataStoreReferenceXMLConverter());


    // data objects
    // ValuedDataObjectXMLConverter 负责解析dataObject元素
    addConverter(new ValuedDataObjectXMLConverter(), StringDataObject.class);
    addConverter(new ValuedDataObjectXMLConverter(), BooleanDataObject.class);
    addConverter(new ValuedDataObjectXMLConverter(), IntegerDataObject.class);
    addConverter(new ValuedDataObjectXMLConverter(), LongDataObject.class);
    addConverter(new ValuedDataObjectXMLConverter(), DoubleDataObject.class);
    addConverter(new ValuedDataObjectXMLConverter(), DateDataObject.class);

    // Alfresco types
    addConverter(new AlfrescoStartEventXMLConverter());
    addConverter(new AlfrescoUserTaskXMLConverter());
  } //end static

  // 添加转换器
  public static void addConverter(BaseBpmnXMLConverter converter) {
    // converter.getBpmnElementType() == entity
    addConverter(converter, converter.getBpmnElementType());
  }
  
  // 添加转换器
  public static void addConverter(BaseBpmnXMLConverter converter, Class<? extends BaseElement> elementType) {
    // converter.getXMLElementName() == xml节点
    convertersToBpmnMap.put(converter.getXMLElementName(), converter);
    convertersToXMLMap.put(elementType, converter);
  }
  
  
}

(3).BpmnXMLConverter.convertToBpmnModel

public BpmnModel convertToBpmnModel(InputStreamProvider inputStreamProvider, boolean validateSchema, boolean enableSafeBpmnXml, String encoding) {
    XMLInputFactory xif = XMLInputFactory.newInstance();
    if (xif.isPropertySupported(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES)) {
      xif.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
    }
    if (xif.isPropertySupported(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES)) {
      xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
    }
    if (xif.isPropertySupported(XMLInputFactory.SUPPORT_DTD)) {
      xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
    }
    InputStreamReader in = null;
    try {
      in = new InputStreamReader(inputStreamProvider.getInputStream(), encoding);
      XMLStreamReader xtr = xif.createXMLStreamReader(in);

      try {
        if (validateSchema) {
          if (!enableSafeBpmnXml) {
            validateModel(inputStreamProvider);
          } else {
            validateModel(xtr);
          }

          // The input stream is closed after schema validation
          in = new InputStreamReader(inputStreamProvider.getInputStream(), encoding);
          xtr = xif.createXMLStreamReader(in);
        } //end if
      } catch (Exception e) {
        throw new XMLException(e.getMessage(), e);
      }
      // ********************************************************************
      // XML conversion
      // 读取XML并转换
      // ********************************************************************
      return convertToBpmnModel(xtr);
    } catch (UnsupportedEncodingException e) {
      throw new XMLException("The bpmn 2.0 xml is not UTF8 encoded", e);
    } catch (XMLStreamException e) {
      throw new XMLException("Error while reading the BPMN 2.0 XML", e);
    } finally {
      if (in != null) {
        try {
          in.close();
        } catch (IOException e) {
          LOGGER.debug("Problem closing BPMN input stream", e);
        }
      }
    }
  }

(4).BpmnXMLConverter.convertToBpmnModel

public BpmnModel convertToBpmnModel(XMLStreamReader xtr) {
    // 创建返回后的结果集
    BpmnModel model = new BpmnModel();
    model.setStartEventFormTypes(startEventFormTypes);
    model.setUserTaskFormTypes(userTaskFormTypes);
    try {
      Process activeProcess = null;
      List<SubProcess> activeSubProcessList = new ArrayList<SubProcess>();
      while (xtr.hasNext()) {
        try {
          xtr.next();
        } catch (Exception e) {
          LOGGER.debug("Error reading XML document", e);
          throw new XMLException("Error reading XML", e);
        }

        if (xtr.isEndElement() && (ELEMENT_SUBPROCESS.equals(xtr.getLocalName()) || 
            ELEMENT_TRANSACTION.equals(xtr.getLocalName()) ||
            ELEMENT_ADHOC_SUBPROCESS.equals(xtr.getLocalName()))) {          
          activeSubProcessList.remove(activeSubProcessList.size() - 1);
        }
        
        if (xtr.isStartElement() == false) {
            // 如果不是开始节点,则跳过这个节点
          continue;
        }
        
       if (ELEMENT_DEFINITIONS.equals(xtr.getLocalName())) { // <definitions>
            // **********************************************************
            definitionsParser.parse(xtr, model);		  
            // **********************************************************
        } else if (ELEMENT_RESOURCE.equals(xtr.getLocalName())) { // <resource>
            resourceParser.parse(xtr, model);          
        } else if (ELEMENT_SIGNAL.equals(xtr.getLocalName())) {  // <signal>
            signalParser.parse(xtr, model);			
        } else if (ELEMENT_MESSAGE.equals(xtr.getLocalName())) { // <message>
            messageParser.parse(xtr, model);
        } else if (ELEMENT_ERROR.equals(xtr.getLocalName())) {   // <error>
           if (StringUtils.isNotEmpty(xtr.getAttributeValue(null, ATTRIBUTE_ID))) {
               model.addError(xtr.getAttributeValue(null, ATTRIBUTE_ID), xtr.getAttributeValue(null, ATTRIBUTE_ERROR_CODE));
           }
        } else if (ELEMENT_IMPORT.equals(xtr.getLocalName())) {  // <import>
              importParser.parse(xtr, model);
        } else if (ELEMENT_ITEM_DEFINITION.equals(xtr.getLocalName())) {  // <itemDefinition>
              itemDefinitionParser.parse(xtr, model);
        } else if (ELEMENT_DATA_STORE.equals(xtr.getLocalName())) {   // <dataStore>
              dataStoreParser.parse(xtr, model);
        } else if (ELEMENT_INTERFACE.equals(xtr.getLocalName())) {   // <interface>
              interfaceParser.parse(xtr, model);
        } else if (ELEMENT_IOSPECIFICATION.equals(xtr.getLocalName())) {  // <ioSpecification>
              ioSpecificationParser.parseChildElement(xtr, activeProcess, model);
        } else if (ELEMENT_PARTICIPANT.equals(xtr.getLocalName())) {   // <participant>
              participantParser.parse(xtr, model);
        } else if (ELEMENT_MESSAGE_FLOW.equals(xtr.getLocalName())) {   // <messageFlow>
              messageFlowParser.parse(xtr, model);
        } else if (ELEMENT_PROCESS.equals(xtr.getLocalName())) {   // <process>
              Process process = processParser.parse(xtr, model);
              if (process != null) {
                activeProcess = process;
              }
        } else if (ELEMENT_POTENTIAL_STARTER.equals(xtr.getLocalName())) {  // <potentialStarter>
              potentialStarterParser.parse(xtr, activeProcess);
        } else if (ELEMENT_LANE.equals(xtr.getLocalName())) {   // <lane>
              laneParser.parse(xtr, activeProcess, model);
        } else if (ELEMENT_DOCUMENTATION.equals(xtr.getLocalName())) {  //<documentation>
              BaseElement parentElement = null;
              if (!activeSubProcessList.isEmpty()) {
                parentElement = activeSubProcessList.get(activeSubProcessList.size() - 1);
              } else if (activeProcess != null) {
                parentElement = activeProcess;
              }
              documentationParser.parseChildElement(xtr, parentElement, model);
        } else if (activeProcess == null && ELEMENT_TEXT_ANNOTATION.equals(xtr.getLocalName())) {  // <textAnnotation>
              String elementId = xtr.getAttributeValue(null, ATTRIBUTE_ID);
              TextAnnotation textAnnotation = (TextAnnotation) new TextAnnotationXMLConverter().convertXMLToElement(xtr, model);
              textAnnotation.setId(elementId);
              model.getGlobalArtifacts().add(textAnnotation);
        } else if (activeProcess == null && ELEMENT_ASSOCIATION.equals(xtr.getLocalName())) {  // <association>
              String elementId = xtr.getAttributeValue(null, ATTRIBUTE_ID);
              Association association = (Association) new AssociationXMLConverter().convertXMLToElement(xtr, model);
              association.setId(elementId);
              model.getGlobalArtifacts().add(association);
        } else if (ELEMENT_EXTENSIONS.equals(xtr.getLocalName())) {   // <extensionElements>
              extensionElementsParser.parse(xtr, activeSubProcessList, activeProcess, model);
        } else if (ELEMENT_SUBPROCESS.equals(xtr.getLocalName()) || ELEMENT_TRANSACTION.equals(xtr.getLocalName()) || ELEMENT_ADHOC_SUBPROCESS.equals(xtr.getLocalName())) {  // <subProcess>/transaction
              subProcessParser.parse(xtr, activeSubProcessList, activeProcess);       
        } else if (ELEMENT_COMPLETION_CONDITION.equals(xtr.getLocalName())) {   // <completionCondition>
              if (!activeSubProcessList.isEmpty()) {
                SubProcess subProcess = activeSubProcessList.get(activeSubProcessList.size() - 1);
                if (subProcess instanceof AdhocSubProcess) {
                  AdhocSubProcess adhocSubProcess = (AdhocSubProcess) subProcess;
                  adhocSubProcess.setCompletionCondition(xtr.getElementText());
                } //end if
              } // end if
        } else if (ELEMENT_DI_SHAPE.equals(xtr.getLocalName())) {  //<BPMNShape>
              bpmnShapeParser.parse(xtr, model);
        } else if (ELEMENT_DI_EDGE.equals(xtr.getLocalName())) {  // BPMNEdge
              bpmnEdgeParser.parse(xtr, model);
        } else {
              if (!activeSubProcessList.isEmpty() && ELEMENT_MULTIINSTANCE.equalsIgnoreCase(xtr.getLocalName())) {  //<multiInstanceLoopCharacteristics>
                multiInstanceParser.parseChildElement(xtr, activeSubProcessList.get(activeSubProcessList.size() - 1), model);
              } else if (convertersToBpmnMap.containsKey(xtr.getLocalName())) {   // 预留给业务的处理
                if (activeProcess != null) {
                  //  ****************************************************************
                  BaseBpmnXMLConverter converter = convertersToBpmnMap.get(xtr.getLocalName());
                  converter.convertToBpmnModel(xtr, model, activeProcess, activeSubProcessList);
                }
             } //end else if
        } //end else
      } //end while

      // 处理所有的Processes
      for (Process process : model.getProcesses()) {
        for (Pool pool : model.getPools()) {
          if (process.getId().equals(pool.getProcessRef())) {
            pool.setExecutable(process.isExecutable());
          }
        }
        processFlowElements(process.getFlowElements(), process);
      }
    } catch (XMLException e) {
      throw e;
    } catch (Exception e) {
      LOGGER.error("Error processing BPMN document", e);
      throw new XMLException("Error processing BPMN document", e);
    }
    return model;
}

(5).解析

public class DefinitionsParser implements BpmnXMLConstants {
  // 默认的属性列表
  protected static final List<ExtensionAttribute> defaultAttributes = 
    Arrays.asList(
        new ExtensionAttribute(TYPE_LANGUAGE_ATTRIBUTE), 
        new ExtensionAttribute(EXPRESSION_LANGUAGE_ATTRIBUTE),
        new ExtensionAttribute(TARGET_NAMESPACE_ATTRIBUTE)
   );

  @SuppressWarnings("unchecked")
  public void parse(XMLStreamReader xtr, BpmnModel model) throws Exception {
    // <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"></definitions>
    // 解析属性:targetNamespace,并设置到实例上
    model.setTargetNamespace(xtr.getAttributeValue(null, TARGET_NAMESPACE_ATTRIBUTE));
    // 解析namespace的数量
    for (int i = 0; i < xtr.getNamespaceCount(); i++) {
      String prefix = xtr.getNamespacePrefix(i);
      if (StringUtils.isNotEmpty(prefix)) {
        model.addNamespace(prefix, xtr.getNamespaceURI(i));
      }
    }

    // 解析:属性数量
    for (int i = 0; i < xtr.getAttributeCount(); i++) {
      ExtensionAttribute extensionAttribute = new ExtensionAttribute();
      extensionAttribute.setName(xtr.getAttributeLocalName(i));
      extensionAttribute.setValue(xtr.getAttributeValue(i));
      if (StringUtils.isNotEmpty(xtr.getAttributeNamespace(i))) {
        extensionAttribute.setNamespace(xtr.getAttributeNamespace(i));
      }
      if (StringUtils.isNotEmpty(xtr.getAttributePrefix(i))) {
        extensionAttribute.setNamespacePrefix(xtr.getAttributePrefix(i));
      }
      // 属性不在默认列表之内,则添加到实体里
      if (!BpmnXMLUtil.isBlacklisted(extensionAttribute, defaultAttributes)) {
        model.addDefinitionsAttribute(extensionAttribute);
      }
    }
  } //end parse
  
}

(6).解析

/**
*  <process id="process1" name="My process" isExecutable="true">
*    ... ...
*  </process>  
*/
public class ProcessParser implements BpmnXMLConstants {
    
    public Process parse(XMLStreamReader xtr, BpmnModel model) throws Exception {
        Process process = null;
        if (StringUtils.isNotEmpty(xtr.getAttributeValue(null, ATTRIBUTE_ID))) {
          // 解析id="process1"
          String processId = xtr.getAttributeValue(null, ATTRIBUTE_ID);
          process = new Process();
          process.setId(processId);
          // XML中位置
          BpmnXMLUtil.addXMLLocation(process, xtr);
          // 解析name="My process"
          process.setName(xtr.getAttributeValue(null, ATTRIBUTE_NAME));
          // 解析isExecutable="true"
          if (StringUtils.isNotEmpty(xtr.getAttributeValue(null, ATTRIBUTE_PROCESS_EXECUTABLE))) {
            process.setExecutable(Boolean.parseBoolean(xtr.getAttributeValue(null, ATTRIBUTE_PROCESS_EXECUTABLE)));
          }
          // 解析candidateStarterUsers="${zhangsan,lishi}"
          String candidateUsersString = xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_PROCESS_CANDIDATE_USERS);
          if (StringUtils.isNotEmpty(candidateUsersString)) {
            //
            List<String> candidateUsers = BpmnXMLUtil.parseDelimitedList(candidateUsersString);
            process.setCandidateStarterUsers(candidateUsers);
          }
          // 解析candidateStarterGroups="${group1}"
          String candidateGroupsString = xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_PROCESS_CANDIDATE_GROUPS);
          if (StringUtils.isNotEmpty(candidateGroupsString)) {
            List<String> candidateGroups = BpmnXMLUtil.parseDelimitedList(candidateGroupsString);
            process.setCandidateStarterGroups(candidateGroups);
          }
          // 解析自定义的属性 
          BpmnXMLUtil.addCustomAttributes(xtr, process, ProcessExport.defaultProcessAttributes);
          // 添加解析的process到实体中
          // 证明一个模型中允许存中多个<process>
          model.getProcesses().add(process);
        }
        return process;
  } //end parse
    
}

(7).解析

/**
*  <userTask id="usertask1" name="任务节点1" activiti:assignee="lixin" activiti:author="Hello World!!!">
*  </userTask>
*/
public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants {
  protected static final List<ExtensionAttribute> defaultElementAttributes = 
     Arrays.asList(
         new ExtensionAttribute(ATTRIBUTE_ID), 
         new ExtensionAttribute(ATTRIBUTE_NAME)
     );

  protected static final List<ExtensionAttribute> defaultActivityAttributes = 
    Arrays.asList(
        new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_ACTIVITY_ASYNCHRONOUS),
        new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_ACTIVITY_EXCLUSIVE), 
        new ExtensionAttribute(ATTRIBUTE_DEFAULT), 
        new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE,ATTRIBUTE_ACTIVITY_ISFORCOMPENSATION)
  );
  
  public void convertToBpmnModel(XMLStreamReader xtr, BpmnModel model, Process activeProcess, List<SubProcess> activeSubProcessList) throws Exception {
      
    // 解析:id
    String elementId = xtr.getAttributeValue(null, ATTRIBUTE_ID);
    // 解析:name
    String elementName = xtr.getAttributeValue(null, ATTRIBUTE_NAME);
    // 解析:async
    boolean async = parseAsync(xtr);
    // 解析:exclusive
    boolean notExclusive = parseNotExclusive(xtr);
    // 解析:default
    String defaultFlow = xtr.getAttributeValue(null, ATTRIBUTE_DEFAULT);
    // 解析:isForCompensation
    boolean isForCompensation = parseForCompensation(xtr);
    // 交给子类去实现(UserTaskXMLConverter)
    BaseElement parsedElement = convertXMLToElement(xtr, model);
    
    // 当节点是:Artifact的处理
    if (parsedElement instanceof Artifact) {
      Artifact currentArtifact = (Artifact) parsedElement;
      currentArtifact.setId(elementId);
      if (!activeSubProcessList.isEmpty()) {
        activeSubProcessList.get(activeSubProcessList.size() - 1).addArtifact(currentArtifact);

      } else {
        activeProcess.addArtifact(currentArtifact);
      }
    }

    // 当节点是:FlowElement处理(userTask继承于:FlowElement)
    // 证明: 
    // FlowElement包含有的子类有:FlowNode/FlowNode/Activity/Gateway/DataObject
    // FlowNode包含有的子类有:Activity/Gateway
    if (parsedElement instanceof FlowElement) {
      FlowElement currentFlowElement = (FlowElement) parsedElement;
      currentFlowElement.setId(elementId);
      currentFlowElement.setName(elementName);
      
      if (currentFlowElement instanceof FlowNode) {  //流程节点处理
        FlowNode flowNode = (FlowNode) currentFlowElement;
        flowNode.setAsynchronous(async);
        flowNode.setNotExclusive(notExclusive);
        
        // 活动节点处理
        if (currentFlowElement instanceof Activity) {
          Activity activity = (Activity) currentFlowElement;
          activity.setForCompensation(isForCompensation);
          if (StringUtils.isNotEmpty(defaultFlow)) {
            activity.setDefaultFlow(defaultFlow);
          }
        }
        
        // 网关处理
        if (currentFlowElement instanceof Gateway) {
          Gateway gateway = (Gateway) currentFlowElement;
          if (StringUtils.isNotEmpty(defaultFlow)) {
            gateway.setDefaultFlow(defaultFlow);
          }
        }
      }
      
      // 数据节点处理
      if (currentFlowElement instanceof DataObject) {
        if (!activeSubProcessList.isEmpty()) {
          SubProcess subProcess = activeSubProcessList.get(activeSubProcessList.size() - 1);
          subProcess.getDataObjects().add((ValuedDataObject) parsedElement);
        } else {
          activeProcess.getDataObjects().add((ValuedDataObject) parsedElement);
        }
      }

      if (!activeSubProcessList.isEmpty()) {
        SubProcess subProcess = activeSubProcessList.get(activeSubProcessList.size() - 1);
        subProcess.addFlowElement(currentFlowElement);
      } else {
        activeProcess.addFlowElement(currentFlowElement);
      }
    }  // end if (parsedElement instanceof FlowElement) 
      
  } //end convertToBpmnModel
  
  
}

(8).UserTaskXMLConverter

public class UserTaskXMLConverter extends BaseBpmnXMLConverter {
    protected Map<String, BaseChildElementParser> childParserMap = new HashMap<String, BaseChildElementParser>();
    
    protected static final List<ExtensionAttribute> defaultUserTaskAttributes = 
      Arrays.asList(
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_FORM_FORMKEY), 
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_DUEDATE), 
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_BUSINESS_CALENDAR_NAME),
          new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_ASSIGNEE), 
         new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_OWNER), 
         new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_PRIORITY), 
         new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATEUSERS), 
         new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATEGROUPS),
         new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CATEGORY),
         new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_EXTENSIONID),
         new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_SKIP_EXPRESSION)
  );
  
  public UserTaskXMLConverter() {
    HumanPerformerParser humanPerformerParser = new HumanPerformerParser();
    childParserMap.put(humanPerformerParser.getElementName(), humanPerformerParser);
    PotentialOwnerParser potentialOwnerParser = new PotentialOwnerParser();
    childParserMap.put(potentialOwnerParser.getElementName(), potentialOwnerParser);
    CustomIdentityLinkParser customIdentityLinkParser = new CustomIdentityLinkParser();
    childParserMap.put(customIdentityLinkParser.getElementName(), customIdentityLinkParser);
  }
  
  // 转换xml到Element
  protected BaseElement convertXMLToElement(XMLStreamReader xtr, BpmnModel model) throws Exception {
    // 解析:formKey
    String formKey = xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_FORM_FORMKEY);
    
    UserTask userTask = null;
    if (StringUtils.isNotEmpty(formKey)) {
      if (model.getUserTaskFormTypes() != null 
         && model.getUserTaskFormTypes().contains(formKey)) {
        //
        userTask = new AlfrescoUserTask();
      }
    }
    
    if (userTask == null) {
      // 创建UserTask
      userTask = new UserTask();
    }
    // 设置usertask的位置
    BpmnXMLUtil.addXMLLocation(userTask, xtr);
    // 解析:dueDate
    userTask.setDueDate(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_DUEDATE));
    // 解析:businessCalendarName
    userTask.setBusinessCalendarName(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_BUSINESS_CALENDAR_NAME));
    // 解析:category
    userTask.setCategory(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CATEGORY));
    // 设置forKey
    userTask.setFormKey(formKey);
    // 解析:assignee
    userTask.setAssignee(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_ASSIGNEE)); 
    // 解析:owner
    userTask.setOwner(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_OWNER));
    // 解析:priority
    userTask.setPriority(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_PRIORITY));
    
    // 解析:candidateUsers
    if (StringUtils.isNotEmpty(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATEUSERS))) {
      String expression = xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATEUSERS);
      userTask.getCandidateUsers().addAll(parseDelimitedList(expression));
    } 
    
    // 解析:candidateGroups
    if (StringUtils.isNotEmpty(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATEGROUPS))) {
      String expression = xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATEGROUPS);
      userTask.getCandidateGroups().addAll(parseDelimitedList(expression));
    }
    
    // 解析:extensionId
    userTask.setExtensionId(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_EXTENSIONID));
    // 解析:skipExpression
    if (StringUtils.isNotEmpty(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_SKIP_EXPRESSION))) {
      String expression = xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_SKIP_EXPRESSION);
      userTask.setSkipExpression(expression);
    }

    // 解析自定义的信息(activiti:author="Hello World!!!")
    BpmnXMLUtil.addCustomAttributes(xtr, userTask, defaultElementAttributes, 
        defaultActivityAttributes, defaultUserTaskAttributes);

    // 解析子节点
    parseChildElements(getXMLElementName(), userTask, childParserMap, model, xtr);
    return userTask;
  } //end convertXMLToElement
    
}

(9).解析

/**
* <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1">
* </sequenceFlow>
*/

public class SequenceFlowXMLConverter extends BaseBpmnXMLConverter {
    protected BaseElement convertXMLToElement(XMLStreamReader xtr, BpmnModel model) throws Exception {
        SequenceFlow sequenceFlow = new SequenceFlow();
        BpmnXMLUtil.addXMLLocation(sequenceFlow, xtr);
        // sourceRef
        sequenceFlow.setSourceRef(xtr.getAttributeValue(null, ATTRIBUTE_FLOW_SOURCE_REF));
        // targetRef
        sequenceFlow.setTargetRef(xtr.getAttributeValue(null, ATTRIBUTE_FLOW_TARGET_REF));
        // name
        sequenceFlow.setName(xtr.getAttributeValue(null, ATTRIBUTE_NAME));
        // skipExpression
        sequenceFlow.setSkipExpression(xtr.getAttributeValue(null, ATTRIBUTE_FLOW_SKIP_EXPRESSION));
        // 解析子节点
        parseChildElements(getXMLElementName(), sequenceFlow, model, xtr);
        return sequenceFlow;
  } //end convertXMLToElement
  
}

(10).通用子节点解析(BpmnXMLUtil)

这里所说的通用子节点解析是指:

public class BpmnXMLUtil implements BpmnXMLConstants {
    private static Map<String, BaseChildElementParser> genericChildParserMap = 
                                new HashMap<String, BaseChildElementParser>();
    // 定义通用解析
    static {
        addGenericParser(new ActivitiEventListenerParser());
        addGenericParser(new CancelEventDefinitionParser());
        addGenericParser(new CompensateEventDefinitionParser());
        addGenericParser(new ConditionExpressionParser());
        addGenericParser(new DataInputAssociationParser());
        addGenericParser(new DataOutputAssociationParser());
        addGenericParser(new DataStateParser());
        addGenericParser(new DocumentationParser());
        addGenericParser(new ErrorEventDefinitionParser());
        addGenericParser(new ExecutionListenerParser());
        addGenericParser(new FieldExtensionParser());
        addGenericParser(new FormPropertyParser());
        addGenericParser(new IOSpecificationParser());
        addGenericParser(new MessageEventDefinitionParser());
        addGenericParser(new MultiInstanceParser());
        addGenericParser(new SignalEventDefinitionParser());
        addGenericParser(new TaskListenerParser());
        addGenericParser(new TerminateEventDefinitionParser());
        addGenericParser(new TimerEventDefinitionParser());
        addGenericParser(new TimeDateParser());
        addGenericParser(new TimeCycleParser());
        addGenericParser(new TimeDurationParser());
        addGenericParser(new FlowNodeRefParser());
        addGenericParser(new ActivitiFailedjobRetryParser());
        addGenericParser(new ActivitiMapExceptionParser());
  } // end static                                

}

(11).SequenceFlowXMLConverter 解析子节点

public class SequenceFlowXMLConverter extends BaseBpmnXMLConverter {
    protected BaseElement convertXMLToElement(XMLStreamReader xtr, BpmnModel model) throws Exception {
        // .... ...
        // *******************************************
        // 解析子节点
        parseChildElements(getXMLElementName(), sequenceFlow, model, xtr);
        // .... ...
        return sequenceFlow;
      } // end convertXMLToElement
}

(12).BaseBpmnXMLConverter 解析子节点

public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants {
    // 解析子节点
    protected void parseChildElements(String elementName, BaseElement parentElement, BpmnModel model, XMLStreamReader xtr) throws Exception {
        parseChildElements(elementName, parentElement, null, model, xtr);
    } //end parseChildElements
    
    // 解析子节点,并传入扩展的:BaseChildElementParser集合
    protected void parseChildElements(String elementName, BaseElement parentElement, Map<String, BaseChildElementParser> additionalParsers, BpmnModel model, XMLStreamReader xtr) throws Exception {
        Map<String, BaseChildElementParser> childParsers = new HashMap<String, BaseChildElementParser>();
        if (additionalParsers != null) {
          childParsers.putAll(additionalParsers);
        }
        // ******************************************8
        // 解析子节点
        BpmnXMLUtil.parseChildElements(elementName, parentElement, xtr, childParsers, model);
  } //end parseChildElements
}

(13).BpmnXMLUtil.parseChildElements

public class BpmnXMLUtil implements BpmnXMLConstants {
    // ... ...
    
    // 解析子节点
    public static void parseChildElements(
        String elementName, 
        BaseElement parentElement, 
        XMLStreamReader xtr, 
        Map<String, BaseChildElementParser> childParsers, 
        BpmnModel model
     ) throws Exception {
         
    // genericChildParserMap 为系统默认的解析器
    Map<String, BaseChildElementParser> localParserMap =
        new HashMap<String, BaseChildElementParser>(genericChildParserMap);
    if (childParsers != null) {
      // 添加(覆盖) BaseChildElementParser
      localParserMap.putAll(childParsers);
    }
    boolean inExtensionElements = false;
    boolean readyWithChildElements = false;
    while (readyWithChildElements == false && xtr.hasNext()) {
      xtr.next();
      if (xtr.isStartElement()) {
        if (ELEMENT_EXTENSIONS.equals(xtr.getLocalName())) {
          inExtensionElements = true;
        } else if (localParserMap.containsKey(xtr.getLocalName())) {
          BaseChildElementParser childParser = localParserMap.get(xtr.getLocalName());
          if (inExtensionElements && !childParser.accepts(parentElement)) {
            //  解析:ExtensionElement
            ExtensionElement extensionElement = BpmnXMLUtil.parseExtensionElement(xtr);
            parentElement.addExtensionElement(extensionElement);
            continue;
          }
          
          localParserMap.get(xtr.getLocalName()).parseChildElement(xtr, parentElement, model);
        } else if (inExtensionElements) {
          ExtensionElement extensionElement = BpmnXMLUtil.parseExtensionElement(xtr);
          parentElement.addExtensionElement(extensionElement);
        }
      } else if (xtr.isEndElement()) {
        if (ELEMENT_EXTENSIONS.equals(xtr.getLocalName())) {
          inExtensionElements = false;
        } else if (elementName.equalsIgnoreCase(xtr.getLocalName())) {
          readyWithChildElements = true;
        }
      }
    }
  } //end parseChildElements
    
}

(14).扩展节点解析案例

<process id="process1" name="My process" isExecutable="true" xmlns:activiti="http://activiti.org/bpmn" activiti:author="lixin">
  	<extensionElements>
        <activiti:field name="name" stringValue="lixin"/>
	</extensionElements>
</process> 

(15).BpmnXMLConverter

public class BpmnXMLConverter implements BpmnXMLConstants {
    // 扩展元素解析
    protected ExtensionElementsParser extensionElementsParser = new ExtensionElementsParser();
    
    public BpmnModel convertToBpmnModel(XMLStreamReader xtr) {
        // ...
        } else if (ELEMENT_EXTENSIONS.equals(xtr.getLocalName())) {
            // *****************************
            extensionElementsParser.parse(xtr, activeSubProcessList, activeProcess, model);
        } 
        // ...
    }
}

(16).ExtensionElementsParser

public class ExtensionElementsParser implements BpmnXMLConstants {
    public void parse(XMLStreamReader xtr, List<SubProcess> activeSubProcessList, Process activeProcess, BpmnModel model) throws Exception {
    BaseElement parentElement = null;
    if (!activeSubProcessList.isEmpty()) {
      parentElement = activeSubProcessList.get(activeSubProcessList.size() - 1);

    } else {
      parentElement = activeProcess;
    }

    boolean readyWithChildElements = false;
    while (readyWithChildElements == false && xtr.hasNext()) {
      xtr.next();
      if (xtr.isStartElement()) {
        if (ELEMENT_EXECUTION_LISTENER.equals(xtr.getLocalName())) { // executionListener
          new ExecutionListenerParser().parseChildElement(xtr, parentElement, model);
        } else if (ELEMENT_EVENT_LISTENER.equals(xtr.getLocalName())) {  // eventListener
          new ActivitiEventListenerParser().parseChildElement(xtr, parentElement, model);
        } else if (ELEMENT_POTENTIAL_STARTER.equals(xtr.getLocalName())) { // potentialStarter
          new PotentialStarterParser().parse(xtr, activeProcess);
        } else {
          // extensionElements
          ExtensionElement extensionElement = BpmnXMLUtil.parseExtensionElement(xtr);
          parentElement.addExtensionElement(extensionElement);
        }

      } else if (xtr.isEndElement()) {
        if (ELEMENT_EXTENSIONS.equals(xtr.getLocalName())) {
          readyWithChildElements = true;
        }
      }
    }
  } // end parse
}