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();
127    
128                    ddmFormValues.setDDMForm(ddmForm);
129                    ddmFormValues.setAvailableLocales(availableLocales);
130                    ddmFormValues.setDefaultLocale(defaultLocale);
131    
132                    return ddmFormValues;
133            }
134    
135            protected String getDDMFieldInstanceId(
136                    Fields ddmFields, String fieldName, int index) {
137    
138                    Field ddmFieldsDisplayField = ddmFields.get(
139                            DDMImpl.FIELDS_DISPLAY_NAME);
140    
141                    if (ddmFieldsDisplayField == null) {
142                            return StringUtil.randomString();
143                    }
144    
145                    String prefix = fieldName.concat(DDMImpl.INSTANCE_SEPARATOR);
146    
147                    String[] ddmFieldsDisplayValues = StringUtil.split(
148                            (String)ddmFieldsDisplayField.getValue());
149    
150                    for (String ddmFieldsDisplayValue : ddmFieldsDisplayValues) {
151                            if (ddmFieldsDisplayValue.startsWith(prefix)) {
152                                    index--;
153    
154                                    if (index < 0) {
155                                            return StringUtil.extractLast(
156                                                    ddmFieldsDisplayValue, DDMImpl.INSTANCE_SEPARATOR);
157                                    }
158                            }
159                    }
160    
161                    return null;
162            }
163    
164            protected String[] getDDMFieldsDisplayValues(Field ddmFieldsDisplayField)
165                    throws PortalException {
166    
167                    try {
168                            return DDMUtil.getFieldsDisplayValues(ddmFieldsDisplayField);
169                    }
170                    catch (Exception e) {
171                            throw new PortalException(e);
172                    }
173            }
174    
175            protected String getDDMFieldValueString(
176                    Field ddmField, Locale locale, int index) {
177    
178                    Serializable fieldValue = ddmField.getValue(locale, index);
179    
180                    if (fieldValue instanceof Date) {
181                            Date valueDate = (Date)fieldValue;
182    
183                            fieldValue = valueDate.getTime();
184                    }
185    
186                    return String.valueOf(fieldValue);
187            }
188    
189            protected void setDDMFormFieldValueInstanceId(
190                    DDMFormFieldValue ddmFormFieldValue, Fields ddmFields,
191                    DDMFieldsCounter ddmFieldsCounter) {
192    
193                    String name = ddmFormFieldValue.getName();
194    
195                    String instanceId = getDDMFieldInstanceId(
196                            ddmFields, name, ddmFieldsCounter.get(name));
197    
198                    ddmFormFieldValue.setInstanceId(instanceId);
199            }
200    
201            protected void setDDMFormFieldValueLocalizedValue(
202                    DDMFormFieldValue ddmFormFieldValue, Field ddmField, int index) {
203    
204                    Value value = new LocalizedValue(ddmField.getDefaultLocale());
205    
206                    for (Locale availableLocale : ddmField.getAvailableLocales()) {
207                            String valueString = getDDMFieldValueString(
208                                    ddmField, availableLocale, index);
209    
210                            value.addString(availableLocale, valueString);
211                    }
212    
213                    ddmFormFieldValue.setValue(value);
214            }
215    
216            protected void setDDMFormFieldValueProperties(
217                            DDMFormFieldValue ddmFormFieldValue, DDMStructure ddmStructure,
218                            Fields ddmFields, DDMFieldsCounter ddmFieldsCounter)
219                    throws PortalException {
220    
221                    setDDMFormFieldValueInstanceId(
222                            ddmFormFieldValue, ddmFields, ddmFieldsCounter);
223    
224                    setNestedDDMFormFieldValues(
225                            ddmFormFieldValue, ddmStructure, ddmFields, ddmFieldsCounter);
226    
227                    setDDMFormFieldValueValues(
228                            ddmFormFieldValue, ddmStructure, ddmFields, ddmFieldsCounter);
229            }
230    
231            protected void setDDMFormFieldValueUnlocalizedValue(
232                    DDMFormFieldValue ddmFormFieldValue, Field ddmField, int index) {
233    
234                    String valueString = getDDMFieldValueString(
235                            ddmField, ddmField.getDefaultLocale(), index);
236    
237                    Value value = new UnlocalizedValue(valueString);
238    
239                    ddmFormFieldValue.setValue(value);
240            }
241    
242            protected void setDDMFormFieldValueValues(
243                            DDMFormFieldValue ddmFormFieldValue, DDMStructure ddmStructure,
244                            Fields ddmFields, DDMFieldsCounter ddmFieldsCounter)
245                    throws PortalException {
246    
247                    String fieldName = ddmFormFieldValue.getName();
248    
249                    if (!ddmStructure.isFieldTransient(fieldName)) {
250                            DDMFormField ddmFormField = ddmStructure.getDDMFormField(fieldName);
251    
252                            if (ddmFormField.isLocalizable()) {
253                                    setDDMFormFieldValueLocalizedValue(
254                                            ddmFormFieldValue, ddmFields.get(fieldName),
255                                            ddmFieldsCounter.get(fieldName));
256                            }
257                            else {
258                                    setDDMFormFieldValueUnlocalizedValue(
259                                            ddmFormFieldValue, ddmFields.get(fieldName),
260                                            ddmFieldsCounter.get(fieldName));
261                            }
262                    }
263    
264                    ddmFieldsCounter.incrementKey(fieldName);
265            }
266    
267            protected void setNestedDDMFormFieldValues(
268                            DDMFormFieldValue ddmFormFieldValue, DDMStructure ddmStructure,
269                            Fields ddmFields, DDMFieldsCounter ddmFieldsCounter)
270                    throws PortalException {
271    
272                    String fieldName = ddmFormFieldValue.getName();
273    
274                    int parentOffset = ddmFieldsCounter.get(fieldName);
275    
276                    List<String> nestedFieldNames = ddmStructure.getChildrenFieldNames(
277                            fieldName);
278    
279                    for (String nestedFieldName : nestedFieldNames) {
280                            int repetitions = countDDMFieldRepetitions(
281                                    ddmFields, nestedFieldName, fieldName, parentOffset);
282    
283                            for (int i = 0; i < repetitions; i++) {
284                                    DDMFormFieldValue nestedDDMFormFieldValue =
285                                            createDDMFormFieldValue(nestedFieldName);
286    
287                                    setDDMFormFieldValueProperties(
288                                            nestedDDMFormFieldValue, ddmStructure, ddmFields,
289                                            ddmFieldsCounter);
290    
291                                    ddmFormFieldValue.addNestedDDMFormFieldValue(
292                                            nestedDDMFormFieldValue);
293                            }
294                    }
295            }
296    
297    }