public void createForm(
      M2Type contentType,
      Form formConfig,
      FormDefinition formDefinition,
      WorkflowDefinitionConversion conversion) {
    if (formDefinition != null && formDefinition.getFormGroups() != null) {

      for (FormPropertyGroup group : formDefinition.getFormGroups()) {
        // Create a group in the form-config
        String groupId = null;
        if (group.getId() != null) {
          groupId = AlfrescoConversionUtil.getValidIdString(group.getId());
        } else {
          groupId = AlfrescoConversionUtil.getValidIdString(group.getTitle());
        }

        FormSet formSet =
            formConfig
                .getFormAppearance()
                .addFormSet(
                    groupId,
                    getAppearanceForGroup(group),
                    group.getTitle(),
                    getTemplateForGroup(group));

        // Convert all properties
        AlfrescoFormPropertyConverter converter = null;
        for (FormPropertyDefinition property : group.getFormPropertyDefinitions()) {
          converter = propertyConverters.get(property.getClass());
          if (converter == null) {
            throw new AlfrescoSimpleWorkflowException(
                "Unsupported property type: " + property.getClass().getName());
          }
          converter.convertProperty(contentType, formSet.getId(), formConfig, property, conversion);
        }
      }
    }

    // Finally, add "transitions" if not already added
    // TODO: check if added once transitions are supported
    formConfig
        .getFormAppearance()
        .addFormSet(AlfrescoConversionConstants.FORM_SET_RESPONSE, null, null, null);
    formConfig
        .getFormFieldVisibility()
        .addShowFieldElement(AlfrescoConversionConstants.FORM_FIELD_TRANSITIONS);
    formConfig
        .getFormAppearance()
        .addFormField(
            AlfrescoConversionConstants.FORM_FIELD_TRANSITIONS,
            null,
            AlfrescoConversionConstants.FORM_SET_RESPONSE);
  }
 /** Write the content model XML in the given conversion to the given stream. */
 public void writeContentModel(OutputStream out, WorkflowDefinitionConversion conversion)
     throws IOException {
   M2Model model = AlfrescoConversionUtil.getContentModel(conversion);
   try {
     Marshaller marshaller = modelJaxbContext.createMarshaller();
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
     marshaller.marshal(model, out);
   } catch (JAXBException jaxbe) {
     throw new IOException(jaxbe);
   }
 }
  protected void addAssociation(
      Form form,
      String formSet,
      ReferencePropertyDefinition referenceDefinition,
      M2Type contentType,
      WorkflowDefinitionConversion conversion) {

    M2Model model = AlfrescoConversionUtil.getContentModel(conversion);

    // Check if model contains an aspect for the property
    String propertyName = getPropertyName(referenceDefinition, conversion);

    M2ClassAssociation association = new M2ClassAssociation();
    association.setName(propertyName);
    association.setTitle(referenceDefinition.getName());
    M2AssociationSource source = new M2AssociationSource();
    source.setMany(false);
    source.setMandatory(true);
    M2AssociationTarget target = new M2AssociationTarget();
    target.setClassName(referenceDefinition.getType());
    target.setMandatory(referenceDefinition.isMandatory());

    // Determine whether or not it's allowed to select multiple targets
    boolean isTargetMany =
        extractBooleanFromParameters(
            referenceDefinition.getParameters(),
            AlfrescoConversionConstants.PARAMETER_REFERENCE_MANY,
            false);
    target.setMany(isTargetMany);

    association.setTarget(target);
    association.setSource(source);

    M2Aspect aspect = model.getAspect(propertyName);
    if (aspect != null) {
      if (aspect.getAssociations().isEmpty()) {
        aspect.getAssociations().add(association);
      }
      contentType.getMandatoryAspects().add(propertyName);
    } else {
      contentType.getAssociations().add(association);
    }

    // Add field to form
    form.getFormFieldVisibility().addShowFieldElement(propertyName);

    FormField field = new FormField();
    form.getFormAppearance().addFormAppearanceElement(field);
    field.setId(propertyName);
    field.setSet(formSet);
  }
  /** Write the Share module XML in the given conversion to the given stream. */
  public void writeShareConfig(
      OutputStream out, WorkflowDefinitionConversion conversion, boolean asModule)
      throws IOException {
    Module module = AlfrescoConversionUtil.getModule(conversion);
    try {
      Object toMarshall = module;

      // In case the configuration should NOT be exported as a module, wrap the configurations
      // in a "alfresco-configuration" element instead
      if (!asModule) {
        toMarshall = new AlfrescoConfiguration();
        ((AlfrescoConfiguration) toMarshall).setConfigurations(module.getConfigurations());
      }
      Marshaller marshaller = moduleJaxbContext.createMarshaller();
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
      marshaller.marshal(toMarshall, out);
    } catch (JAXBException jaxbe) {
      throw new IOException(jaxbe);
    }
  }
  protected void addFieldReference(
      Form form,
      String formSet,
      ReferencePropertyDefinition definition,
      M2Type contentType,
      WorkflowDefinitionConversion conversion) {
    if (form.isStartForm()) {
      throw new AlfrescoSimpleWorkflowException("Field references cannot be used on start-forms");
    }

    M2Model model = AlfrescoConversionUtil.getContentModel(conversion);

    // Check if model contains an aspect for the property
    String propertyName = getPropertyName(definition, conversion);

    if (model.getAspect(propertyName) == null) {
      throw new AlfrescoSimpleWorkflowException(
          "The property '"
              + definition.getName()
              + "' is not used in a from prior to this form: "
              + contentType.getName()
              + " - "
              + propertyName);
    }

    // Add aspect to content-type
    contentType.getMandatoryAspects().add(propertyName);

    // Add read-only field to form
    form.getFormFieldVisibility().addShowFieldElement(propertyName);

    FormField field = new FormField();
    form.getFormAppearance().addFormAppearanceElement(field);
    field.setId(propertyName);
    field.setLabelId(definition.getName());
    field.setSet(formSet);
    field.setControl(new FormFieldControl(AlfrescoConversionConstants.FORM_READONLY_TEMPLATE));
  }