001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.dynamicdatamapping.io;
016    
017    import com.liferay.portal.kernel.util.LocaleUtil;
018    import com.liferay.portal.kernel.util.StringUtil;
019    import com.liferay.portal.kernel.xml.Document;
020    import com.liferay.portal.kernel.xml.Element;
021    import com.liferay.portal.kernel.xml.SAXReaderUtil;
022    import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
023    import com.liferay.portlet.dynamicdatamapping.model.DDMFormField;
024    import com.liferay.portlet.dynamicdatamapping.model.DDMFormFieldOptions;
025    import com.liferay.portlet.dynamicdatamapping.model.LocalizedValue;
026    
027    import java.util.HashMap;
028    import java.util.List;
029    import java.util.Locale;
030    import java.util.Map;
031    import java.util.Set;
032    
033    /**
034     * @author Pablo Carvalho
035     */
036    public class DDMFormXSDSerializerImpl implements DDMFormXSDSerializer {
037    
038            @Override
039            public String serialize(DDMForm ddmForm) {
040                    Document document = SAXReaderUtil.createDocument();
041    
042                    Element rootElement = document.addElement("root");
043    
044                    rootElement.addAttribute(
045                            "available-locales", getAvailableLanguagesIds(ddmForm));
046                    rootElement.addAttribute(
047                            "default-locale",
048                            LocaleUtil.toLanguageId(ddmForm.getDefaultLocale()));
049    
050                    addDynamicElementElements(ddmForm.getDDMFormFields(), rootElement);
051    
052                    return document.asXML();
053            }
054    
055            protected void addDynamicElementAttributes(
056                    DDMFormField ddmFormField, Element dynamicElementElement) {
057    
058                    dynamicElementElement.addAttribute(
059                            "dataType", ddmFormField.getDataType());
060                    dynamicElementElement.addAttribute(
061                            "fieldNamespace", ddmFormField.getNamespace());
062                    dynamicElementElement.addAttribute(
063                            "indexType", ddmFormField.getIndexType());
064                    dynamicElementElement.addAttribute(
065                            "localizable", Boolean.toString(ddmFormField.isLocalizable()));
066                    dynamicElementElement.addAttribute(
067                            "multiple", Boolean.toString(ddmFormField.isMultiple()));
068                    dynamicElementElement.addAttribute("name", ddmFormField.getName());
069                    dynamicElementElement.addAttribute(
070                            "readOnly", Boolean.toString(ddmFormField.isReadOnly()));
071                    dynamicElementElement.addAttribute(
072                            "repeatable", Boolean.toString(ddmFormField.isRepeatable()));
073                    dynamicElementElement.addAttribute(
074                            "required", Boolean.toString(ddmFormField.isRequired()));
075                    dynamicElementElement.addAttribute(
076                            "showLabel", Boolean.toString(ddmFormField.isShowLabel()));
077                    dynamicElementElement.addAttribute("type", ddmFormField.getType());
078            }
079    
080            protected void addDynamicElementElement(
081                    DDMFormField ddmFormField, Element element) {
082    
083                    Element dynamicElementElement = SAXReaderUtil.createElement(
084                            "dynamic-element");
085    
086                    addDynamicElementAttributes(ddmFormField, dynamicElementElement);
087    
088                    addDynamicElementElements(
089                            ddmFormField.getNestedDDMFormFields(), dynamicElementElement);
090    
091                    String ddmFormFieldType = ddmFormField.getType();
092    
093                    if (ddmFormFieldType.equals("radio") ||
094                            ddmFormFieldType.equals("select")) {
095    
096                            addOptionsDynamicElements(
097                                    ddmFormField.getDDMFormFieldOptions(), dynamicElementElement);
098                    }
099    
100                    Map<Locale, Map<String, String>> metadataMap =
101                            getDDMFormFieldMetadataMap(ddmFormField);
102    
103                    addMetadataElements(metadataMap, dynamicElementElement);
104    
105                    List<Element> elements = dynamicElementElement.elements();
106    
107                    if (!elements.isEmpty()) {
108                            element.add(dynamicElementElement);
109                    }
110            }
111    
112            protected void addDynamicElementElements(
113                    List<DDMFormField> ddmFormFields, Element element) {
114    
115                    for (DDMFormField ddmFormField : ddmFormFields) {
116                            addDynamicElementElement(ddmFormField, element);
117                    }
118            }
119    
120            protected void addMetadataElements(
121                    Map<Locale, Map<String, String>> metadataMap,
122                    Element dynamicElementElement) {
123    
124                    for (Locale locale : metadataMap.keySet()) {
125                            Element metadataElement = dynamicElementElement.addElement(
126                                    "meta-data");
127    
128                            metadataElement.addAttribute(
129                                    "locale", LocaleUtil.toLanguageId(locale));
130    
131                            addMetadataEntry(metadataMap.get(locale), metadataElement);
132                    }
133            }
134    
135            protected void addMetadataEntry(
136                    Map<String, String> entryMap, Element metadataElement) {
137    
138                    for (Map.Entry<String, String> entry : entryMap.entrySet()) {
139                            Element entryElement = metadataElement.addElement("entry");
140    
141                            entryElement.addAttribute("name", entry.getKey());
142    
143                            entryElement.addText(entry.getValue());
144                    }
145            }
146    
147            protected void addMetadataEntryValues(
148                    Map<Locale, Map<String, String>> ddmFormFieldMetadataMap,
149                    String entryName, LocalizedValue localizedValue) {
150    
151                    for (Locale availableLocale : localizedValue.getAvailableLocales()) {
152                            Map<String, String> metadataMap = ddmFormFieldMetadataMap.get(
153                                    availableLocale);
154    
155                            if (metadataMap == null) {
156                                    metadataMap = new HashMap<String, String>();
157    
158                                    ddmFormFieldMetadataMap.put(availableLocale, metadataMap);
159                            }
160    
161                            metadataMap.put(
162                                    entryName, localizedValue.getString(availableLocale));
163                    }
164            }
165    
166            protected Element addOptionDynamicElement(
167                    String optionValue, Element dynamicElement) {
168    
169                    Element optionElement = dynamicElement.addElement("dynamic-element");
170    
171                    optionElement.addAttribute("name", "option_" + StringUtil.randomId());
172                    optionElement.addAttribute("type", "option");
173                    optionElement.addAttribute("value", optionValue);
174    
175                    return optionElement;
176            }
177    
178            protected void addOptionsDynamicElements(
179                    DDMFormFieldOptions ddmFormFieldOptions,
180                    Element dynamicElementElement) {
181    
182                    for (String optionValue : ddmFormFieldOptions.getOptionsValues()) {
183                            Element optionElement = addOptionDynamicElement(
184                                    optionValue, dynamicElementElement);
185    
186                            Map<Locale, Map<String, String>> optionLabelsMap =
187                                    getOptionLabelsMap(
188                                            ddmFormFieldOptions.getOptionLabels(optionValue));
189    
190                            addMetadataElements(optionLabelsMap, optionElement);
191                    }
192            }
193    
194            protected String getAvailableLanguagesIds(DDMForm ddmForm) {
195                    Set<Locale> availableLocales = ddmForm.getAvailableLocales();
196    
197                    String[] availableLanguageIds = LocaleUtil.toLanguageIds(
198                            availableLocales.toArray(new Locale[availableLocales.size()]));
199    
200                    return StringUtil.merge(availableLanguageIds);
201            }
202    
203            protected Map<Locale, Map<String, String>> getDDMFormFieldMetadataMap(
204                    DDMFormField ddmFormField) {
205    
206                    Map<Locale, Map<String, String>> ddmFormFieldMetadataMap =
207                            new HashMap<Locale, Map<String, String>>();
208    
209                    addMetadataEntryValues(
210                            ddmFormFieldMetadataMap, "label", ddmFormField.getLabel());
211    
212                    addMetadataEntryValues(
213                            ddmFormFieldMetadataMap, "predefinedValue",
214                            ddmFormField.getPredefinedValue());
215    
216                    addMetadataEntryValues(
217                            ddmFormFieldMetadataMap, "tip", ddmFormField.getTip());
218    
219                    return ddmFormFieldMetadataMap;
220            }
221    
222            protected Map<Locale, Map<String, String>> getOptionLabelsMap(
223                    LocalizedValue optionLabels) {
224    
225                    Map<Locale, Map<String, String>> optionLabelsMap =
226                            new HashMap<Locale, Map<String, String>>();
227    
228                    for (Locale availableLocale : optionLabels.getAvailableLocales()) {
229                            Map<String, String> optionMetadataEntries =
230                                    new HashMap<String, String>();
231    
232                            optionMetadataEntries.put(
233                                    "label", optionLabels.getString(availableLocale));
234    
235                            optionLabelsMap.put(availableLocale, optionMetadataEntries);
236                    }
237    
238                    return optionLabelsMap;
239            }
240    
241    }