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