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.json.JSONArray;
019    import com.liferay.portal.kernel.json.JSONFactoryUtil;
020    import com.liferay.portal.kernel.json.JSONObject;
021    import com.liferay.portal.kernel.language.LanguageUtil;
022    import com.liferay.portal.kernel.repository.model.FileEntry;
023    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
024    import com.liferay.portal.kernel.upload.UploadRequest;
025    import com.liferay.portal.kernel.util.ArrayUtil;
026    import com.liferay.portal.kernel.util.DateFormatFactoryUtil;
027    import com.liferay.portal.kernel.util.FileUtil;
028    import com.liferay.portal.kernel.util.GetterUtil;
029    import com.liferay.portal.kernel.util.HttpUtil;
030    import com.liferay.portal.kernel.util.ListUtil;
031    import com.liferay.portal.kernel.util.LocaleUtil;
032    import com.liferay.portal.kernel.util.OrderByComparator;
033    import com.liferay.portal.kernel.util.StringPool;
034    import com.liferay.portal.kernel.util.StringUtil;
035    import com.liferay.portal.kernel.util.UnicodeFormatter;
036    import com.liferay.portal.kernel.util.Validator;
037    import com.liferay.portal.model.Image;
038    import com.liferay.portal.model.Layout;
039    import com.liferay.portal.service.ImageLocalServiceUtil;
040    import com.liferay.portal.service.LayoutLocalServiceUtil;
041    import com.liferay.portal.service.ServiceContext;
042    import com.liferay.portal.theme.ThemeDisplay;
043    import com.liferay.portal.util.PortalUtil;
044    import com.liferay.portal.util.PropsValues;
045    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
046    import com.liferay.portlet.documentlibrary.util.DLUtil;
047    import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
048    import com.liferay.portlet.dynamicdatamapping.io.DDMFormValuesJSONDeserializerUtil;
049    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
050    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
051    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
052    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
053    import com.liferay.portlet.dynamicdatamapping.storage.DDMFormValues;
054    import com.liferay.portlet.dynamicdatamapping.storage.Field;
055    import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
056    import com.liferay.portlet.dynamicdatamapping.storage.Fields;
057    import com.liferay.portlet.dynamicdatamapping.util.comparator.StructureIdComparator;
058    import com.liferay.portlet.dynamicdatamapping.util.comparator.StructureModifiedDateComparator;
059    import com.liferay.portlet.dynamicdatamapping.util.comparator.TemplateIdComparator;
060    import com.liferay.portlet.dynamicdatamapping.util.comparator.TemplateModifiedDateComparator;
061    
062    import java.io.File;
063    import java.io.Serializable;
064    
065    import java.text.DateFormat;
066    
067    import java.util.ArrayList;
068    import java.util.Date;
069    import java.util.HashSet;
070    import java.util.Iterator;
071    import java.util.List;
072    import java.util.Locale;
073    import java.util.Map;
074    import java.util.Set;
075    
076    import javax.servlet.http.HttpServletRequest;
077    
078    /**
079     * @author Eduardo Lundgren
080     * @author Brian Wing Shun Chan
081     * @author Eduardo Garcia
082     * @author Marcellus Tavares
083     */
084    @DoPrivileged
085    public class DDMImpl implements DDM {
086    
087            public static final String FIELDS_DISPLAY_NAME = "_fieldsDisplay";
088    
089            public static final String INSTANCE_SEPARATOR = "_INSTANCE_";
090    
091            public static final String TYPE_CHECKBOX = "checkbox";
092    
093            public static final String TYPE_DDM_DATE = "ddm-date";
094    
095            public static final String TYPE_DDM_DOCUMENTLIBRARY = "ddm-documentlibrary";
096    
097            public static final String TYPE_DDM_IMAGE = "ddm-image";
098    
099            public static final String TYPE_DDM_LINK_TO_PAGE = "ddm-link-to-page";
100    
101            public static final String TYPE_DDM_TEXT_HTML = "ddm-text-html";
102    
103            public static final String TYPE_RADIO = "radio";
104    
105            public static final String TYPE_SELECT = "select";
106    
107            @Override
108            public DDMDisplay getDDMDisplay(ServiceContext serviceContext) {
109                    String refererPortletName = (String)serviceContext.getAttribute(
110                            "refererPortletName");
111    
112                    if (refererPortletName == null) {
113                            refererPortletName = serviceContext.getPortletId();
114    
115                            if (refererPortletName == null) {
116                                    throw new IllegalArgumentException(
117                                            "Service context must have values for either " +
118                                                    "the referer portlet nme or portlet preference IDs");
119                            }
120                    }
121    
122                    return DDMDisplayRegistryUtil.getDDMDisplay(refererPortletName);
123            }
124    
125            @Override
126            public Serializable getDisplayFieldValue(
127                            ThemeDisplay themeDisplay, Serializable fieldValue, String type)
128                    throws Exception {
129    
130                    if (fieldValue instanceof Date) {
131                            Date valueDate = (Date)fieldValue;
132    
133                            DateFormat dateFormat = DateFormatFactoryUtil.getDate(
134                                    themeDisplay.getLocale());
135    
136                            fieldValue = dateFormat.format(valueDate);
137                    }
138                    else if (type.equals(DDMImpl.TYPE_CHECKBOX)) {
139                            Boolean valueBoolean = (Boolean)fieldValue;
140    
141                            if (valueBoolean) {
142                                    fieldValue = LanguageUtil.get(themeDisplay.getLocale(), "yes");
143                            }
144                            else {
145                                    fieldValue = LanguageUtil.get(themeDisplay.getLocale(), "no");
146                            }
147                    }
148                    else if (type.equals(DDMImpl.TYPE_DDM_DOCUMENTLIBRARY)) {
149                            if (Validator.isNull(fieldValue)) {
150                                    return StringPool.BLANK;
151                            }
152    
153                            String valueString = String.valueOf(fieldValue);
154    
155                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
156                                    valueString);
157    
158                            String uuid = jsonObject.getString("uuid");
159                            long groupId = jsonObject.getLong("groupId");
160    
161                            FileEntry fileEntry =
162                                    DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
163                                            uuid, groupId);
164    
165                            fieldValue = DLUtil.getPreviewURL(
166                                    fileEntry, fileEntry.getFileVersion(), null, StringPool.BLANK,
167                                    false, true);
168                    }
169                    else if (type.equals(DDMImpl.TYPE_DDM_LINK_TO_PAGE)) {
170                            if (Validator.isNull(fieldValue)) {
171                                    return StringPool.BLANK;
172                            }
173    
174                            String valueString = String.valueOf(fieldValue);
175    
176                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
177                                    valueString);
178    
179                            long groupId = jsonObject.getLong("groupId");
180                            boolean privateLayout = jsonObject.getBoolean("privateLayout");
181                            long layoutId = jsonObject.getLong("layoutId");
182    
183                            Layout layout = LayoutLocalServiceUtil.getLayout(
184                                    groupId, privateLayout, layoutId);
185    
186                            fieldValue = PortalUtil.getLayoutFriendlyURL(layout, themeDisplay);
187                    }
188                    else if (type.equals(DDMImpl.TYPE_RADIO) ||
189                                     type.equals(DDMImpl.TYPE_SELECT)) {
190    
191                            String valueString = String.valueOf(fieldValue);
192    
193                            JSONArray jsonArray = JSONFactoryUtil.createJSONArray(valueString);
194    
195                            String[] stringArray = ArrayUtil.toStringArray(jsonArray);
196    
197                            fieldValue = stringArray[0];
198                    }
199    
200                    return fieldValue;
201            }
202    
203            @Override
204            public Fields getFields(
205                            long ddmStructureId, long ddmTemplateId,
206                            ServiceContext serviceContext)
207                    throws PortalException {
208    
209                    return getFields(
210                            ddmStructureId, ddmTemplateId, StringPool.BLANK, serviceContext);
211            }
212    
213            @Override
214            public Fields getFields(
215                            long ddmStructureId, long ddmTemplateId, String fieldNamespace,
216                            ServiceContext serviceContext)
217                    throws PortalException {
218    
219                    DDMStructure ddmStructure = getDDMStructure(
220                            ddmStructureId, ddmTemplateId);
221    
222                    Set<String> fieldNames = ddmStructure.getFieldNames();
223    
224                    boolean translating = true;
225    
226                    String defaultLanguageId = (String)serviceContext.getAttribute(
227                            "defaultLanguageId");
228                    String toLanguageId = (String)serviceContext.getAttribute(
229                            "toLanguageId");
230    
231                    if (Validator.isNull(toLanguageId) ||
232                            Validator.equals(defaultLanguageId, toLanguageId)) {
233    
234                            translating = false;
235                    }
236    
237                    Fields fields = new Fields();
238    
239                    for (String fieldName : fieldNames) {
240                            boolean localizable = GetterUtil.getBoolean(
241                                    ddmStructure.getFieldProperty(fieldName, "localizable"), true);
242    
243                            if (!localizable && translating &&
244                                    !ddmStructure.isFieldPrivate(fieldName)) {
245    
246                                    continue;
247                            }
248    
249                            List<Serializable> fieldValues = getFieldValues(
250                                    ddmStructure, fieldName, fieldNamespace, serviceContext);
251    
252                            if ((fieldValues == null) || fieldValues.isEmpty()) {
253                                    continue;
254                            }
255    
256                            Field field = createField(
257                                    ddmStructure, fieldName, fieldValues, serviceContext);
258    
259                            fields.put(field);
260                    }
261    
262                    return fields;
263            }
264    
265            @Override
266            public Fields getFields(long ddmStructureId, ServiceContext serviceContext)
267                    throws PortalException {
268    
269                    String serializedDDMFormValues = GetterUtil.getString(
270                            serviceContext.getAttribute("ddmFormValues"));
271    
272                    if (Validator.isNotNull(serializedDDMFormValues)) {
273                            return getFields(ddmStructureId, serializedDDMFormValues);
274                    }
275    
276                    return getFields(ddmStructureId, 0, serviceContext);
277            }
278    
279            @Override
280            public Fields getFields(
281                            long ddmStructureId, String fieldNamespace,
282                            ServiceContext serviceContext)
283                    throws PortalException {
284    
285                    String serializedDDMFormValues = GetterUtil.getString(
286                            serviceContext.getAttribute(fieldNamespace + "ddmFormValues"));
287    
288                    if (Validator.isNotNull(serializedDDMFormValues)) {
289                            return getFields(ddmStructureId, serializedDDMFormValues);
290                    }
291    
292                    return getFields(ddmStructureId, 0, fieldNamespace, serviceContext);
293            }
294    
295            @Override
296            public String[] getFieldsDisplayValues(Field fieldsDisplayField)
297                    throws Exception {
298    
299                    DDMStructure ddmStructure = fieldsDisplayField.getDDMStructure();
300    
301                    List<String> fieldsDisplayValues = new ArrayList<String>();
302    
303                    String[] values = splitFieldsDisplayValue(fieldsDisplayField);
304    
305                    for (String value : values) {
306                            String fieldName = StringUtil.extractFirst(
307                                    value, DDMImpl.INSTANCE_SEPARATOR);
308    
309                            if (ddmStructure.hasField(fieldName)) {
310                                    fieldsDisplayValues.add(fieldName);
311                            }
312                    }
313    
314                    return fieldsDisplayValues.toArray(
315                            new String[fieldsDisplayValues.size()]);
316            }
317    
318            @Override
319            public Serializable getIndexedFieldValue(
320                            Serializable fieldValue, String type)
321                    throws Exception {
322    
323                    if (fieldValue instanceof Date) {
324                            Date valueDate = (Date)fieldValue;
325    
326                            DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat(
327                                    "yyyyMMddHHmmss");
328    
329                            fieldValue = dateFormat.format(valueDate);
330                    }
331                    else if (type.equals(DDMImpl.TYPE_RADIO) ||
332                                     type.equals(DDMImpl.TYPE_SELECT)) {
333    
334                            String valueString = (String)fieldValue;
335    
336                            JSONArray jsonArray = JSONFactoryUtil.createJSONArray(valueString);
337    
338                            String[] stringArray = ArrayUtil.toStringArray(jsonArray);
339    
340                            fieldValue = stringArray[0];
341                    }
342    
343                    return fieldValue;
344            }
345    
346            @Override
347            public OrderByComparator<DDMStructure> getStructureOrderByComparator(
348                    String orderByCol, String orderByType) {
349    
350                    boolean orderByAsc = false;
351    
352                    if (orderByType.equals("asc")) {
353                            orderByAsc = true;
354                    }
355    
356                    OrderByComparator<DDMStructure> orderByComparator = null;
357    
358                    if (orderByCol.equals("id")) {
359                            orderByComparator = new StructureIdComparator(orderByAsc);
360                    }
361                    else if (orderByCol.equals("modified-date")) {
362                            orderByComparator = new StructureModifiedDateComparator(orderByAsc);
363                    }
364    
365                    return orderByComparator;
366            }
367    
368            @Override
369            public OrderByComparator<DDMTemplate> getTemplateOrderByComparator(
370                    String orderByCol, String orderByType) {
371    
372                    boolean orderByAsc = false;
373    
374                    if (orderByType.equals("asc")) {
375                            orderByAsc = true;
376                    }
377    
378                    OrderByComparator<DDMTemplate> orderByComparator = null;
379    
380                    if (orderByCol.equals("id")) {
381                            orderByComparator = new TemplateIdComparator(orderByAsc);
382                    }
383                    else if (orderByCol.equals("modified-date")) {
384                            orderByComparator = new TemplateModifiedDateComparator(orderByAsc);
385                    }
386    
387                    return orderByComparator;
388            }
389    
390            @Override
391            public Fields mergeFields(Fields newFields, Fields existingFields) {
392                    String[] newFieldsDisplayValues = splitFieldsDisplayValue(
393                            newFields.get(DDMImpl.FIELDS_DISPLAY_NAME));
394    
395                    String[] existingFieldsDisplayValues = splitFieldsDisplayValue(
396                            existingFields.get(DDMImpl.FIELDS_DISPLAY_NAME));
397    
398                    Iterator<Field> itr = newFields.iterator(true);
399    
400                    while (itr.hasNext()) {
401                            Field newField = itr.next();
402    
403                            Field existingField = existingFields.get(newField.getName());
404    
405                            if ((existingField == null) || newField.isPrivate()) {
406                                    existingFields.put(newField);
407    
408                                    continue;
409                            }
410    
411                            existingField.setDefaultLocale(newField.getDefaultLocale());
412    
413                            Map<Locale, List<Serializable>> mergedFieldValuesMap =
414                                    getMergedFieldValuesMap(
415                                            newField, newFieldsDisplayValues, existingField,
416                                            existingFieldsDisplayValues);
417    
418                            existingField.setValuesMap(mergedFieldValuesMap);
419                    }
420    
421                    return existingFields;
422            }
423    
424            protected int countFieldRepetition(
425                    String[] fieldsDisplayValues, String fieldName) {
426    
427                    int count = 0;
428    
429                    for (String fieldsDisplayValue : fieldsDisplayValues) {
430                            String prefix = StringUtil.extractFirst(
431                                    fieldsDisplayValue, INSTANCE_SEPARATOR);
432    
433                            if (prefix.equals(fieldName)) {
434                                    count++;
435                            }
436                    }
437    
438                    return count;
439            }
440    
441            protected Field createField(
442                    DDMStructure ddmStructure, String fieldName,
443                    List<Serializable> fieldValues, ServiceContext serviceContext) {
444    
445                    Field field = new Field();
446    
447                    field.setDDMStructureId(ddmStructure.getStructureId());
448    
449                    String languageId = GetterUtil.getString(
450                            serviceContext.getAttribute("languageId"),
451                            serviceContext.getLanguageId());
452    
453                    Locale locale = LocaleUtil.fromLanguageId(languageId);
454    
455                    String defaultLanguageId = GetterUtil.getString(
456                            serviceContext.getAttribute("defaultLanguageId"));
457    
458                    Locale defaultLocale = LocaleUtil.fromLanguageId(defaultLanguageId);
459    
460                    if (ddmStructure.isFieldPrivate(fieldName)) {
461                            locale = LocaleUtil.getSiteDefault();
462    
463                            defaultLocale = LocaleUtil.getSiteDefault();
464                    }
465    
466                    field.setDefaultLocale(defaultLocale);
467    
468                    field.setName(fieldName);
469                    field.setValues(locale, fieldValues);
470    
471                    return field;
472            }
473    
474            protected DDMStructure getDDMStructure(
475                            long ddmStructureId, long ddmTemplateId)
476                    throws PortalException {
477    
478                    DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(
479                            ddmStructureId);
480    
481                    try {
482                            DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
483                                    ddmTemplateId);
484    
485                            // Clone ddmStructure to make sure changes are never persisted
486    
487                            ddmStructure = (DDMStructure)ddmStructure.clone();
488    
489                            ddmStructure.setDefinition(ddmTemplate.getScript());
490                    }
491                    catch (NoSuchTemplateException nste) {
492                    }
493    
494                    return ddmStructure;
495            }
496    
497            protected int getExistingFieldValueIndex(
498                    String[] newFieldsDisplayValues, String[] existingFieldsDisplayValues,
499                    String fieldName, int index) {
500    
501                    String instanceId = getFieldIntanceId(
502                            newFieldsDisplayValues, fieldName, index);
503    
504                    return getFieldValueIndex(
505                            existingFieldsDisplayValues, fieldName, instanceId);
506            }
507    
508            protected String getFieldIntanceId(
509                    String[] fieldsDisplayValues, String fieldName, int index) {
510    
511                    String prefix = fieldName.concat(INSTANCE_SEPARATOR);
512    
513                    for (String fieldsDisplayValue : fieldsDisplayValues) {
514                            if (fieldsDisplayValue.startsWith(prefix)) {
515                                    index--;
516    
517                                    if (index < 0) {
518                                            return StringUtil.extractLast(
519                                                    fieldsDisplayValue, DDMImpl.INSTANCE_SEPARATOR);
520                                    }
521                            }
522                    }
523    
524                    return null;
525            }
526    
527            protected List<String> getFieldNames(
528                    String fieldNamespace, String fieldName,
529                    ServiceContext serviceContext) {
530    
531                    String[] fieldsDisplayValues = StringUtil.split(
532                            (String)serviceContext.getAttribute(
533                                    fieldNamespace + FIELDS_DISPLAY_NAME));
534    
535                    List<String> privateFieldNames = ListUtil.fromArray(
536                            PropsValues.DYNAMIC_DATA_MAPPING_STRUCTURE_PRIVATE_FIELD_NAMES);
537    
538                    List<String> fieldNames = new ArrayList<String>();
539    
540                    if ((fieldsDisplayValues.length == 0) ||
541                            privateFieldNames.contains(fieldName)) {
542    
543                            fieldNames.add(fieldNamespace + fieldName);
544                    }
545                    else {
546                            for (String namespacedFieldName : fieldsDisplayValues) {
547                                    String fieldNameValue = StringUtil.extractFirst(
548                                            namespacedFieldName, INSTANCE_SEPARATOR);
549    
550                                    if (fieldNameValue.equals(fieldName)) {
551                                            fieldNames.add(fieldNamespace + namespacedFieldName);
552                                    }
553                            }
554                    }
555    
556                    return fieldNames;
557            }
558    
559            protected Fields getFields(
560                            long ddmStructureId, String serializedDDMFormValues)
561                    throws PortalException {
562    
563                    DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(
564                            ddmStructureId);
565    
566                    DDMFormValues ddmFormValues =
567                            DDMFormValuesJSONDeserializerUtil.deserialize(
568                                    ddmStructure.getFullHierarchyDDMForm(),
569                                    serializedDDMFormValues);
570    
571                    return DDMFormValuesToFieldsConverterUtil.convert(
572                            ddmStructure, ddmFormValues);
573            }
574    
575            protected int getFieldValueIndex(
576                    String[] fieldsDisplayValues, String fieldName, String instanceId) {
577    
578                    if (instanceId == null) {
579                            return -1;
580                    }
581    
582                    int offset = 0;
583    
584                    for (String fieldsDisplayValue : fieldsDisplayValues) {
585                            if (fieldsDisplayValue.startsWith(fieldName)) {
586                                    String fieldIstanceId = StringUtil.extractLast(
587                                            fieldsDisplayValue, DDMImpl.INSTANCE_SEPARATOR);
588    
589                                    if (fieldIstanceId.equals(instanceId)) {
590                                            return offset;
591                                    }
592    
593                                    offset++;
594                            }
595                    }
596    
597                    return -1;
598            }
599    
600            protected List<Serializable> getFieldValues(
601                            DDMStructure ddmStructure, String fieldName, String fieldNamespace,
602                            ServiceContext serviceContext)
603                    throws PortalException {
604    
605                    String fieldDataType = ddmStructure.getFieldDataType(fieldName);
606                    String fieldType = ddmStructure.getFieldType(fieldName);
607    
608                    List<String> fieldNames = getFieldNames(
609                            fieldNamespace, fieldName, serviceContext);
610    
611                    List<Serializable> fieldValues = new ArrayList<Serializable>(
612                            fieldNames.size());
613    
614                    for (String fieldNameValue : fieldNames) {
615                            Serializable fieldValue = serviceContext.getAttribute(
616                                    fieldNameValue);
617    
618                            if (fieldType.equals(DDMImpl.TYPE_CHECKBOX) &&
619                                    Validator.isNull(fieldValue)) {
620    
621                                    fieldValue = "false";
622                            }
623                            else if (fieldDataType.equals(FieldConstants.DATE)) {
624                                    int fieldValueMonth = GetterUtil.getInteger(
625                                            serviceContext.getAttribute(fieldNameValue + "Month"));
626                                    int fieldValueDay = GetterUtil.getInteger(
627                                            serviceContext.getAttribute(fieldNameValue + "Day"));
628                                    int fieldValueYear = GetterUtil.getInteger(
629                                            serviceContext.getAttribute(fieldNameValue + "Year"));
630    
631                                    Date fieldValueDate = PortalUtil.getDate(
632                                            fieldValueMonth, fieldValueDay, fieldValueYear);
633    
634                                    if (fieldValueDate != null) {
635                                            fieldValue = String.valueOf(fieldValueDate.getTime());
636                                    }
637                            }
638                            else if (fieldDataType.equals(FieldConstants.IMAGE) &&
639                                             Validator.isNull(fieldValue)) {
640    
641                                    HttpServletRequest request = serviceContext.getRequest();
642    
643                                    if (!(request instanceof UploadRequest)) {
644                                            return null;
645                                    }
646    
647                                    fieldValue = getImageFieldValue(
648                                            (UploadRequest)request, fieldNameValue);
649                            }
650    
651                            if (fieldValue == null) {
652                                    return null;
653                            }
654    
655                            if (DDMImpl.TYPE_RADIO.equals(fieldType) ||
656                                    DDMImpl.TYPE_SELECT.equals(fieldType)) {
657    
658                                    if (fieldValue instanceof String) {
659                                            fieldValue = new String[] {String.valueOf(fieldValue)};
660                                    }
661    
662                                    fieldValue = JSONFactoryUtil.serialize(fieldValue);
663                            }
664    
665                            Serializable fieldValueSerializable =
666                                    FieldConstants.getSerializable(
667                                            fieldDataType, GetterUtil.getString(fieldValue));
668    
669                            fieldValues.add(fieldValueSerializable);
670                    }
671    
672                    return fieldValues;
673            }
674    
675            protected List<Serializable> getFieldValues(Field field, Locale locale) {
676                    Map<Locale, List<Serializable>> fieldValuesMap = field.getValuesMap();
677    
678                    return fieldValuesMap.get(locale);
679            }
680    
681            protected byte[] getImageBytes(
682                            UploadRequest uploadRequest, String fieldNameValue)
683                    throws Exception {
684    
685                    File file = uploadRequest.getFile(fieldNameValue + "File");
686    
687                    byte[] bytes = FileUtil.getBytes(file);
688    
689                    if (ArrayUtil.isNotEmpty(bytes)) {
690                            return bytes;
691                    }
692    
693                    String url = uploadRequest.getParameter(fieldNameValue + "URL");
694    
695                    long imageId = GetterUtil.getLong(
696                            HttpUtil.getParameter(url, "img_id", false));
697    
698                    Image image = ImageLocalServiceUtil.fetchImage(imageId);
699    
700                    if (image == null) {
701                            return null;
702                    }
703    
704                    return image.getTextObj();
705            }
706    
707            protected String getImageFieldValue(
708                    UploadRequest uploadRequest, String fieldNameValue) {
709    
710                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
711    
712                    jsonObject.put("alt", StringPool.BLANK);
713                    jsonObject.put("data", StringPool.BLANK);
714    
715                    try {
716                            byte[] bytes = getImageBytes(uploadRequest, fieldNameValue);
717    
718                            if (ArrayUtil.isNotEmpty(bytes)) {
719                                    jsonObject.put(
720                                            "alt", uploadRequest.getParameter(fieldNameValue + "Alt"));
721                                    jsonObject.put("data", UnicodeFormatter.bytesToHex(bytes));
722                            }
723                    }
724                    catch (Exception e) {
725                    }
726    
727                    return jsonObject.toString();
728            }
729    
730            protected Set<Locale> getMergedAvailableLocales(
731                    Set<Locale> newFieldAvailableLocales,
732                    Set<Locale> existingFieldAvailableLocales) {
733    
734                    Set<Locale> mergedAvailableLocales = new HashSet<Locale>();
735    
736                    mergedAvailableLocales.addAll(newFieldAvailableLocales);
737                    mergedAvailableLocales.addAll(existingFieldAvailableLocales);
738    
739                    return mergedAvailableLocales;
740            }
741    
742            protected List<Serializable> getMergedFieldValues(
743                    String fieldName, List<Serializable> newFieldValues,
744                    String[] newFieldsDisplayValues, List<Serializable> existingFieldValues,
745                    String[] existingFieldsDisplayValues,
746                    List<Serializable> defaultFieldValues) {
747    
748                    if (existingFieldValues == null) {
749                            return newFieldValues;
750                    }
751    
752                    List<Serializable> mergedLocaleValues = new ArrayList<Serializable>();
753    
754                    int repetition = countFieldRepetition(
755                            newFieldsDisplayValues, fieldName);
756    
757                    for (int i = 0; i < repetition; i++) {
758                            int existingFieldValueIndex = getExistingFieldValueIndex(
759                                    newFieldsDisplayValues, existingFieldsDisplayValues, fieldName,
760                                    i);
761    
762                            if (existingFieldValueIndex == -1) {
763                                    mergedLocaleValues.add(i, defaultFieldValues.get(i));
764                            }
765                            else {
766                                    if (newFieldValues != null) {
767                                            mergedLocaleValues.add(i, newFieldValues.get(i));
768                                    }
769                                    else {
770                                            Serializable existingValue = existingFieldValues.get(
771                                                    existingFieldValueIndex);
772    
773                                            mergedLocaleValues.add(i, existingValue);
774                                    }
775                            }
776                    }
777    
778                    return mergedLocaleValues;
779            }
780    
781            protected Map<Locale, List<Serializable>> getMergedFieldValuesMap(
782                    Field newField, String[] newFieldsDisplayValues, Field existingField,
783                    String[] existingFieldsDisplayValues) {
784    
785                    Set<Locale> availableLocales = getMergedAvailableLocales(
786                            newField.getAvailableLocales(),
787                            existingField.getAvailableLocales());
788    
789                    for (Locale locale : availableLocales) {
790                            List<Serializable> newFieldValues = getFieldValues(
791                                    newField, locale);
792    
793                            List<Serializable> existingFieldValues = getFieldValues(
794                                    existingField, locale);
795    
796                            List<Serializable> defaultFieldValues = getFieldValues(
797                                    newField, newField.getDefaultLocale());
798    
799                            List<Serializable> mergedLocaleValues = getMergedFieldValues(
800                                    newField.getName(), newFieldValues, newFieldsDisplayValues,
801                                    existingFieldValues, existingFieldsDisplayValues,
802                                    defaultFieldValues);
803    
804                            existingField.setValues(locale, mergedLocaleValues);
805                    }
806    
807                    return existingField.getValuesMap();
808            }
809    
810            protected String[] splitFieldsDisplayValue(Field fieldsDisplayField) {
811                    String value = (String)fieldsDisplayField.getValue();
812    
813                    return StringUtil.split(value);
814            }
815    
816    }