001
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
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
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 }