public static void writeMultiInstance(Activity activity, XMLStreamWriter xtw) throws Exception {
    if (activity.getLoopCharacteristics() != null) {
      MultiInstanceLoopCharacteristics multiInstanceObject = activity.getLoopCharacteristics();
      if (StringUtils.isNotEmpty(multiInstanceObject.getLoopCardinality())
          || StringUtils.isNotEmpty(multiInstanceObject.getInputDataItem())
          || StringUtils.isNotEmpty(multiInstanceObject.getCompletionCondition())) {

        xtw.writeStartElement(ELEMENT_MULTIINSTANCE);
        BpmnXMLUtil.writeDefaultAttribute(
            ATTRIBUTE_MULTIINSTANCE_SEQUENTIAL,
            String.valueOf(multiInstanceObject.isSequential()).toLowerCase(),
            xtw);
        if (StringUtils.isNotEmpty(multiInstanceObject.getInputDataItem())) {
          BpmnXMLUtil.writeQualifiedAttribute(
              ATTRIBUTE_MULTIINSTANCE_COLLECTION, multiInstanceObject.getInputDataItem(), xtw);
        }
        if (StringUtils.isNotEmpty(multiInstanceObject.getElementVariable())) {
          BpmnXMLUtil.writeQualifiedAttribute(
              ATTRIBUTE_MULTIINSTANCE_VARIABLE, multiInstanceObject.getElementVariable(), xtw);
        }
        if (StringUtils.isNotEmpty(multiInstanceObject.getLoopCardinality())) {
          xtw.writeStartElement(ELEMENT_MULTIINSTANCE_CARDINALITY);
          xtw.writeCharacters(multiInstanceObject.getLoopCardinality());
          xtw.writeEndElement();
        }
        if (StringUtils.isNotEmpty(multiInstanceObject.getCompletionCondition())) {
          xtw.writeStartElement(ELEMENT_MULTIINSTANCE_CONDITION);
          xtw.writeCharacters(multiInstanceObject.getCompletionCondition());
          xtw.writeEndElement();
        }
        xtw.writeEndElement();
      }
    }
  }
 private static void writeDataPath(DataPath path, XMLStreamWriter xtw) throws Exception {
   xtw.writeStartElement(ELEMENT_DATA_PATH);
   BpmnXMLUtil.writeDefaultAttribute(ATTRIBUTE_ID, path.getId(), xtw);
   BpmnXMLUtil.writeDefaultAttribute(ATTRIBUTE_LANGUAGE, path.getLanguage(), xtw);
   BpmnXMLUtil.writeDefaultAttribute(
       ATTRIBUTE_EVALUATES_TO_TYPE_REF, path.getEvaluatesToTypeRef(), xtw);
   xtw.writeCData(path.getExpressionValue());
   xtw.writeEndElement();
 }
  public void parseChildElement(XMLStreamReader xtr, BaseElement parentElement, BpmnModel model)
      throws Exception {
    if (parentElement instanceof EndEvent == false) return;

    TerminateEventDefinition eventDefinition = new TerminateEventDefinition();
    BpmnXMLUtil.addXMLLocation(eventDefinition, xtr);

    BpmnXMLUtil.parseChildElements(ELEMENT_EVENT_TERMINATEDEFINITION, eventDefinition, xtr, model);

    ((Event) parentElement).getEventDefinitions().add(eventDefinition);
  }
 protected void writeSignalDefinition(
     Event parentEvent, SignalEventDefinition signalDefinition, XMLStreamWriter xtw)
     throws Exception {
   xtw.writeStartElement(ELEMENT_EVENT_SIGNALDEFINITION);
   writeDefaultAttribute(ATTRIBUTE_SIGNAL_REF, signalDefinition.getSignalRef(), xtw);
   if (parentEvent instanceof ThrowEvent && signalDefinition.isAsync()) {
     BpmnXMLUtil.writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_ASYNCHRONOUS, "true", xtw);
   }
   boolean didWriteExtensionStartElement =
       BpmnXMLUtil.writeExtensionElements(signalDefinition, false, xtw);
   if (didWriteExtensionStartElement) {
     xtw.writeEndElement();
   }
   xtw.writeEndElement();
 }
  protected void writeMessageDefinition(
      Event parentEvent,
      MessageEventDefinition messageDefinition,
      BpmnModel model,
      XMLStreamWriter xtw)
      throws Exception {
    xtw.writeStartElement(ELEMENT_EVENT_MESSAGEDEFINITION);

    String messageRef = messageDefinition.getMessageRef();
    if (StringUtils.isNotEmpty(messageRef)) {
      // remove the namespace from the message id if set
      if (messageRef.startsWith(model.getTargetNamespace())) {
        messageRef = messageRef.replace(model.getTargetNamespace(), "");
        messageRef = messageRef.replaceFirst(":", "");
      } else {
        for (String prefix : model.getNamespaces().keySet()) {
          String namespace = model.getNamespace(prefix);
          if (messageRef.startsWith(namespace)) {
            messageRef = messageRef.replace(model.getTargetNamespace(), "");
            messageRef = prefix + messageRef;
          }
        }
      }
    }
    writeDefaultAttribute(ATTRIBUTE_MESSAGE_REF, messageRef, xtw);
    boolean didWriteExtensionStartElement =
        BpmnXMLUtil.writeExtensionElements(messageDefinition, false, xtw);
    if (didWriteExtensionStartElement) {
      xtw.writeEndElement();
    }
    xtw.writeEndElement();
  }
  protected void writeTimerDefinition(
      Event parentEvent, TimerEventDefinition timerDefinition, XMLStreamWriter xtw)
      throws Exception {
    xtw.writeStartElement(ELEMENT_EVENT_TIMERDEFINITION);
    boolean didWriteExtensionStartElement =
        BpmnXMLUtil.writeExtensionElements(timerDefinition, false, xtw);
    if (didWriteExtensionStartElement) {
      xtw.writeEndElement();
    }
    if (StringUtils.isNotEmpty(timerDefinition.getTimeDate())) {
      xtw.writeStartElement(ATTRIBUTE_TIMER_DATE);
      xtw.writeCharacters(timerDefinition.getTimeDate());
      xtw.writeEndElement();

    } else if (StringUtils.isNotEmpty(timerDefinition.getTimeCycle())) {
      xtw.writeStartElement(ATTRIBUTE_TIMER_CYCLE);
      xtw.writeCharacters(timerDefinition.getTimeCycle());
      xtw.writeEndElement();

    } else if (StringUtils.isNotEmpty(timerDefinition.getTimeDuration())) {
      xtw.writeStartElement(ATTRIBUTE_TIMER_DURATION);
      xtw.writeCharacters(timerDefinition.getTimeDuration());
      xtw.writeEndElement();
    }

    xtw.writeEndElement();
  }
  @SuppressWarnings("unchecked")
  protected ExtensionElement parseExtensionElement(XMLStreamReader xtr) throws Exception {
    ExtensionElement extensionElement = new ExtensionElement();
    extensionElement.setName(xtr.getLocalName());
    if (StringUtils.isNotEmpty(xtr.getNamespaceURI())) {
      extensionElement.setNamespace(xtr.getNamespaceURI());
    }
    if (StringUtils.isNotEmpty(xtr.getPrefix())) {
      extensionElement.setNamespacePrefix(xtr.getPrefix());
    }

    BpmnXMLUtil.addCustomAttributes(xtr, extensionElement, defaultElementAttributes);

    boolean readyWithExtensionElement = false;
    while (readyWithExtensionElement == false && xtr.hasNext()) {
      xtr.next();
      if (xtr.isCharacters()) {
        if (StringUtils.isNotEmpty(xtr.getText().trim())) {
          extensionElement.setElementText(xtr.getText().trim());
        }
      } else if (xtr.isStartElement()) {
        ExtensionElement childExtensionElement = parseExtensionElement(xtr);
        extensionElement.addChildElement(childExtensionElement);
      } else if (xtr.isEndElement()
          && extensionElement.getName().equalsIgnoreCase(xtr.getLocalName())) {
        readyWithExtensionElement = true;
      }
    }
    return extensionElement;
  }
 @Override
 protected BaseElement convertXMLToElement(XMLStreamReader xtr) throws Exception {
   ManualTask manualTask = new ManualTask();
   BpmnXMLUtil.addXMLLocation(manualTask, xtr);
   parseChildElements(getXMLElementName(), manualTask, xtr);
   return manualTask;
 }
