001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.dynamicdatamapping.util;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.json.JSONArray;
020    import com.liferay.portal.kernel.json.JSONFactoryUtil;
021    import com.liferay.portal.kernel.json.JSONObject;
022    import com.liferay.portal.kernel.language.LanguageUtil;
023    import com.liferay.portal.kernel.repository.model.FileEntry;
024    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
025    import com.liferay.portal.kernel.upload.UploadRequest;
026    import com.liferay.portal.kernel.util.ArrayUtil;
027    import com.liferay.portal.kernel.util.DateFormatFactoryUtil;
028    import com.liferay.portal.kernel.util.FileUtil;
029    import com.liferay.portal.kernel.util.GetterUtil;
030    import com.liferay.portal.kernel.util.HttpUtil;
031    import com.liferay.portal.kernel.util.ListUtil;
032    import com.liferay.portal.kernel.util.LocaleUtil;
033    import com.liferay.portal.kernel.util.OrderByComparator;
034    import com.liferay.portal.kernel.util.StringPool;
035    import com.liferay.portal.kernel.util.StringUtil;
036    import com.liferay.portal.kernel.util.TimeZoneUtil;
037    import com.liferay.portal.kernel.util.UnicodeFormatter;
038    import com.liferay.portal.kernel.util.Validator;
039    import com.liferay.portal.model.Image;
040    import com.liferay.portal.model.Layout;
041    import com.liferay.portal.service.ImageLocalServiceUtil;
042    import com.liferay.portal.service.LayoutLocalServiceUtil;
043    import com.liferay.portal.service.ServiceContext;
044    import com.liferay.portal.theme.ThemeDisplay;
045    import com.liferay.portal.util.PortalUtil;
046    import com.liferay.portal.util.PropsValues;
047    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
048    import com.liferay.portlet.documentlibrary.util.DLUtil;
049    import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
050    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
051    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
052    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
053    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
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, SystemException {
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, SystemException {
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                                    continue;
239                            }
240    
241                            List<Serializable> fieldValues = getFieldValues(
242                                    ddmStructure, fieldName, fieldNamespace, serviceContext);
243    
244                            if ((fieldValues == null) || fieldValues.isEmpty()) {
245                                    continue;
246                            }
247    
248                            Field field = createField(
249                                    ddmStructure, fieldName, fieldValues, serviceContext);
250    
251                            fields.put(field);
252                    }
253    
254                    return fields;
255            }
256    
257            @Override
258            public Fields getFields(long ddmStructureId, ServiceContext serviceContext)
259                    throws PortalException, SystemException {
260    
261                    return getFields(ddmStructureId, 0, serviceContext);
262            }
263    
264            @Override
265            public Fields getFields(
266                            long ddmStructureId, String fieldNamespace,
267                            ServiceContext serviceContext)
268                    throws PortalException, SystemException {
269    
270                    return getFields(ddmStructureId, 0, fieldNamespace, serviceContext);
271            }
272    
273            @Override
274            public String[] getFieldsDisplayValues(Field fieldsDisplayField)
275                    throws Exception {
276    
277                    DDMStructure ddmStructure = fieldsDisplayField.getDDMStructure();
278    
279                    List<String> fieldsDisplayValues = new ArrayList<String>();
280    
281                    String[] values = splitFieldsDisplayValue(fieldsDisplayField);
282    
283                    for (String value : values) {
284                            String fieldName = StringUtil.extractFirst(
285                                    value, DDMImpl.INSTANCE_SEPARATOR);
286    
287                            if (ddmStructure.hasField(fieldName)) {
288                                    fieldsDisplayValues.add(fieldName);
289                            }
290                    }
291    
292                    return fieldsDisplayValues.toArray(
293                            new String[fieldsDisplayValues.size()]);
294            }
295    
296            @Override
297            public Serializable getIndexedFieldValue(
298                            Serializable fieldValue, String type)
299                    throws Exception {
300    
301                    if (fieldValue instanceof Date) {
302                            Date valueDate = (Date)fieldValue;
303    
304                            DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat(
305                                    "yyyyMMddHHmmss");
306    
307                            fieldValue = dateFormat.format(valueDate);
308                    }
309                    else if (type.equals(DDMImpl.TYPE_RADIO) ||
310                                     type.equals(DDMImpl.TYPE_SELECT)) {
311    
312                            String valueString = (String)fieldValue;
313    
314                            JSONArray jsonArray = JSONFactoryUtil.createJSONArray(valueString);
315    
316                            String[] stringArray = ArrayUtil.toStringArray(jsonArray);
317    
318                            fieldValue = stringArray[0];
319                    }
320    
321                    return fieldValue;
322            }
323    
324            @Override
325            public OrderByComparator getStructureOrderByComparator(
326                    String orderByCol, String orderByType) {
327    
328                    boolean orderByAsc = false;
329    
330                    if (orderByType.equals("asc")) {
331                            orderByAsc = true;
332                    }
333    
334                    OrderByComparator orderByComparator = null;
335    
336                    if (orderByCol.equals("id")) {
337                            orderByComparator = new StructureIdComparator(orderByAsc);
338                    }
339                    else if (orderByCol.equals("modified-date")) {
340                            orderByComparator = new StructureModifiedDateComparator(orderByAsc);
341                    }
342    
343                    return orderByComparator;
344            }
345    
346            @Override
347            public OrderByComparator getTemplateOrderByComparator(
348                    String orderByCol, String orderByType) {
349    
350                    boolean orderByAsc = false;
351    
352                    if (orderByType.equals("asc")) {
353                            orderByAsc = true;
354                    }
355    
356                    OrderByComparator orderByComparator = null;
357    
358                    if (orderByCol.equals("id")) {
359                            orderByComparator = new TemplateIdComparator(orderByAsc);
360                    }
361                    else if (orderByCol.equals("modified-date")) {
362                            orderByComparator = new TemplateModifiedDateComparator(orderByAsc);
363                    }
364    
365                    return orderByComparator;
366            }
367    
368            @Override
369            public Fields mergeFields(Fields newFields, Fields existingFields) {
370                    String[] newFieldsDisplayValues = splitFieldsDisplayValue(
371                            newFields.get(DDMImpl.FIELDS_DISPLAY_NAME));
372    
373                    String[] existingFieldsDisplayValues = splitFieldsDisplayValue(
374                            existingFields.get(DDMImpl.FIELDS_DISPLAY_NAME));
375    
376                    Iterator<Field> itr = newFields.iterator(true);
377    
378                    while (itr.hasNext()) {
379                            Field newField = itr.next();
380    
381                            Field existingField = existingFields.get(newField.getName());
382    
383                            if (existingField == null) {
384                                    existingFields.put(newField);
385    
386                                    continue;
387                            }
388    
389                            if (newField.isPrivate()) {
390                                    String[] existingFieldValues = splitFieldsDisplayValue(
391                                            existingField);
392    
393                                    String[] newFieldValues = splitFieldsDisplayValue(newField);
394    
395                                    Locale currentLocale = getFirstLocaleFromField(newField);
396    
397                                    if (currentLocale.equals(newField.getDefaultLocale()) &&
398                                            !Validator.equalsSorted(
399                                                    existingFieldValues, newFieldValues)) {
400    
401                                                    existingFields.put(newField);
402                                    }
403    
404                                    continue;
405                            }
406    
407                            existingField.setDefaultLocale(newField.getDefaultLocale());
408    
409                            Map<Locale, List<Serializable>> mergedFieldValuesMap =
410                                    getMergedFieldValuesMap(
411                                            newField, newFieldsDisplayValues, existingField,
412                                            existingFieldsDisplayValues);
413    
414                            existingField.setValuesMap(mergedFieldValuesMap);
415                    }
416    
417                    return existingFields;
418            }
419    
420            @Override
421            public String[] splitFieldsDisplayValue(Field fieldsDisplayField) {
422                    String value = (String)fieldsDisplayField.getValue();
423    
424                    if (Validator.isNull(value)) {
425                            Locale locale = getFirstLocaleFromField(fieldsDisplayField);
426    
427                            value = (String)fieldsDisplayField.getValue(locale);
428                    }
429    
430                    return StringUtil.split(value);
431            }
432    
433            protected int countFieldRepetition(
434                    String[] fieldsDisplayValues, String fieldName) {
435    
436                    int count = 0;
437    
438                    for (String fieldsDisplayValue : fieldsDisplayValues) {
439                            String prefix = StringUtil.extractFirst(
440                                    fieldsDisplayValue, INSTANCE_SEPARATOR);
441    
442                            if (prefix.equals(fieldName)) {
443                                    count++;
444                            }
445                    }
446    
447                    return count;
448            }
449    
450            protected Field createField(
451                            DDMStructure ddmStructure, String fieldName,
452                            List<Serializable> fieldValues, ServiceContext serviceContext)
453                    throws PortalException, SystemException {
454    
455                    Field field = new Field();
456    
457                    field.setDDMStructureId(ddmStructure.getStructureId());
458    
459                    String languageId = GetterUtil.getString(
460                            serviceContext.getAttribute("languageId"),
461                            serviceContext.getLanguageId());
462    
463                    Locale locale = LocaleUtil.fromLanguageId(languageId);
464    
465                    String defaultLanguageId = GetterUtil.getString(
466                            serviceContext.getAttribute("defaultLanguageId"));
467    
468                    Locale defaultLocale = LocaleUtil.fromLanguageId(defaultLanguageId);
469    
470                    field.setDefaultLocale(defaultLocale);
471    
472                    field.setName(fieldName);
473                    field.setValues(locale, fieldValues);
474    
475                    return field;
476            }
477    
478            protected DDMStructure getDDMStructure(
479                            long ddmStructureId, long ddmTemplateId)
480                    throws PortalException, SystemException {
481    
482                    DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(
483                            ddmStructureId);
484    
485                    try {
486                            DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
487                                    ddmTemplateId);
488    
489                            // Clone ddmStructure to make sure changes are never persisted
490    
491                            ddmStructure = (DDMStructure)ddmStructure.clone();
492    
493                            ddmStructure.setXsd(ddmTemplate.getScript());
494                    }
495                    catch (NoSuchTemplateException nste) {
496                    }
497    
498                    return ddmStructure;
499            }
500    
501            protected int getExistingFieldValueIndex(
502                    String[] newFieldsDisplayValues, String[] existingFieldsDisplayValues,
503                    String fieldName, int index) {
504    
505                    String instanceId = getFieldIntanceId(
506                            newFieldsDisplayValues, fieldName, index);
507    
508                    return getFieldValueIndex(
509                            existingFieldsDisplayValues, fieldName, instanceId);
510            }
511    
512            protected String getFieldIntanceId(
513                    String[] fieldsDisplayValues, String fieldName, int index) {
514    
515                    String prefix = fieldName.concat(INSTANCE_SEPARATOR);
516    
517                    for (String fieldsDisplayValue : fieldsDisplayValues) {
518                            if (fieldsDisplayValue.startsWith(prefix)) {
519                                    index--;
520    
521                                    if (index < 0) {
522                                            return StringUtil.extractLast(
523                                                    fieldsDisplayValue, DDMImpl.INSTANCE_SEPARATOR);
524                                    }
525                            }
526                    }
527    
528                    return null;
529            }
530    
531            protected List<String> getFieldNames(
532                    String fieldNamespace, String fieldName,
533                    ServiceContext serviceContext) {
534    
535                    String[] fieldsDisplayValues = StringUtil.split(
536                            (String)serviceContext.getAttribute(
537                                    fieldNamespace + FIELDS_DISPLAY_NAME));
538    
539                    List<String> privateFieldNames = ListUtil.fromArray(
540                            PropsValues.DYNAMIC_DATA_MAPPING_STRUCTURE_PRIVATE_FIELD_NAMES);
541    
542                    List<String> fieldNames = new ArrayList<String>();
543    
544                    if ((fieldsDisplayValues.length == 0) ||
545                            privateFieldNames.contains(fieldName)) {
546    
547                            fieldNames.add(fieldNamespace + fieldName);
548                    }
549                    else {
550                            for (String namespacedFieldName : fieldsDisplayValues) {
551                                    String fieldNameValue = StringUtil.extractFirst(
552                                            namespacedFieldName, INSTANCE_SEPARATOR);
553    
554                                    if (fieldNameValue.equals(fieldName)) {
555                                            fieldNames.add(fieldNamespace + namespacedFieldName);
556                                    }
557                            }
558                    }
559    
560                    return fieldNames;
561            }
562    
563            protected int getFieldValueIndex(
564                    String[] fieldsDisplayValues, String fieldName, String instanceId) {
565    
566                    if (instanceId == null) {
567                            return -1;
568                    }
569    
570                    int offset = 0;
571    
572                    String prefix = fieldName.concat(INSTANCE_SEPARATOR);
573    
574                    for (String fieldsDisplayValue : fieldsDisplayValues) {
575                            if (fieldsDisplayValue.startsWith(prefix)) {
576                                    String fieldIstanceId = StringUtil.extractLast(
577                                            fieldsDisplayValue, DDMImpl.INSTANCE_SEPARATOR);
578    
579                                    if (fieldIstanceId.equals(instanceId)) {
580                                            return offset;
581                                    }
582    
583                                    offset++;
584                            }
585                    }
586    
587                    return -1;
588            }
589    
590            protected List<Serializable> getFieldValues(
591                            DDMStructure ddmStructure, String fieldName, String fieldNamespace,
592                            ServiceContext serviceContext)
593                    throws PortalException, SystemException {
594    
595                    String fieldDataType = ddmStructure.getFieldDataType(fieldName);
596                    String fieldType = ddmStructure.getFieldType(fieldName);
597    
598                    List<String> fieldNames = getFieldNames(
599                            fieldNamespace, fieldName, serviceContext);
600    
601                    List<Serializable> fieldValues = new ArrayList<Serializable>(
602                            fieldNames.size());
603    
604                    for (String fieldNameValue : fieldNames) {
605                            Serializable fieldValue = serviceContext.getAttribute(
606                                    fieldNameValue);
607    
608                            if (fieldDataType.equals(FieldConstants.DATE)) {
609                                    int fieldValueMonth = GetterUtil.getInteger(
610                                            serviceContext.getAttribute(fieldNameValue + "Month"));
611                                    int fieldValueDay = GetterUtil.getInteger(
612                                            serviceContext.getAttribute(fieldNameValue + "Day"));
613                                    int fieldValueYear = GetterUtil.getInteger(
614                                            serviceContext.getAttribute(fieldNameValue + "Year"));
615    
616                                    String fieldValueDateString = GetterUtil.getString(
617                                            serviceContext.getAttribute(fieldNameValue));
618    
619                                    if (Validator.isNull(fieldValueDateString)) {
620                                            fieldValue = StringPool.BLANK;
621                                    }
622                                    else {
623                                            Date fieldValueDate = PortalUtil.getDate(
624                                                    fieldValueMonth, fieldValueDay, fieldValueYear,
625                                                    TimeZoneUtil.getTimeZone("UTC"), null);
626    
627                                            if (fieldValueDate != null) {
628                                                    fieldValue = String.valueOf(fieldValueDate.getTime());
629                                            }
630                                    }
631                            }
632                            else if (fieldDataType.equals(FieldConstants.IMAGE) &&
633                                             Validator.isNull(fieldValue)) {
634    
635                                    HttpServletRequest request = serviceContext.getRequest();
636    
637                                    if (!(request instanceof UploadRequest)) {
638                                            return null;
639                                    }
640    
641                                    fieldValue = getImageFieldValue(
642                                            (UploadRequest)request, fieldNameValue);
643                            }
644    
645                            if (DDMImpl.TYPE_RADIO.equals(fieldType) ||
646                                    DDMImpl.TYPE_SELECT.equals(fieldType)) {
647    
648                                    if (fieldValue == null) {
649                                            fieldValue = new String[] {StringPool.BLANK};
650                                    }
651                                    else if (fieldValue instanceof String) {
652                                            fieldValue = new String[] {String.valueOf(fieldValue)};
653                                    }
654    
655                                    fieldValue = JSONFactoryUtil.serialize(fieldValue);
656                            }
657    
658                            if (fieldValue == null) {
659                                    return null;
660                            }
661    
662                            Serializable fieldValueSerializable =
663                                    FieldConstants.getSerializable(
664                                            fieldDataType, GetterUtil.getString(fieldValue));
665    
666                            fieldValues.add(fieldValueSerializable);
667                    }
668    
669                    return fieldValues;
670            }
671    
672            protected List<Serializable> getFieldValues(Field field, Locale locale) {
673                    Map<Locale, List<Serializable>> fieldValuesMap = field.getValuesMap();
674    
675                    return fieldValuesMap.get(locale);
676            }
677    
678            protected byte[] getImageBytes(
679                            UploadRequest uploadRequest, String fieldNameValue)
680                    throws Exception {
681    
682                    File file = uploadRequest.getFile(fieldNameValue);
683    
684                    byte[] bytes = FileUtil.getBytes(file);
685    
686                    if (ArrayUtil.isNotEmpty(bytes)) {
687                            return bytes;
688                    }
689    
690                    String url = uploadRequest.getParameter(fieldNameValue + "URL");
691    
692                    long imageId = GetterUtil.getLong(
693                            HttpUtil.getParameter(url, "img_id", false));
694    
695                    Image image = ImageLocalServiceUtil.fetchImage(imageId);
696    
697                    if (image == null) {
698                            return null;
699                    }
700    
701                    return image.getTextObj();
702            }
703    
704            protected String getImageFieldValue(
705                    UploadRequest uploadRequest, String fieldNameValue) {
706    
707                    try {
708                            byte[] bytes = getImageBytes(uploadRequest, fieldNameValue);
709    
710                            if (ArrayUtil.isNotEmpty(bytes)) {
711                                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
712    
713                                    jsonObject.put(
714                                            "alt", uploadRequest.getParameter(fieldNameValue + "Alt"));
715                                    jsonObject.put("data", UnicodeFormatter.bytesToHex(bytes));
716    
717                                    return jsonObject.toString();
718                            }
719                    }
720                    catch (Exception e) {
721                    }
722    
723                    return StringPool.BLANK;
724            }
725    
726            protected Set<Locale> getMergedAvailableLocales(
727                    Set<Locale> newFieldAvailableLocales,
728                    Set<Locale> existingFieldAvailableLocales) {
729    
730                    Set<Locale> mergedAvailableLocales = new HashSet<Locale>();
731    
732                    mergedAvailableLocales.addAll(newFieldAvailableLocales);
733                    mergedAvailableLocales.addAll(existingFieldAvailableLocales);
734    
735                    return mergedAvailableLocales;
736            }
737    
738            protected List<Serializable> getMergedFieldValues(
739                    String fieldName, List<Serializable> newFieldValues,
740                    String[] newFieldsDisplayValues, List<Serializable> existingFieldValues,
741                    String[] existingFieldsDisplayValues,
742                    List<Serializable> defaultFieldValues) {
743    
744                    if (existingFieldValues == null) {
745                            return newFieldValues;
746                    }
747    
748                    List<Serializable> mergedLocaleValues = new ArrayList<Serializable>();
749    
750                    int repetition = countFieldRepetition(
751                            newFieldsDisplayValues, fieldName);
752    
753                    for (int i = 0; i < repetition; i++) {
754                            int existingFieldValueIndex = getExistingFieldValueIndex(
755                                    newFieldsDisplayValues, existingFieldsDisplayValues, fieldName,
756                                    i);
757    
758                            if (existingFieldValueIndex == -1) {
759                                    if (defaultFieldValues != null) {
760                                            mergedLocaleValues.add(i, defaultFieldValues.get(i));
761                                    }
762                                    else {
763                                            mergedLocaleValues.add(i, null);
764                                    }
765                            }
766                            else {
767                                    if (newFieldValues != null) {
768                                            mergedLocaleValues.add(i, newFieldValues.get(i));
769                                    }
770                                    else {
771                                            Serializable existingValue = existingFieldValues.get(
772                                                    existingFieldValueIndex);
773    
774                                            mergedLocaleValues.add(i, existingValue);
775                                    }
776                            }
777                    }
778    
779                    return mergedLocaleValues;
780            }
781    
782            protected Map<Locale, List<Serializable>> getMergedFieldValuesMap(
783                    Field newField, String[] newFieldsDisplayValues, Field existingField,
784                    String[] existingFieldsDisplayValues) {
785    
786                    Set<Locale> availableLocales = getMergedAvailableLocales(
787                            newField.getAvailableLocales(),
788                            existingField.getAvailableLocales());
789    
790                    for (Locale locale : availableLocales) {
791                            List<Serializable> newFieldValues = getFieldValues(
792                                    newField, locale);
793    
794                            List<Serializable> existingFieldValues = getFieldValues(
795                                    existingField, locale);
796    
797                            List<Serializable> defaultFieldValues = getFieldValues(
798                                    newField, newField.getDefaultLocale());
799    
800                            List<Serializable> mergedLocaleValues = getMergedFieldValues(
801                                    newField.getName(), newFieldValues, newFieldsDisplayValues,
802                                    existingFieldValues, existingFieldsDisplayValues,
803                                    defaultFieldValues);
804    
805                            existingField.setValues(locale, mergedLocaleValues);
806                    }
807    
808                    return existingField.getValuesMap();
809            }
810    
811            private Locale getFirstLocaleFromField(Field fieldsDisplayField) {
812                    Locale firstLocale = null;
813    
814                    Set<Locale> availableLocales = fieldsDisplayField.getAvailableLocales();
815    
816                    Iterator<Locale> localeIterator = availableLocales.iterator();
817    
818                    while ((firstLocale == null) && localeIterator.hasNext()) {
819                            firstLocale = localeIterator.next();
820                    }
821    
822                    return firstLocale;
823            }
824    
825    }