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.util;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.util.StringUtil;
019    import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
020    import com.liferay.portlet.dynamicdatamapping.model.DDMFormField;
021    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
022    import com.liferay.portlet.dynamicdatamapping.model.LocalizedValue;
023    import com.liferay.portlet.dynamicdatamapping.model.UnlocalizedValue;
024    import com.liferay.portlet.dynamicdatamapping.model.Value;
025    import com.liferay.portlet.dynamicdatamapping.storage.DDMFormFieldValue;
026    import com.liferay.portlet.dynamicdatamapping.storage.DDMFormValues;
027    import com.liferay.portlet.dynamicdatamapping.storage.Field;
028    import com.liferay.portlet.dynamicdatamapping.storage.Fields;
029    
030    import java.io.Serializable;
031    
032    import java.util.Date;
033    import java.util.List;
034    import java.util.Locale;
035    import java.util.Set;
036    
037    /**
038     * @author Marcellus Tavares
039     */
040    public class FieldsToDDMFormValuesConverterImpl
041            implements FieldsToDDMFormValuesConverter {
042    
043            @Override
044            public DDMFormValues convert(DDMStructure ddmStructure, Fields fields)
045                    throws PortalException {
046    
047                    DDMFormValues ddmFormValues = createDDMFormValues(
048                            ddmStructure.getDDMForm(), fields.getAvailableLocales(),
049                            fields.getDefaultLocale());
050    
051                    DDMFieldsCounter ddmFieldsCounter = new DDMFieldsCounter();
052    
053                    for (String fieldName : ddmStructure.getRootFieldNames()) {
054                            int repetitions = countDDMFieldRepetitions(
055                                    fields, fieldName, null, -1);
056    
057                            for (int i = 0; i < repetitions; i++) {
058                                    DDMFormFieldValue ddmFormFieldValue = createDDMFormFieldValue(
059                                            fieldName);
060    
061                                    setDDMFormFieldValueProperties(
062                                            ddmFormFieldValue, ddmStructure, fields, ddmFieldsCounter);
063    
064                                    ddmFormValues.addDDMFormFieldValue(ddmFormFieldValue);
065                            }
066                    }
067    
068                    return ddmFormValues;
069            }
070    
071            protected int countDDMFieldRepetitions(
072                            Fields ddmFields, String fieldName, String parentFieldName,
073                            int parentOffset)
074                    throws PortalException {
075    
076                    Field ddmFieldsDisplayField = ddmFields.get(
077                            DDMImpl.FIELDS_DISPLAY_NAME);
078    
079                    if (ddmFieldsDisplayField == null) {
080                            if (ddmFields.contains(fieldName)) {
081                                    return 1;
082                            }
083    
084                            return 0;
085                    }
086    
087                    String[] ddmFieldsDisplayValues = getDDMFieldsDisplayValues(
088                            ddmFieldsDisplayField);
089    
090                    int offset = -1;
091    
092                    int repetitions = 0;
093    
094                    for (int i = 0; i < ddmFieldsDisplayValues.length; i++) {
095                            String fieldDisplayName = ddmFieldsDisplayValues[i];
096    
097                            if (offset > parentOffset) {
098                                    break;
099                            }
100    
101                            if (fieldDisplayName.equals(parentFieldName)) {
102                                    offset++;
103                            }
104    
105                            if (fieldDisplayName.equals(fieldName) &&
106                                    (offset == parentOffset)) {
107    
108                                    repetitions++;
109                            }
110                    }
111    
112                    return repetitions;
113            }
114    
115            protected DDMFormFieldValue createDDMFormFieldValue(String name) {
116                    DDMFormFieldValue ddmFormFieldValue = new DDMFormFieldValue();
117    
118                    ddmFormFieldValue.setName(name);
119    
120                    return ddmFormFieldValue;
121            }
122    
123            protected DDMFormValues createDDMFormValues(
124                    DDMForm ddmForm, Set<Locale> availableLocales, Locale defaultLocale) {
125    
126                    DDMFormValues ddmFormValues = new DDMFormValues(ddmForm);
127    
128                    ddmFormValues.setAvailableLocales(availableLocales);
129                    ddmFormValues.setDefaultLocale(defaultLocale);
130    
131                    return ddmFormValues;
132            }
133    
134            protected String getDDMFieldInstanceId(
135                    Fields ddmFields, String fieldName, int index) {
136    
137                    Field ddmFieldsDisplayField = ddmFields.get(
138                            DDMImpl.FIELDS_DISPLAY_NAME);
139    
140                    if (ddmFieldsDisplayField == null) {
141                            return StringUtil.randomString();
142                    }
143    
144                    String prefix = fieldName.concat(DDMImpl.INSTANCE_SEPARATOR);
145    
146                    String[] ddmFieldsDisplayValues = StringUtil.split(
147                            (String)ddmFieldsDisplayField.getValue());
148    
149                    for (String ddmFieldsDisplayValue : ddmFieldsDisplayValues) {
150                            if (ddmFieldsDisplayValue.startsWith(prefix)) {
151                                    index--;
152    
153                                    if (index < 0) {
154                                            return StringUtil.extractLast(
155                                                    ddmFieldsDisplayValue, DDMImpl.INSTANCE_SEPARATOR);
156                                    }
157                            }
158                    }
159    
160                    return null;
161            }
162    
163            protected String[] getDDMFieldsDisplayValues(Field ddmFieldsDisplayField)
164                    throws PortalException {
165    
166                    try {
167                            return DDMUtil.getFieldsDisplayValues(ddmFieldsDisplayField);
168                    }
169                    catch (Exception e) {
170                            throw new PortalException(e);
171                    }
172            }
173    
174            protected String getDDMFieldValueString(
175                    Field ddmField, Locale locale, int index) {
176    
177                    Serializable fieldValue = ddmField.getValue(locale, index);
178    
179                    if (fieldValue instanceof Date) {
180                            Date valueDate = (Date)fieldValue;
181    
182                            fieldValue = valueDate.getTime();
183                    }
184    
185                    return String.valueOf(fieldValue);
186            }
187    
188            protected void setDDMFormFieldValueInstanceId(
189                    DDMFormFieldValue ddmFormFieldValue, Fields ddmFields,
190                    DDMFieldsCounter ddmFieldsCounter) {
191    
192                    String name = ddmFormFieldValue.getName();
193    
194                    String instanceId = getDDMFieldInstanceId(
195                            ddmFields, name, ddmFieldsCounter.get(name));
196    
197                    ddmFormFieldValue.setInstanceId(instanceId);
198            }
199    
200            protected void setDDMFormFieldValueLocalizedValue(
201                    DDMFormFieldValue ddmFormFieldValue, Field ddmField, int index) {
202    
203                    Value value = new LocalizedValue(ddmField.getDefaultLocale());
204    
205                    for (Locale availableLocale : ddmField.getAvailableLocales()) {
206                            String valueString = getDDMFieldValueString(
207                                    ddmField, availableLocale, index);
208    
209                            value.addString(availableLocale, valueString);
210                    }
211    
212                    ddmFormFieldValue.setValue(value);
213            }
214    
215            protected void setDDMFormFieldValueProperties(
216                            DDMFormFieldValue ddmFormFieldValue, DDMStructure ddmStructure,
217                            Fields ddmFields, DDMFieldsCounter ddmFieldsCounter)
218                    throws PortalException {
219    
220                    setDDMFormFieldValueInstanceId(
221                            ddmFormFieldValue, ddmFields, ddmFieldsCounter);
222    
223                    setNestedDDMFormFieldValues(
224                            ddmFormFieldValue, ddmStructure, ddmFields, ddmFieldsCounter);
225    
226                    setDDMFormFieldValueValues(
227                            ddmFormFieldValue, ddmStructure, ddmFields, ddmFieldsCounter);
228            }
229    
230            protected void setDDMFormFieldValueUnlocalizedValue(
231                    DDMFormFieldValue ddmFormFieldValue, Field ddmField, int index) {
232    
233                    String valueString = getDDMFieldValueString(
234                            ddmField, ddmField.getDefaultLocale(), index);
235    
236                    Value value = new UnlocalizedValue(valueString);
237    
238                    ddmFormFieldValue.setValue(value);
239            }
240    
241            protected void setDDMFormFieldValueValues(
242                            DDMFormFieldValue ddmFormFieldValue, DDMStructure ddmStructure,
243                            Fields ddmFields, DDMFieldsCounter ddmFieldsCounter)
244                    throws PortalException {
245    
246                    String fieldName = ddmFormFieldValue.getName();
247    
248                    if (!ddmStructure.isFieldTransient(fieldName)) {
249                            DDMFormField ddmFormField = ddmStructure.getDDMFormField(fieldName);
250    
251                            if (ddmFormField.isLocalizable()) {
252                                    setDDMFormFieldValueLocalizedValue(
253                                            ddmFormFieldValue, ddmFields.get(fieldName),
254                                            ddmFieldsCounter.get(fieldName));
255                            }
256                            else {
257                                    setDDMFormFieldValueUnlocalizedValue(
258                                            ddmFormFieldValue, ddmFields.get(fieldName),
259                                            ddmFieldsCounter.get(fieldName));
260                            }
261                    }
262    
263                    ddmFieldsCounter.incrementKey(fieldName);
264            }
265    
266            protected void setNestedDDMFormFieldValues(
267                            DDMFormFieldValue ddmFormFieldValue, DDMStructure ddmStructure,
268                            Fields ddmFields, DDMFieldsCounter ddmFieldsCounter)
269                    throws PortalException {
270    
271                    String fieldName = ddmFormFieldValue.getName();
272    
273                    int parentOffset = ddmFieldsCounter.get(fieldName);
274    
275                    List<String> nestedFieldNames = ddmStructure.getChildrenFieldNames(
276                            fieldName);
277    
278                    for (String nestedFieldName : nestedFieldNames) {
279                            int repetitions = countDDMFieldRepetitions(
280                                    ddmFields, nestedFieldName, fieldName, parentOffset);
281    
282                            for (int i = 0; i < repetitions; i++) {
283                                    DDMFormFieldValue nestedDDMFormFieldValue =
284                                            createDDMFormFieldValue(nestedFieldName);
285    
286                                    setDDMFormFieldValueProperties(
287                                            nestedDDMFormFieldValue, ddmStructure, ddmFields,
288                                            ddmFieldsCounter);
289    
290                                    ddmFormFieldValue.addNestedDDMFormFieldValue(
291                                            nestedDDMFormFieldValue);
292                            }
293                    }
294            }
295    
296    }