Exemple #9
0
  public void parse(XMLStreamReader xtr, BpmnModel model) throws Exception {

    String id = xtr.getAttributeValue(null, ATTRIBUTE_DI_BPMNELEMENT);
    GraphicInfo graphicInfo = new GraphicInfo();
    BpmnXMLUtil.addXMLLocation(graphicInfo, xtr);
    while (xtr.hasNext()) {
      xtr.next();
      if (xtr.isStartElement() && ELEMENT_DI_BOUNDS.equalsIgnoreCase(xtr.getLocalName())) {
        graphicInfo.setX(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_X)).intValue());
        graphicInfo.setY(Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_Y)).intValue());
        graphicInfo.setWidth(
            Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_WIDTH)).intValue());
        graphicInfo.setHeight(
            Double.valueOf(xtr.getAttributeValue(null, ATTRIBUTE_DI_HEIGHT)).intValue());

        String strIsExpanded = xtr.getAttributeValue(null, ATTRIBUTE_DI_IS_EXPANDED);
        if ("true".equalsIgnoreCase(strIsExpanded)) {
          graphicInfo.setExpanded(true);
        }

        model.addGraphicInfo(id, graphicInfo);
        break;
      } else if (xtr.isEndElement() && ELEMENT_DI_SHAPE.equalsIgnoreCase(xtr.getLocalName())) {
        break;
      }
    }
  }
 private static void writeCorrelationPropertyBinding(
     CorrelationPropertyBinding binding, XMLStreamWriter xtw) throws Exception {
   xtw.writeStartElement(ELEMENT_CORR_PROP_BINDING);
   BpmnXMLUtil.writeDefaultAttribute(ATTRIBUTE_ID, binding.getId(), xtw);
   xtw.writeAttribute(ELEMENT_CORR_PROP_REF, binding.getCorrelationPropertyRef());
   writeDataPath(binding.getDataPath(), xtw);
   xtw.writeEndElement();
 }
  @Override
  protected BaseElement convertXMLToElement(XMLStreamReader xtr) throws Exception {
    ServiceTask serviceTask = new ServiceTask();
    BpmnXMLUtil.addXMLLocation(serviceTask, xtr);
    if (StringUtils.isNotEmpty(
        xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_CLASS))) {
      serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_CLASS);
      serviceTask.setImplementation(
          xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_CLASS));

    } else if (StringUtils.isNotEmpty(
        xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_EXPRESSION))) {
      serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION);
      serviceTask.setImplementation(
          xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_EXPRESSION));

    } else if (StringUtils.isNotEmpty(
        xtr.getAttributeValue(
            ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_DELEGATEEXPRESSION))) {
      serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
      serviceTask.setImplementation(
          xtr.getAttributeValue(
              ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_DELEGATEEXPRESSION));

    } else if ("##WebService".equals(xtr.getAttributeValue(null, ATTRIBUTE_TASK_IMPLEMENTATION))) {
      serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_WEBSERVICE);
      serviceTask.setOperationRef(
          parseOperationRef(xtr.getAttributeValue(null, ATTRIBUTE_TASK_OPERATION_REF), model));
    }

    serviceTask.setResultVariableName(
        xtr.getAttributeValue(
            ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_RESULTVARIABLE));
    if (StringUtils.isEmpty(serviceTask.getResultVariableName())) {
      serviceTask.setResultVariableName(
          xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, "resultVariable"));
    }

    if (StringUtils.isNotEmpty(serviceTask.getResultVariableName())
        && (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equals(serviceTask.getImplementationType())
            || ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equals(
                serviceTask.getImplementationType()))) {

      model.addProblem(
          "'resultVariableName' not supported for service tasks using 'class' or 'delegateExpression",
          xtr);
    }

    serviceTask.setType(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TYPE));
    serviceTask.setExtensionId(
        xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_EXTENSIONID));

    parseChildElements(getXMLElementName(), serviceTask, xtr);

    return serviceTask;
  }
 public static void writeCorrelationSubscription(
     CorrelationSubscription subscription, XMLStreamWriter xtw) throws Exception {
   xtw.writeStartElement(ELEMENT_CORRELATION_SUBSCRIPTION);
   BpmnXMLUtil.writeDefaultAttribute(ATTRIBUTE_ID, subscription.getId(), xtw);
   xtw.writeAttribute(ATTRIBUTE_CORRELATION_KEY_REF, subscription.getCorrelationKeyRef());
   for (CorrelationPropertyBinding binding : subscription.getCorrelationPropertyBindings()) {
     writeCorrelationPropertyBinding(binding, xtw);
   }
   xtw.writeEndElement();
 }
 protected void writeTerminateDefinition(
     Event parentEvent, TerminateEventDefinition terminateDefinition, XMLStreamWriter xtw)
     throws Exception {
   xtw.writeStartElement(ELEMENT_EVENT_TERMINATEDEFINITION);
   boolean didWriteExtensionStartElement =
       BpmnXMLUtil.writeExtensionElements(terminateDefinition, false, xtw);
   if (didWriteExtensionStartElement) {
     xtw.writeEndElement();
   }
   xtw.writeEndElement();
 }
 protected void writeErrorDefinition(
     Event parentEvent, ErrorEventDefinition errorDefinition, XMLStreamWriter xtw)
     throws Exception {
   xtw.writeStartElement(ELEMENT_EVENT_ERRORDEFINITION);
   writeDefaultAttribute(ATTRIBUTE_ERROR_REF, errorDefinition.getErrorCode(), xtw);
   boolean didWriteExtensionStartElement =
       BpmnXMLUtil.writeExtensionElements(errorDefinition, false, xtw);
   if (didWriteExtensionStartElement) {
     xtw.writeEndElement();
   }
   xtw.writeEndElement();
 }
  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);
    }
    BpmnXMLUtil.parseChildElements(elementName, parentElement, xtr, childParsers, model);
  }
  public void parseChildElement(XMLStreamReader xtr, BaseElement parentElement, BpmnModel model)
      throws Exception {
    if (parentElement instanceof Event == false) return;

    CompensateEventDefinition eventDefinition = new CompensateEventDefinition();
    BpmnXMLUtil.addXMLLocation(eventDefinition, xtr);
    eventDefinition.setActivityRef(xtr.getAttributeValue(null, ATTRIBUTE_COMPENSATE_ACTIVITYREF));
    if (StringUtils.isNotEmpty(
        xtr.getAttributeValue(null, ATTRIBUTE_COMPENSATE_WAITFORCOMPLETION))) {
      eventDefinition.setWaitForCompletion(
          Boolean.parseBoolean(
              xtr.getAttributeValue(null, ATTRIBUTE_COMPENSATE_WAITFORCOMPLETION)));
    }

    ((Event) parentElement).getEventDefinitions().add(eventDefinition);
  }
  public void parseChildElement(XMLStreamReader xtr, BaseElement parentElement, BpmnModel model)
      throws Exception {

    /*if (parentElement instanceof ServiceTask == false && parentElement instanceof SendTask == false &&
        parentElement instanceof SubProcess == false && parentElement instanceof Process == false) return;
    */

    if (parentElement instanceof Activity == false && parentElement instanceof Process == false)
      return;
    IOSpecification ioSpecification = new IOSpecification();
    BpmnXMLUtil.addXMLLocation(ioSpecification, xtr);
    boolean readyWithIOSpecification = false;
    System.out.println("IOSPEC PARSE " + parentElement);
    try {
      while (readyWithIOSpecification == false && xtr.hasNext()) {
        xtr.next();
        if (xtr.isStartElement() && ELEMENT_DATA_INPUT.equalsIgnoreCase(xtr.getLocalName())) {
          inputParser.parseChildElement(xtr, ioSpecification, model);

        } else if (xtr.isStartElement()
            && ELEMENT_DATA_OUTPUT.equalsIgnoreCase(xtr.getLocalName())) {
          outputParser.parseChildElement(xtr, ioSpecification, model);

        } else if (xtr.isStartElement()
            && ELEMENT_DATA_INPUTSET.equalsIgnoreCase(xtr.getLocalName())) {
          inputSetParser.parseChildElement(xtr, ioSpecification, model);

        } else if (xtr.isStartElement()
            && ELEMENT_DATA_OUTPUTSET.equalsIgnoreCase(xtr.getLocalName())) {
          outputsetParser.parseChildElement(xtr, ioSpecification, model);

        } else if (xtr.isEndElement() && getElementName().equalsIgnoreCase(xtr.getLocalName())) {
          readyWithIOSpecification = true;
        }
      }
    } catch (Exception e) {
      LOGGER.warn("Error parsing ioSpecification child elements", e);
    }

    if (parentElement instanceof Process) {
      ((Process) parentElement).setIoSpecification(ioSpecification);
    } else {
      ((Activity) parentElement).setIoSpecification(ioSpecification);
    }
  }
  public void parse(XMLStreamReader xtr, BpmnModel model) throws Exception {
    CorrelationKey key = new CorrelationKey();
    BpmnXMLUtil.addXMLLocation(key, xtr);
    key.setId(xtr.getAttributeValue(null, ATTRIBUTE_ID));
    key.setName(xtr.getAttributeValue(null, ATTRIBUTE_NAME));

    boolean ready = false;

    while (ready == false && xtr.hasNext()) {
      xtr.next();
      if (xtr.isStartElement() && ELEMENT_CORR_PROP_REF.equals(xtr.getLocalName())) {
        key.addCorrelationPropertyRef(xtr.getElementText());

      } else if (xtr.isEndElement() && ELEMENT_CORRELATION_KEY.equals(xtr.getLocalName())) {
        ready = true;
      }
    }

    model.addCorrelationKey(key);
  }
  public void convertToXML(XMLStreamWriter xtw, BaseElement baseElement, BpmnModel model)
      throws Exception {
    xtw.writeStartElement(getXMLElementName());
    boolean didWriteExtensionStartElement = false;
    writeDefaultAttribute(ATTRIBUTE_ID, baseElement.getId(), xtw);
    if (baseElement instanceof FlowElement) {
      writeDefaultAttribute(ATTRIBUTE_NAME, ((FlowElement) baseElement).getName(), xtw);
    }

    if (baseElement instanceof Activity) {
      final Activity activity = (Activity) baseElement;
      if (activity.isAsynchronous()) {
        writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_ASYNCHRONOUS, ATTRIBUTE_VALUE_TRUE, xtw);
        if (activity.isNotExclusive()) {
          writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_EXCLUSIVE, ATTRIBUTE_VALUE_FALSE, xtw);
        }
      }
      if (StringUtils.isNotEmpty(activity.getDefaultFlow())) {
        FlowElement defaultFlowElement = model.getFlowElement(activity.getDefaultFlow());
        if (defaultFlowElement != null && defaultFlowElement instanceof SequenceFlow) {
          writeDefaultAttribute(ATTRIBUTE_DEFAULT, activity.getDefaultFlow(), xtw);
        }
      }
    }

    if (baseElement instanceof Gateway) {
      final Gateway gateway = (Gateway) baseElement;
      if (gateway.isAsynchronous()) {
        writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_ASYNCHRONOUS, ATTRIBUTE_VALUE_TRUE, xtw);
        if (gateway.isNotExclusive()) {
          writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_EXCLUSIVE, ATTRIBUTE_VALUE_FALSE, xtw);
        }
      }
      if (StringUtils.isNotEmpty(gateway.getDefaultFlow())) {
        FlowElement defaultFlowElement = model.getFlowElement(gateway.getDefaultFlow());
        if (defaultFlowElement != null && defaultFlowElement instanceof SequenceFlow) {
          writeDefaultAttribute(ATTRIBUTE_DEFAULT, gateway.getDefaultFlow(), xtw);
        }
      }
    }

    writeAdditionalAttributes(baseElement, model, xtw);

    if (baseElement instanceof FlowElement) {
      final FlowElement flowElement = (FlowElement) baseElement;
      if (StringUtils.isNotEmpty(flowElement.getDocumentation())) {

        xtw.writeStartElement(ELEMENT_DOCUMENTATION);
        xtw.writeCharacters(flowElement.getDocumentation());
        xtw.writeEndElement();
      }
    }

    didWriteExtensionStartElement =
        writeExtensionChildElements(baseElement, didWriteExtensionStartElement, xtw);
    didWriteExtensionStartElement = writeListeners(baseElement, didWriteExtensionStartElement, xtw);
    didWriteExtensionStartElement =
        BpmnXMLUtil.writeExtensionElements(baseElement, didWriteExtensionStartElement, xtw);

    if (didWriteExtensionStartElement) {
      xtw.writeEndElement();
    }

    if (baseElement instanceof Activity) {
      final Activity activity = (Activity) baseElement;
      MultiInstanceExport.writeMultiInstance(activity, xtw);
    }

    writeAdditionalChildElements(baseElement, model, xtw);

    xtw.writeEndElement();
  }
 protected void writeQualifiedAttribute(String attributeName, String value, XMLStreamWriter xtw)
     throws Exception {
   BpmnXMLUtil.writeQualifiedAttribute(attributeName, value, xtw);
 }
  @SuppressWarnings("unchecked")
  public static void writeProcess(Process process, XMLStreamWriter xtw) throws Exception {
    // start process element
    xtw.writeStartElement(ELEMENT_PROCESS);
    xtw.writeAttribute(ATTRIBUTE_ID, process.getId());

    if (StringUtils.isNotEmpty(process.getName())) {
      xtw.writeAttribute(ATTRIBUTE_NAME, process.getName());
    }

    xtw.writeAttribute(ATTRIBUTE_PROCESS_EXECUTABLE, Boolean.toString(process.isExecutable()));
    xtw.writeAttribute("isClosed", Boolean.toString(process.isClosed()));
    if (StringUtils.isNotEmpty(process.getProcessType())) {
      xtw.writeAttribute("processType", process.getProcessType());
    }

    if (process.getCandidateStarterUsers().size() > 0) {
      xtw.writeAttribute(
          ACTIVITI_EXTENSIONS_PREFIX,
          ACTIVITI_EXTENSIONS_NAMESPACE,
          ATTRIBUTE_PROCESS_CANDIDATE_USERS,
          BpmnXMLUtil.convertToDelimitedString(process.getCandidateStarterUsers()));
    }

    if (process.getCandidateStarterGroups().size() > 0) {
      xtw.writeAttribute(
          ACTIVITI_EXTENSIONS_PREFIX,
          ACTIVITI_EXTENSIONS_NAMESPACE,
          ATTRIBUTE_PROCESS_CANDIDATE_GROUPS,
          BpmnXMLUtil.convertToDelimitedString(process.getCandidateStarterGroups()));
    }

    // write custom attributes
    BpmnXMLUtil.writeCustomAttributes(
        process.getAttributes().values(), xtw, defaultProcessAttributes);

    if (!process.getDocumentations().isEmpty()) {
      for (Documentation documentation : process.getDocumentations()) {
        xtw.writeStartElement(ELEMENT_DOCUMENTATION);
        if (StringUtils.isNotEmpty(documentation.getId())) {
          writeDefaultAttribute(ATTRIBUTE_ID, documentation.getId(), xtw);
        }
        if (StringUtils.isNotEmpty(documentation.getTextFormat())) {
          writeDefaultAttribute(ATTRIBUTE_TEXTFORMAT, documentation.getTextFormat(), xtw);
        }
        if (StringUtils.isNotEmpty(documentation.getText())) {
          xtw.writeCData(documentation.getText());
        }
        xtw.writeEndElement();
      }
    }

    boolean didWriteExtensionStartElement =
        ActivitiListenerExport.writeListeners(process, false, xtw);
    didWriteExtensionStartElement =
        BpmnXMLUtil.writeExtensionElements(process, didWriteExtensionStartElement, xtw);

    if (didWriteExtensionStartElement) {
      // closing extensions element
      xtw.writeEndElement();
    }
    if (process.getIoSpecification() != null) {
      BpmnXMLUtil.writeIOSpecification(process.getIoSpecification(), xtw);
    }

    LaneExport.writeLanes(process, xtw);
  }
 protected static void writeDefaultAttribute(
     String attributeName, String value, XMLStreamWriter xtw) throws Exception {
   BpmnXMLUtil.writeDefaultAttribute(attributeName, value, xtw);
 }
 protected List<String> parseDelimitedList(String expression) {
   return BpmnXMLUtil.parseDelimitedList(expression);
 }
 protected String convertToDelimitedString(List<String> stringList) {
   return BpmnXMLUtil.convertToDelimitedString(stringList);
 }