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