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.exception.PortalException;
018    import com.liferay.portal.kernel.util.GetterUtil;
019    import com.liferay.portal.kernel.util.HtmlUtil;
020    import com.liferay.portal.kernel.util.LocaleUtil;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.StringUtil;
023    import com.liferay.portal.kernel.xml.Document;
024    import com.liferay.portal.kernel.xml.DocumentException;
025    import com.liferay.portal.kernel.xml.Element;
026    import com.liferay.portal.kernel.xml.SAXReaderUtil;
027    import com.liferay.portal.kernel.xml.XPath;
028    import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
029    import com.liferay.portlet.dynamicdatamapping.model.DDMFormField;
030    import com.liferay.portlet.dynamicdatamapping.model.DDMFormFieldOptions;
031    import com.liferay.portlet.dynamicdatamapping.model.LocalizedValue;
032    
033    import java.util.ArrayList;
034    import java.util.HashSet;
035    import java.util.List;
036    import java.util.Locale;
037    import java.util.Set;
038    
039    /**
040     * @author Pablo Carvalho
041     */
042    public class DDMFormXSDDeserializerImpl implements DDMFormXSDDeserializer {
043    
044            @Override
045            public DDMForm deserialize(String serializedDDMForm)
046                    throws PortalException {
047    
048                    try {
049                            Document document = SAXReaderUtil.read(serializedDDMForm);
050    
051                            DDMForm ddmForm = new DDMForm();
052    
053                            setDDMFormAvailableLocales(document.getRootElement(), ddmForm);
054                            setDDMFormDefaultLocale(document.getRootElement(), ddmForm);
055                            setDDMFormFields(document.getRootElement(), ddmForm);
056                            setDDMFormLocalizedValuesDefaultLocale(ddmForm);
057    
058                            return ddmForm;
059                    }
060                    catch (DocumentException de) {
061                            throw new PortalException(de);
062                    }
063            }
064    
065            protected void addOptionValueLabels(
066                    Element dynamicElementElement, DDMFormFieldOptions ddmFormFieldOptions,
067                    String optionValue) {
068    
069                    List<Element> metadataElements = dynamicElementElement.elements(
070                            "meta-data");
071    
072                    for (Element metadataElement : metadataElements) {
073                            String languageId = metadataElement.attributeValue("locale");
074    
075                            Locale locale = LocaleUtil.fromLanguageId(languageId);
076    
077                            Element labelElement = fetchMetadataEntry(metadataElement, "label");
078    
079                            ddmFormFieldOptions.addOptionLabel(
080                                    optionValue, locale, labelElement.getText());
081                    }
082            }
083    
084            protected Element fetchMetadataEntry(
085                    Element parentElement, String entryName) {
086    
087                    XPath xPathSelector = SAXReaderUtil.createXPath(
088                            "entry[@name=" + HtmlUtil.escapeXPathAttribute(entryName) +
089                                    StringPool.CLOSE_BRACKET);
090    
091                    return (Element)xPathSelector.selectSingleNode(parentElement);
092            }
093    
094            protected Set<Locale> getAvailableLocales(Element rootElement) {
095                    Set<Locale> availableLocales = new HashSet<Locale>();
096    
097                    String availableLanguageIds = rootElement.attributeValue(
098                            "available-locales");
099    
100                    for (String availableLanguageId :
101                                    StringUtil.split(availableLanguageIds)) {
102    
103                            Locale availableLocale = LocaleUtil.fromLanguageId(
104                                    availableLanguageId);
105    
106                            availableLocales.add(availableLocale);
107                    }
108    
109                    return availableLocales;
110            }
111    
112            protected DDMFormField getDDMFormField(Element dynamicElementElement) {
113                    String name = dynamicElementElement.attributeValue("name");
114                    String type = dynamicElementElement.attributeValue("type");
115    
116                    DDMFormField ddmFormField = new DDMFormField(name, type);
117    
118                    setDDMFormFieldDataType(dynamicElementElement, ddmFormField);
119                    setDDMFormFieldIndexType(dynamicElementElement, ddmFormField);
120                    setDDMFormFieldLocalizable(dynamicElementElement, ddmFormField);
121                    setDDMFormFieldMultiple(dynamicElementElement, ddmFormField);
122                    setDDMFormFieldNamespace(dynamicElementElement, ddmFormField);
123                    setDDMFormFieldReadOnly(dynamicElementElement, ddmFormField);
124                    setDDMFormFieldRepeatable(dynamicElementElement, ddmFormField);
125                    setDDMFormFieldRequired(dynamicElementElement, ddmFormField);
126                    setDDMFormFieldShowLabel(dynamicElementElement, ddmFormField);
127    
128                    List<Element> metadataElements = dynamicElementElement.elements(
129                            "meta-data");
130    
131                    for (Element metadataElement : metadataElements) {
132                            setDDMFormFieldMetadata(metadataElement, ddmFormField);
133                    }
134    
135                    if (type.equals("radio") || type.equals("select")) {
136                            setDDMFormFieldOptions(dynamicElementElement, ddmFormField);
137                    }
138                    else {
139                            setNestedDDMFormField(dynamicElementElement, ddmFormField);
140                    }
141    
142                    return ddmFormField;
143            }
144    
145            protected DDMFormFieldOptions getDDMFormFieldOptions(
146                    List<Element> dynamicElementElements) {
147    
148                    DDMFormFieldOptions ddmFormFieldOptions = new DDMFormFieldOptions();
149    
150                    for (Element dynamicElementElement : dynamicElementElements) {
151                            String value = dynamicElementElement.attributeValue("value");
152    
153                            ddmFormFieldOptions.addOption(value);
154    
155                            addOptionValueLabels(
156                                    dynamicElementElement, ddmFormFieldOptions, value);
157                    }
158    
159                    return ddmFormFieldOptions;
160            }
161    
162            protected List<DDMFormField> getDDMFormFields(Element rootElement) {
163                    List<DDMFormField> ddmFormFields = new ArrayList<DDMFormField>();
164    
165                    for (Element dynamicElement : rootElement.elements("dynamic-element")) {
166                            DDMFormField ddmFormField = getDDMFormField(dynamicElement);
167    
168                            ddmFormFields.add(ddmFormField);
169                    }
170    
171                    return ddmFormFields;
172            }
173    
174            protected Locale getDefaultLocale(Element rootElement) {
175                    String defaultLanguageId = rootElement.attributeValue("default-locale");
176    
177                    return LocaleUtil.fromLanguageId(defaultLanguageId);
178            }
179    
180            protected void setDDMFormAvailableLocales(
181                    Element rootElement, DDMForm ddmForm) {
182    
183                    Set<Locale> availableLocales = getAvailableLocales(rootElement);
184    
185                    ddmForm.setAvailableLocales(availableLocales);
186            }
187    
188            protected void setDDMFormDefaultLocale(
189                    Element rootElement, DDMForm ddmForm) {
190    
191                    Locale defaultLocale = getDefaultLocale(rootElement);
192    
193                    ddmForm.setDefaultLocale(defaultLocale);
194            }
195    
196            protected void setDDMFormFieldDataType(
197                    Element dynamicElementElement, DDMFormField ddmFormField) {
198    
199                    String dataType = dynamicElementElement.attributeValue("dataType");
200    
201                    ddmFormField.setDataType(dataType);
202            }
203    
204            protected void setDDMFormFieldIndexType(
205                    Element dynamicElementElement, DDMFormField ddmFormField) {
206    
207                    String indexType = dynamicElementElement.attributeValue("indexType");
208    
209                    ddmFormField.setIndexType(indexType);
210            }
211    
212            protected void setDDMFormFieldLocalizable(
213                    Element dynamicElementElement, DDMFormField ddmFormField) {
214    
215                    boolean localizable = GetterUtil.getBoolean(
216                            dynamicElementElement.attributeValue("localizable"), true);
217    
218                    ddmFormField.setLocalizable(localizable);
219            }
220    
221            protected void setDDMFormFieldLocalizedValuesDefaultLocale(
222                    DDMFormField ddmFormField, Locale defaultLocale) {
223    
224                    LocalizedValue label = ddmFormField.getLabel();
225    
226                    label.setDefaultLocale(defaultLocale);
227    
228                    LocalizedValue predefinedValue = ddmFormField.getPredefinedValue();
229    
230                    predefinedValue.setDefaultLocale(defaultLocale);
231    
232                    LocalizedValue style = ddmFormField.getStyle();
233    
234                    style.setDefaultLocale(defaultLocale);
235    
236                    LocalizedValue tip = ddmFormField.getTip();
237    
238                    tip.setDefaultLocale(defaultLocale);
239    
240                    DDMFormFieldOptions ddmFormFieldOptions =
241                            ddmFormField.getDDMFormFieldOptions();
242    
243                    ddmFormFieldOptions.setDefaultLocale(defaultLocale);
244    
245                    for (DDMFormField nestedDDMFormField :
246                                    ddmFormField.getNestedDDMFormFields()) {
247    
248                            setDDMFormFieldLocalizedValuesDefaultLocale(
249                                    nestedDDMFormField, defaultLocale);
250                    }
251            }
252    
253            protected void setDDMFormFieldMetadata(
254                    Element metadataElement, DDMFormField ddmFormField) {
255    
256                    String languageId = metadataElement.attributeValue("locale");
257    
258                    Locale locale = LocaleUtil.fromLanguageId(languageId);
259    
260                    Element labelElement = fetchMetadataEntry(metadataElement, "label");
261    
262                    if (labelElement != null) {
263                            LocalizedValue label = ddmFormField.getLabel();
264    
265                            label.addString(locale, labelElement.getText());
266                    }
267    
268                    Element predefinedValueElement = fetchMetadataEntry(
269                            metadataElement, "predefinedValue");
270    
271                    if (predefinedValueElement != null) {
272                            LocalizedValue predefinedValue = ddmFormField.getPredefinedValue();
273    
274                            predefinedValue.addString(locale, predefinedValueElement.getText());
275                    }
276    
277                    Element styleElement = fetchMetadataEntry(metadataElement, "style");
278    
279                    if (styleElement != null) {
280                            LocalizedValue style = ddmFormField.getStyle();
281    
282                            style.addString(locale, styleElement.getText());
283                    }
284    
285                    Element tipElement = fetchMetadataEntry(metadataElement, "tip");
286    
287                    if (tipElement != null) {
288                            LocalizedValue tip = ddmFormField.getTip();
289    
290                            tip.addString(locale, tipElement.getText());
291                    }
292            }
293    
294            protected void setDDMFormFieldMultiple(
295                    Element dynamicElementElement, DDMFormField ddmFormField) {
296    
297                    boolean multiple = GetterUtil.getBoolean(
298                            dynamicElementElement.attributeValue("multiple"));
299    
300                    ddmFormField.setMultiple(multiple);
301            }
302    
303            protected void setDDMFormFieldNamespace(
304                    Element dynamicElementElement, DDMFormField ddmFormField) {
305    
306                    String fieldNamespace = dynamicElementElement.attributeValue(
307                            "fieldNamespace");
308    
309                    ddmFormField.setNamespace(fieldNamespace);
310            }
311    
312            protected void setDDMFormFieldOptions(
313                    Element dynamicElementElement, DDMFormField ddmFormField) {
314    
315                    DDMFormFieldOptions ddmFormFieldOptions = getDDMFormFieldOptions(
316                            dynamicElementElement.elements("dynamic-element"));
317    
318                    ddmFormField.setDDMFormFieldOptions(ddmFormFieldOptions);
319            }
320    
321            protected void setDDMFormFieldReadOnly(
322                    Element dynamicElementElement, DDMFormField ddmFormField) {
323    
324                    boolean readOnly = GetterUtil.getBoolean(
325                            dynamicElementElement.attributeValue("readOnly"));
326    
327                    ddmFormField.setReadOnly(readOnly);
328            }
329    
330            protected void setDDMFormFieldRepeatable(
331                    Element dynamicElementElement, DDMFormField ddmFormField) {
332    
333                    boolean repeatable = GetterUtil.getBoolean(
334                            dynamicElementElement.attributeValue("repeatable"));
335    
336                    ddmFormField.setRepeatable(repeatable);
337            }
338    
339            protected void setDDMFormFieldRequired(
340                    Element dynamicElementElement, DDMFormField ddmFormField) {
341    
342                    boolean required = GetterUtil.getBoolean(
343                            dynamicElementElement.attributeValue("required"));
344    
345                    ddmFormField.setRequired(required);
346            }
347    
348            protected void setDDMFormFields(Element rootElement, DDMForm ddmForm) {
349                    List<DDMFormField> ddmFormFields = getDDMFormFields(rootElement);
350    
351                    ddmForm.setDDMFormFields(ddmFormFields);
352            }
353    
354            protected void setDDMFormFieldShowLabel(
355                    Element dynamicElementElement, DDMFormField ddmFormField) {
356    
357                    boolean showLabel = GetterUtil.getBoolean(
358                            dynamicElementElement.attributeValue("showLabel"), true);
359    
360                    ddmFormField.setShowLabel(showLabel);
361            }
362    
363            protected void setDDMFormLocalizedValuesDefaultLocale(DDMForm ddmForm) {
364                    for (DDMFormField ddmFormField : ddmForm.getDDMFormFields()) {
365                            setDDMFormFieldLocalizedValuesDefaultLocale(
366                                    ddmFormField, ddmForm.getDefaultLocale());
367                    }
368            }
369    
370            protected void setNestedDDMFormField(
371                    Element dynamicElementElement, DDMFormField ddmFormField) {
372    
373                    List<DDMFormField> nestedDDMFormFields = getDDMFormFields(
374                            dynamicElementElement);
375    
376                    ddmFormField.setNestedDDMFormFields(nestedDDMFormFields);
377            }
378    
379    }