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