protected void setPropertyFieldValue(String name, ServiceTask task, ObjectNode propertiesNode) {
   for (FieldExtension extension : task.getFieldExtensions()) {
     if (name.substring(8).equalsIgnoreCase(extension.getFieldName())) {
       if (StringUtils.isNotEmpty(extension.getStringValue())) {
         setPropertyValue(name, extension.getStringValue(), propertiesNode);
       } else if (StringUtils.isNotEmpty(extension.getExpression())) {
         setPropertyValue(name, extension.getExpression(), propertiesNode);
       }
     }
   }
 }
  protected FlowElement convertJsonToElement(
      JsonNode elementNode, JsonNode modelNode, Map<String, JsonNode> shapeMap) {
    ServiceTask task = new ServiceTask();
    if (StringUtils.isNotEmpty(getPropertyValueAsString(PROPERTY_SERVICETASK_CLASS, elementNode))) {
      task.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_CLASS);
      task.setImplementation(getPropertyValueAsString(PROPERTY_SERVICETASK_CLASS, elementNode));

    } else if (StringUtils.isNotEmpty(
        getPropertyValueAsString(PROPERTY_SERVICETASK_EXPRESSION, elementNode))) {
      task.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION);
      task.setImplementation(
          getPropertyValueAsString(PROPERTY_SERVICETASK_EXPRESSION, elementNode));

    } else if (StringUtils.isNotEmpty(
        getPropertyValueAsString(PROPERTY_SERVICETASK_DELEGATE_EXPRESSION, elementNode))) {
      task.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
      task.setImplementation(
          getPropertyValueAsString(PROPERTY_SERVICETASK_DELEGATE_EXPRESSION, elementNode));
    }

    if (StringUtils.isNotEmpty(
        getPropertyValueAsString(PROPERTY_SERVICETASK_RESULT_VARIABLE, elementNode))) {
      task.setResultVariableName(
          getPropertyValueAsString(PROPERTY_SERVICETASK_RESULT_VARIABLE, elementNode));
    }

    JsonNode fieldsNode = getProperty(PROPERTY_SERVICETASK_FIELDS, elementNode);
    if (fieldsNode != null) {
      JsonNode itemsArrayNode = fieldsNode.get(EDITOR_PROPERTIES_GENERAL_ITEMS);
      if (itemsArrayNode != null) {
        for (JsonNode itemNode : itemsArrayNode) {
          JsonNode nameNode = itemNode.get(PROPERTY_SERVICETASK_FIELD_NAME);
          if (nameNode != null && StringUtils.isNotEmpty(nameNode.asText())) {

            FieldExtension field = new FieldExtension();
            field.setFieldName(nameNode.asText());
            if (StringUtils.isNotEmpty(
                getValueAsString(PROPERTY_SERVICETASK_FIELD_VALUE, itemNode))) {
              field.setStringValue(getValueAsString(PROPERTY_SERVICETASK_FIELD_VALUE, itemNode));
            } else if (StringUtils.isNotEmpty(
                getValueAsString(PROPERTY_SERVICETASK_FIELD_EXPRESSION, itemNode))) {
              field.setExpression(
                  getValueAsString(PROPERTY_SERVICETASK_FIELD_EXPRESSION, itemNode));
            }
            task.getFieldExtensions().add(field);
          }
        }
      }
    }

    return task;
  }
 protected void addField(String name, JsonNode elementNode, ServiceTask task) {
   FieldExtension field = new FieldExtension();
   field.setFieldName(name.substring(8));
   String value = getPropertyValueAsString(name, elementNode);
   if (StringUtils.isNotEmpty(value)) {
     if ((value.contains("${") || value.contains("#{")) && value.contains("}")) {
       field.setExpression(value);
     } else {
       field.setStringValue(value);
     }
     task.getFieldExtensions().add(field);
   }
 }
 public ClassDelegate createClassDelegateServiceTask(ServiceTask serviceTask) {
   Expression skipExpression;
   if (StringUtils.isNotEmpty(serviceTask.getSkipExpression())) {
     skipExpression = expressionManager.createExpression(serviceTask.getSkipExpression());
   } else {
     skipExpression = null;
   }
   return new ClassDelegate(
       serviceTask.getId(),
       serviceTask.getImplementation(),
       createFieldDeclarations(serviceTask.getFieldExtensions()),
       skipExpression,
       serviceTask.getMapExceptions());
 }
 public ServiceTaskDelegateExpressionActivityBehavior
     createServiceTaskDelegateExpressionActivityBehavior(ServiceTask serviceTask) {
   Expression delegateExpression =
       expressionManager.createExpression(serviceTask.getImplementation());
   Expression skipExpression;
   if (StringUtils.isNotEmpty(serviceTask.getSkipExpression())) {
     skipExpression = expressionManager.createExpression(serviceTask.getSkipExpression());
   } else {
     skipExpression = null;
   }
   return new ServiceTaskDelegateExpressionActivityBehavior(
       delegateExpression,
       skipExpression,
       createFieldDeclarations(serviceTask.getFieldExtensions()));
 }
  @Override
  protected void writeExtensionChildElements(BaseElement element, XMLStreamWriter xtw)
      throws Exception {
    ServiceTask serviceTask = (ServiceTask) element;

    if (serviceTask.getCustomProperties().size() > 0) {
      for (CustomProperty customProperty : serviceTask.getCustomProperties()) {

        if (StringUtils.isEmpty(customProperty.getSimpleValue())) {
          continue;
        }

        if (didWriteExtensionStartElement == false) {
          xtw.writeStartElement(ELEMENT_EXTENSIONS);
          didWriteExtensionStartElement = true;
        }
        xtw.writeStartElement(
            ACTIVITI_EXTENSIONS_PREFIX, ELEMENT_FIELD, ACTIVITI_EXTENSIONS_NAMESPACE);
        xtw.writeAttribute(ATTRIBUTE_FIELD_NAME, customProperty.getName());
        if ((customProperty.getSimpleValue().contains("${")
                || customProperty.getSimpleValue().contains("#{"))
            && customProperty.getSimpleValue().contains("}")) {

          xtw.writeStartElement(
              ACTIVITI_EXTENSIONS_PREFIX,
              ATTRIBUTE_FIELD_EXPRESSION,
              ACTIVITI_EXTENSIONS_NAMESPACE);
        } else {
          xtw.writeStartElement(
              ACTIVITI_EXTENSIONS_PREFIX, ELEMENT_FIELD_STRING, ACTIVITI_EXTENSIONS_NAMESPACE);
        }
        xtw.writeCharacters(customProperty.getSimpleValue());
        xtw.writeEndElement();
        xtw.writeEndElement();
      }
    } else {
      didWriteExtensionStartElement =
          FieldExtensionExport.writeFieldExtensions(
              serviceTask.getFieldExtensions(), didWriteExtensionStartElement, xtw);
    }
  }
  protected void convertElementToJson(ObjectNode propertiesNode, FlowElement flowElement) {
    ServiceTask serviceTask = (ServiceTask) flowElement;

    if ("mail".equalsIgnoreCase(serviceTask.getType())) {

      setPropertyFieldValue(PROPERTY_MAILTASK_TO, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_FROM, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_SUBJECT, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_CC, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_BCC, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_TEXT, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_HTML, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_CHARSET, serviceTask, propertiesNode);

    } else {

      if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equals(
          serviceTask.getImplementationType())) {
        propertiesNode.put(PROPERTY_SERVICETASK_CLASS, serviceTask.getImplementation());
      } else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equals(
          serviceTask.getImplementationType())) {
        propertiesNode.put(PROPERTY_SERVICETASK_EXPRESSION, serviceTask.getImplementation());
      } else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equals(
          serviceTask.getImplementationType())) {
        propertiesNode.put(
            PROPERTY_SERVICETASK_DELEGATE_EXPRESSION, serviceTask.getImplementation());
      }

      if (StringUtils.isNotEmpty(serviceTask.getResultVariableName())) {
        propertiesNode.put(
            PROPERTY_SERVICETASK_RESULT_VARIABLE, serviceTask.getResultVariableName());
      }

      addFieldExtensions(serviceTask.getFieldExtensions(), propertiesNode);
    }
  }
  private void drawFlowElements(
      Collection<FlowElement> elementList,
      Map<String, GraphicInfo> locationMap,
      ContainerShape parentShape,
      Process process) {

    final IFeatureProvider featureProvider = getDiagramTypeProvider().getFeatureProvider();

    List<FlowElement> noDIList = new ArrayList<FlowElement>();
    for (FlowElement flowElement : elementList) {

      if (flowElement instanceof SequenceFlow) {
        continue;
      }

      AddContext context = new AddContext(new AreaContext(), flowElement);
      IAddFeature addFeature = featureProvider.getAddFeature(context);

      if (addFeature == null) {
        System.out.println("Element not supported: " + flowElement);
        return;
      }

      GraphicInfo graphicInfo = locationMap.get(flowElement.getId());
      if (graphicInfo == null) {

        noDIList.add(flowElement);

      } else {

        context.setNewObject(flowElement);
        context.setSize((int) graphicInfo.getWidth(), (int) graphicInfo.getHeight());

        ContainerShape parentContainer = null;
        if (parentShape instanceof Diagram) {
          parentContainer = getParentContainer(flowElement.getId(), process, (Diagram) parentShape);
        } else {
          parentContainer = parentShape;
        }

        context.setTargetContainer(parentContainer);
        if (parentContainer instanceof Diagram == false) {
          Point location = getLocation(parentContainer);
          context.setLocation(
              (int) graphicInfo.getX() - location.x, (int) graphicInfo.getY() - location.y);
        } else {
          context.setLocation((int) graphicInfo.getX(), (int) graphicInfo.getY());
        }

        if (flowElement instanceof ServiceTask) {

          ServiceTask serviceTask = (ServiceTask) flowElement;

          if (serviceTask.isExtended()) {

            CustomServiceTask targetTask = findCustomServiceTask(serviceTask);

            if (targetTask != null) {

              for (FieldExtension field : serviceTask.getFieldExtensions()) {
                CustomProperty customFieldProperty = new CustomProperty();
                customFieldProperty.setName(field.getFieldName());
                if (StringUtils.isNotEmpty(field.getExpression())) {
                  customFieldProperty.setSimpleValue(field.getExpression());
                } else {
                  customFieldProperty.setSimpleValue(field.getStringValue());
                }
                serviceTask.getCustomProperties().add(customFieldProperty);
              }

              serviceTask.getFieldExtensions().clear();
            }
          }
        }

        if (flowElement instanceof BoundaryEvent) {
          BoundaryEvent boundaryEvent = (BoundaryEvent) flowElement;
          if (boundaryEvent.getAttachedToRef() != null) {
            ContainerShape container =
                (ContainerShape)
                    featureProvider.getPictogramElementForBusinessObject(
                        boundaryEvent.getAttachedToRef());

            if (container != null) {
              AddContext boundaryContext = new AddContext(new AreaContext(), boundaryEvent);
              boundaryContext.setTargetContainer(container);
              Point location = getLocation(container);
              boundaryContext.setLocation(
                  (int) graphicInfo.getX() - location.x, (int) graphicInfo.getY() - location.y);

              if (addFeature.canAdd(boundaryContext)) {
                PictogramElement newBoundaryContainer = addFeature.add(boundaryContext);
                // featureProvider.link(newBoundaryContainer, new Object[] { boundaryEvent });
              }
            }
          }
        } else if (addFeature.canAdd(context)) {
          PictogramElement newContainer = addFeature.add(context);
          featureProvider.link(newContainer, new Object[] {flowElement});

          if (flowElement instanceof SubProcess) {
            drawFlowElements(
                ((SubProcess) flowElement).getFlowElements(),
                locationMap,
                (ContainerShape) newContainer,
                process);
          }
        }
      }
    }

    for (FlowElement flowElement : noDIList) {
      if (flowElement instanceof BoundaryEvent) {
        ((BoundaryEvent) flowElement).getAttachedToRef().getBoundaryEvents().remove(flowElement);
      } else {
        elementList.remove(flowElement);
      }
    }
  }
  @SuppressWarnings({"rawtypes", "unchecked"})
  protected void drawFlowElements(
      Collection<FlowElement> elementList,
      Map<String, GraphicInfo> locationMap,
      ContainerShape parentShape,
      Process process) {

    final IFeatureProvider featureProvider = getDiagramTypeProvider().getFeatureProvider();

    List<FlowElement> noDIList = new ArrayList<FlowElement>();
    for (FlowElement flowElement : elementList) {

      if (flowElement instanceof SequenceFlow) {
        continue;
      }

      AddContext context = new AddContext(new AreaContext(), flowElement);
      IAddFeature addFeature = featureProvider.getAddFeature(context);

      if (addFeature == null) {
        System.out.println("Element not supported: " + flowElement);
        return;
      }

      GraphicInfo graphicInfo = locationMap.get(flowElement.getId());
      if (graphicInfo == null) {

        noDIList.add(flowElement);

      } else {

        context.setNewObject(flowElement);
        context.setSize((int) graphicInfo.getWidth(), (int) graphicInfo.getHeight());
        ContainerShape parentContainer = null;
        if (parentShape instanceof Diagram) {
          parentContainer = getParentContainer(flowElement.getId(), process, (Diagram) parentShape);
        } else {
          parentContainer = parentShape;
        }

        context.setTargetContainer(parentContainer);
        if (parentContainer instanceof Diagram == false) {
          Point location = getLocation(parentContainer);
          context.setLocation(
              (int) graphicInfo.getX() - location.x, (int) graphicInfo.getY() - location.y);
        } else {
          context.setLocation((int) graphicInfo.getX(), (int) graphicInfo.getY());
        }

        if (flowElement instanceof ServiceTask) {

          ServiceTask serviceTask = (ServiceTask) flowElement;

          if (serviceTask.isExtended()) {

            CustomServiceTask targetTask = findCustomServiceTask(serviceTask);

            if (targetTask != null) {

              for (FieldExtension field : serviceTask.getFieldExtensions()) {
                CustomProperty customFieldProperty = new CustomProperty();
                customFieldProperty.setName(field.getFieldName());
                if (StringUtils.isNotEmpty(field.getExpression())) {
                  customFieldProperty.setSimpleValue(field.getExpression());
                } else {
                  customFieldProperty.setSimpleValue(field.getStringValue());
                }
                serviceTask.getCustomProperties().add(customFieldProperty);
              }

              serviceTask.getFieldExtensions().clear();
            }
          }

        } else if (flowElement instanceof UserTask) {

          UserTask userTask = (UserTask) flowElement;

          if (userTask.isExtended()) {

            CustomUserTask targetTask = findCustomUserTask(userTask);

            if (targetTask != null) {

              final List<Class<CustomUserTask>> classHierarchy =
                  new ArrayList<Class<CustomUserTask>>();
              final List<String> fieldInfoObjects = new ArrayList<String>();

              Class clazz = targetTask.getClass();
              classHierarchy.add(clazz);

              boolean hierarchyOpen = true;
              while (hierarchyOpen) {
                clazz = clazz.getSuperclass();
                if (CustomUserTask.class.isAssignableFrom(clazz)) {
                  classHierarchy.add(clazz);
                } else {
                  hierarchyOpen = false;
                }
              }

              for (final Class<CustomUserTask> currentClass : classHierarchy) {
                for (final Field field : currentClass.getDeclaredFields()) {
                  if (field.isAnnotationPresent(Property.class)) {
                    fieldInfoObjects.add(field.getName());
                  }
                }
              }

              for (String fieldName : userTask.getExtensionElements().keySet()) {
                if (fieldInfoObjects.contains(fieldName)) {
                  CustomProperty customFieldProperty = new CustomProperty();
                  customFieldProperty.setName(fieldName);
                  customFieldProperty.setSimpleValue(
                      userTask.getExtensionElements().get(fieldName).get(0).getElementText());
                  userTask.getCustomProperties().add(customFieldProperty);
                }
              }

              for (String fieldName : fieldInfoObjects) {
                userTask.getExtensionElements().remove(fieldName);
              }
            }
          }
        }

        if (flowElement instanceof BoundaryEvent) {
          BoundaryEvent boundaryEvent = (BoundaryEvent) flowElement;
          if (boundaryEvent.getAttachedToRef() != null) {
            ContainerShape container =
                (ContainerShape)
                    featureProvider.getPictogramElementForBusinessObject(
                        boundaryEvent.getAttachedToRef());

            if (container != null) {
              AddContext boundaryContext = new AddContext(new AreaContext(), boundaryEvent);
              boundaryContext.setTargetContainer(container);
              Point location = getLocation(container);
              boundaryContext.setLocation(
                  (int) graphicInfo.getX() - location.x, (int) graphicInfo.getY() - location.y);

              if (addFeature.canAdd(boundaryContext)) {
                addFeature.add(boundaryContext);
              }
            }
          }
        } else if (addFeature.canAdd(context)) {
          PictogramElement newContainer = addFeature.add(context);
          featureProvider.link(newContainer, new Object[] {flowElement});

          if (flowElement instanceof SubProcess) {
            drawFlowElements(
                ((SubProcess) flowElement).getFlowElements(),
                locationMap,
                (ContainerShape) newContainer,
                process);
          }
        }
      }
    }

    for (FlowElement flowElement : noDIList) {
      if (flowElement instanceof BoundaryEvent) {
        ((BoundaryEvent) flowElement).getAttachedToRef().getBoundaryEvents().remove(flowElement);
      } else {
        // do not remove Data Objects
        if (flowElement instanceof DataObject == false) {
          elementList.remove(flowElement);
        }
      }
    }
  }
 public ShellActivityBehavior createShellActivityBehavior(ServiceTask serviceTask) {
   List<FieldDeclaration> fieldDeclarations =
       createFieldDeclarations(serviceTask.getFieldExtensions());
   return (ShellActivityBehavior)
       ClassDelegate.instantiateDelegate(ShellActivityBehavior.class, fieldDeclarations);
 }
 // We do not want a hard dependency on Camel, hence we return ActivityBehavior and instantiate
 // the delegate instance using a string instead of the Class itself.
 public ActivityBehavior createCamelActivityBehavior(
     ServiceTask serviceTask, BpmnModel bpmnModel) {
   return createCamelActivityBehavior(serviceTask, serviceTask.getFieldExtensions(), bpmnModel);
 }
 public MailActivityBehavior createMailActivityBehavior(ServiceTask serviceTask) {
   return createMailActivityBehavior(serviceTask.getId(), serviceTask.getFieldExtensions());
 }