@Test
  public void testTransformTextFormFieldValue() throws Exception {
    DDMForm ddmForm = createDDMForm();

    addTextDDMFormFields(ddmForm, "FirstName", "LastName");

    DDMFormField ddmFormField = new DDMFormField("Description", "textarea");

    ddmForm.addDDMFormField(ddmFormField);

    DDMFormValues ddmFormValues = createDDMFormValues(ddmForm);

    ddmFormValues.addDDMFormFieldValue(
        createDDMFormFieldValue("FirstName", new UnlocalizedValue("Joe")));
    ddmFormValues.addDDMFormFieldValue(
        createDDMFormFieldValue("LastName", new UnlocalizedValue("Smith")));
    ddmFormValues.addDDMFormFieldValue(
        createDDMFormFieldValue("Description", new UnlocalizedValue("Description Value")));

    DDMFormValuesTransformer ddmFormValuesTransformer = new DDMFormValuesTransformer(ddmFormValues);

    String prefix = StringPool.UNDERLINE;

    ddmFormValuesTransformer.addTransformer(new DDMFormFieldValuePrefixAppender(prefix));

    ddmFormValuesTransformer.transform();

    List<DDMFormFieldValue> ddmFormFieldValues = ddmFormValues.getDDMFormFieldValues();

    testDDMFormFieldValue(ddmFormFieldValues.get(0), prefix.concat("Joe"));
    testDDMFormFieldValue(ddmFormFieldValues.get(1), prefix.concat("Smith"));
    testDDMFormFieldValue(ddmFormFieldValues.get(2), "Description Value");
  }
  @Test
  public void testCreateDDMFormFieldTypeSettingsDDMForm() {
    DDMForm ddmForm = DDMFormFactory.create(DDMFormFieldTypeSettings.class);

    Assert.assertNotNull(ddmForm);

    assertRequiredDDMFormFieldTypeSettings(ddmForm.getDDMFormFieldsMap(false));
  }
  protected DDMForm createDDMForm(List<Locale> availableLocales, Locale defaultLocale) {

    DDMForm ddmForm = new DDMForm();

    ddmForm.setAvailableLocales(availableLocales);
    ddmForm.setDefaultLocale(defaultLocale);

    return ddmForm;
  }
  @Override
  public void validate(DDMForm ddmForm) throws DDMFormValidationException {
    validateDDMFormLocales(ddmForm);

    validateDDMFormFields(
        ddmForm.getDDMFormFields(),
        new HashSet<String>(),
        ddmForm.getAvailableLocales(),
        ddmForm.getDefaultLocale());
  }
  protected void validateDDMFormLocales(DDMForm ddmForm) throws DDMFormValidationException {

    Locale defaultLocale = ddmForm.getDefaultLocale();

    if (defaultLocale == null) {
      throw new DDMFormValidationException(
          "The default locale property was never set for DDM form");
    }

    validateDDMFormAvailableLocales(ddmForm.getAvailableLocales(), defaultLocale);
  }
  protected DDMFormField getDDMFormField(HttpServletRequest request) throws PortalException {

    String definition = ParamUtil.getString(request, "definition");
    String fieldName = ParamUtil.getString(request, "fieldName");

    DDMForm ddmForm = _ddmFormJSONDeserializer.deserialize(definition);

    Map<String, DDMFormField> ddmFormFieldsMap = ddmForm.getDDMFormFieldsMap(true);

    return ddmFormFieldsMap.get(fieldName);
  }
  @Override
  public String serialize(DDMForm ddmForm) {
    Document document = SAXReaderUtil.createDocument();

    Element rootElement = document.addElement("root");

    rootElement.addAttribute("available-locales", getAvailableLanguagesIds(ddmForm));
    rootElement.addAttribute("default-locale", LocaleUtil.toLanguageId(ddmForm.getDefaultLocale()));

    addDynamicElementElements(ddmForm.getDDMFormFields(), rootElement);

    return document.asXML();
  }
  protected void assertEquals(DDMForm expectedDDMForm, DDMForm actualDDMForm) {

    Map<String, DDMFormField> expectedDDMFormFieldsMap = expectedDDMForm.getDDMFormFieldsMap(true);

    Map<String, DDMFormField> actualDDMFormFieldsMap = actualDDMForm.getDDMFormFieldsMap(true);

    for (Map.Entry<String, DDMFormField> expectedEntry : expectedDDMFormFieldsMap.entrySet()) {

      DDMFormField actualDDMFormField = actualDDMFormFieldsMap.get(expectedEntry.getKey());

      assertEquals(expectedEntry.getValue(), actualDDMFormField);
    }
  }
  @Test
  public void testTransformNestedRepeatableTextFormFieldValue() throws Exception {

    DDMForm ddmForm = createDDMForm();

    DDMFormField nameDDMFormField = new DDMFormField("Name", "textarea");

    DDMFormField phoneDDMFormField = new DDMFormField("Phone", "text");

    phoneDDMFormField.setRepeatable(true);

    nameDDMFormField.addNestedDDMFormField(phoneDDMFormField);

    ddmForm.addDDMFormField(nameDDMFormField);

    DDMFormValues ddmFormValues = createDDMFormValues(ddmForm);

    DDMFormFieldValue nameDDMFormFieldValue =
        createDDMFormFieldValue("Name", new UnlocalizedValue("Joe Smith"));

    nameDDMFormFieldValue.addNestedDDMFormFieldValue(
        createDDMFormFieldValue("Phone", new UnlocalizedValue("123")));
    nameDDMFormFieldValue.addNestedDDMFormFieldValue(
        createDDMFormFieldValue("Phone", new UnlocalizedValue("456")));
    nameDDMFormFieldValue.addNestedDDMFormFieldValue(
        createDDMFormFieldValue("Phone", new UnlocalizedValue("789")));

    ddmFormValues.addDDMFormFieldValue(nameDDMFormFieldValue);

    DDMFormValuesTransformer ddmFormValuesTransformer = new DDMFormValuesTransformer(ddmFormValues);

    String prefix = "+1";

    ddmFormValuesTransformer.addTransformer(new DDMFormFieldValuePrefixAppender(prefix));

    ddmFormValuesTransformer.transform();

    List<DDMFormFieldValue> ddmFormFieldValues = ddmFormValues.getDDMFormFieldValues();

    nameDDMFormFieldValue = ddmFormFieldValues.get(0);

    testDDMFormFieldValue(ddmFormFieldValues.get(0), "Joe Smith");

    List<DDMFormFieldValue> phoneDDMFormFieldValues =
        nameDDMFormFieldValue.getNestedDDMFormFieldValues();

    testDDMFormFieldValue(phoneDDMFormFieldValues.get(0), prefix.concat("123"));
    testDDMFormFieldValue(phoneDDMFormFieldValues.get(1), prefix.concat("456"));
    testDDMFormFieldValue(phoneDDMFormFieldValues.get(2), prefix.concat("789"));
  }
  protected void addTextDDMFormFields(DDMForm ddmForm, String... fieldNames) {
    List<DDMFormField> ddmFormFields = ddmForm.getDDMFormFields();

    for (String fieldName : fieldNames) {
      ddmFormFields.add(createTextDDMFormField(fieldName));
    }
  }
  protected void addDDMFormFields(DDMForm ddmForm, DDMFormField... ddmFormFieldsArray) {

    List<DDMFormField> ddmFormFields = ddmForm.getDDMFormFields();

    for (DDMFormField ddmFormField : ddmFormFieldsArray) {
      ddmFormFields.add(ddmFormField);
    }
  }
  protected List<DDMFormFieldValue> getDDMFormFieldValues(
      HttpServletRequest httpServletRequest, DDMForm ddmForm) {

    Map<String, DDMFormFieldValue> ddmFormFieldValuesMap =
        createDDMFormFieldValuesMap(httpServletRequest, ddmForm);

    return getDDMFormFieldValues(ddmFormFieldValuesMap, ddmForm.getDDMFormFields());
  }
  protected Set<String> createDefaultDDMFormFieldParameterNames(DDMForm ddmForm) {

    Set<String> defaultDDMFormFieldParameterNames = new TreeSet<>();

    poupulateDefaultDDMFormFieldParameterNames(
        ddmForm.getDDMFormFields(), StringPool.BLANK, defaultDDMFormFieldParameterNames);

    return defaultDDMFormFieldParameterNames;
  }
  protected String getAvailableLanguagesIds(DDMForm ddmForm) {
    List<Locale> availableLocales = ddmForm.getAvailableLocales();

    StringBuilder sb = new StringBuilder(2 * availableLocales.size() - 1);

    for (int i = 0; i < availableLocales.size(); i++) {
      if (i != 0) {
        sb.append(",");
      }

      sb.append(LocaleUtil.toLanguageId(availableLocales.get(i)));
    }

    return sb.toString();
  }
  protected Map<String, DDMFormFieldValue> createDDMFormFieldValuesMap(
      HttpServletRequest httpServletRequest, DDMForm ddmForm) {

    Map<String, DDMFormFieldValue> ddmFormFieldValuesMap = new HashMap<>();

    Set<String> ddmFormFieldParameterNames =
        getDDMFormFieldParameterNames(httpServletRequest, ddmForm);

    Map<String, DDMFormField> ddmFormFieldsMap = ddmForm.getDDMFormFieldsMap(true);

    for (String ddmFormFieldParameterName : ddmFormFieldParameterNames) {
      DDMFormFieldValue ddmFormFieldValue =
          createDDMFormFieldValue(httpServletRequest, ddmFormFieldParameterName, ddmFormFieldsMap);

      ddmFormFieldValuesMap.put(ddmFormFieldParameterName, ddmFormFieldValue);
    }

    return ddmFormFieldValuesMap;
  }
  @Test
  public void testCreateDefaultDDMFormFieldTypeSettingsDDMForm() {
    DDMForm ddmForm = DDMFormFactory.create(DefaultDDMFormFieldTypeSettings.class);

    Assert.assertNotNull(ddmForm);

    Map<String, DDMFormField> ddmFormFieldsMap = ddmForm.getDDMFormFieldsMap(false);

    assertRequiredDDMFormFieldTypeSettings(ddmFormFieldsMap);

    DDMFormField indexTypeDDMFormField = ddmFormFieldsMap.get("indexType");

    Assert.assertNotNull(indexTypeDDMFormField);
    Assert.assertEquals("string", indexTypeDDMFormField.getDataType());
    Assert.assertEquals("text", indexTypeDDMFormField.getType());

    DDMFormField labelDDMFormField = ddmFormFieldsMap.get("label");

    Assert.assertNotNull(labelDDMFormField);
    Assert.assertEquals("string", labelDDMFormField.getDataType());
    Assert.assertEquals("text", labelDDMFormField.getType());
    Assert.assertEquals(true, labelDDMFormField.isLocalizable());

    DDMFormField localizableDDMFormField = ddmFormFieldsMap.get("localizable");

    Assert.assertNotNull(localizableDDMFormField);
    Assert.assertEquals("boolean", localizableDDMFormField.getDataType());
    Assert.assertEquals("checkbox", localizableDDMFormField.getType());

    DDMFormField predefinedValueDDMFormField = ddmFormFieldsMap.get("predefinedValue");

    Assert.assertNotNull(predefinedValueDDMFormField);
    Assert.assertEquals("string", predefinedValueDDMFormField.getDataType());
    Assert.assertEquals("text", predefinedValueDDMFormField.getType());
    Assert.assertEquals(true, predefinedValueDDMFormField.isLocalizable());

    DDMFormField readOnlyDDMFormField = ddmFormFieldsMap.get("readOnly");

    Assert.assertNotNull(readOnlyDDMFormField);
    Assert.assertEquals("boolean", readOnlyDDMFormField.getDataType());
    Assert.assertEquals("checkbox", readOnlyDDMFormField.getType());

    DDMFormField repeatableDDMFormField = ddmFormFieldsMap.get("repeatable");

    Assert.assertNotNull(repeatableDDMFormField);
    Assert.assertEquals("boolean", repeatableDDMFormField.getDataType());
    Assert.assertEquals("checkbox", repeatableDDMFormField.getType());

    DDMFormField requiredDDMFormField = ddmFormFieldsMap.get("readOnly");

    Assert.assertNotNull(requiredDDMFormField);
    Assert.assertEquals("boolean", requiredDDMFormField.getDataType());
    Assert.assertEquals("checkbox", requiredDDMFormField.getType());

    DDMFormField showLabelDDMFormField = ddmFormFieldsMap.get("showLabel");

    Assert.assertNotNull(showLabelDDMFormField);
    Assert.assertEquals("boolean", showLabelDDMFormField.getDataType());
    Assert.assertEquals("checkbox", showLabelDDMFormField.getType());

    DDMFormField tipDDMFormField = ddmFormFieldsMap.get("tip");

    Assert.assertNotNull(tipDDMFormField);
    Assert.assertEquals("string", tipDDMFormField.getDataType());
    Assert.assertEquals("text", tipDDMFormField.getType());
    Assert.assertEquals(true, tipDDMFormField.isLocalizable());
  }