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.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.repository.model.FileEntry;
025 import com.liferay.portal.kernel.security.pacl.DoPrivileged;
026 import com.liferay.portal.kernel.upload.UploadRequest;
027 import com.liferay.portal.kernel.util.ArrayUtil;
028 import com.liferay.portal.kernel.util.DateFormatFactoryUtil;
029 import com.liferay.portal.kernel.util.DateUtil;
030 import com.liferay.portal.kernel.util.FileUtil;
031 import com.liferay.portal.kernel.util.GetterUtil;
032 import com.liferay.portal.kernel.util.HttpUtil;
033 import com.liferay.portal.kernel.util.ListUtil;
034 import com.liferay.portal.kernel.util.LocaleUtil;
035 import com.liferay.portal.kernel.util.OrderByComparator;
036 import com.liferay.portal.kernel.util.ParamUtil;
037 import com.liferay.portal.kernel.util.StringPool;
038 import com.liferay.portal.kernel.util.StringUtil;
039 import com.liferay.portal.kernel.util.UnicodeFormatter;
040 import com.liferay.portal.kernel.util.Validator;
041 import com.liferay.portal.model.Image;
042 import com.liferay.portal.model.Layout;
043 import com.liferay.portal.service.ImageLocalServiceUtil;
044 import com.liferay.portal.service.LayoutLocalServiceUtil;
045 import com.liferay.portal.service.ServiceContext;
046 import com.liferay.portal.theme.ThemeDisplay;
047 import com.liferay.portal.util.PortalUtil;
048 import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
049 import com.liferay.portlet.documentlibrary.util.DLUtil;
050 import com.liferay.portlet.dynamicdatamapping.StructureDefinitionException;
051 import com.liferay.portlet.dynamicdatamapping.io.DDMFormJSONDeserializerUtil;
052 import com.liferay.portlet.dynamicdatamapping.io.DDMFormValuesJSONDeserializerUtil;
053 import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
054 import com.liferay.portlet.dynamicdatamapping.model.DDMFormField;
055 import com.liferay.portlet.dynamicdatamapping.model.DDMFormFieldOptions;
056 import com.liferay.portlet.dynamicdatamapping.model.DDMFormLayout;
057 import com.liferay.portlet.dynamicdatamapping.model.DDMFormLayoutColumn;
058 import com.liferay.portlet.dynamicdatamapping.model.DDMFormLayoutPage;
059 import com.liferay.portlet.dynamicdatamapping.model.DDMFormLayoutRow;
060 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
061 import com.liferay.portlet.dynamicdatamapping.model.DDMStructureVersion;
062 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
063 import com.liferay.portlet.dynamicdatamapping.model.LocalizedValue;
064 import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
065 import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
066 import com.liferay.portlet.dynamicdatamapping.storage.DDMFormValues;
067 import com.liferay.portlet.dynamicdatamapping.storage.Field;
068 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
069 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
070 import com.liferay.portlet.dynamicdatamapping.util.comparator.StructureIdComparator;
071 import com.liferay.portlet.dynamicdatamapping.util.comparator.StructureModifiedDateComparator;
072 import com.liferay.portlet.dynamicdatamapping.util.comparator.TemplateIdComparator;
073 import com.liferay.portlet.dynamicdatamapping.util.comparator.TemplateModifiedDateComparator;
074
075 import java.io.File;
076 import java.io.Serializable;
077
078 import java.text.DateFormat;
079 import java.text.ParseException;
080
081 import java.util.ArrayList;
082 import java.util.Date;
083 import java.util.HashSet;
084 import java.util.Iterator;
085 import java.util.List;
086 import java.util.Locale;
087 import java.util.Map;
088 import java.util.Set;
089
090 import javax.portlet.PortletRequest;
091
092 import javax.servlet.http.HttpServletRequest;
093
094
100 @DoPrivileged
101 public class DDMImpl implements DDM {
102
103 public static final String FIELDS_DISPLAY_NAME = "_fieldsDisplay";
104
105 public static final String INSTANCE_SEPARATOR = "_INSTANCE_";
106
107 public static final String TYPE_CHECKBOX = "checkbox";
108
109 public static final String TYPE_DDM_DATE = "ddm-date";
110
111 public static final String TYPE_DDM_DOCUMENTLIBRARY = "ddm-documentlibrary";
112
113 public static final String TYPE_DDM_IMAGE = "ddm-image";
114
115 public static final String TYPE_DDM_LINK_TO_PAGE = "ddm-link-to-page";
116
117 public static final String TYPE_DDM_TEXT_HTML = "ddm-text-html";
118
119 public static final String TYPE_RADIO = "radio";
120
121 public static final String TYPE_SELECT = "select";
122
123 @Override
124 public DDMDisplay getDDMDisplay(long classNameId) {
125 List<DDMDisplay> ddmDisplays = DDMDisplayRegistryUtil.getDDMDisplays();
126
127 for (DDMDisplay ddmDisplay : ddmDisplays) {
128 DDMPermissionHandler ddmPermissionHandler =
129 ddmDisplay.getDDMPermissionHandler();
130
131 if (ArrayUtil.contains(
132 ddmPermissionHandler.getResourceClassNameIds(),
133 classNameId)) {
134
135 return ddmDisplay;
136 }
137 }
138
139 throw new IllegalArgumentException(
140 "No DDM display registered for " +
141 PortalUtil.getClassName(classNameId));
142 }
143
144 @Override
145 public DDMForm getDDMForm(long classNameId, long classPK)
146 throws PortalException {
147
148 if ((classNameId <= 0) || (classPK <= 0)) {
149 return null;
150 }
151
152 long ddmStructureClassNameId = PortalUtil.getClassNameId(
153 DDMStructure.class);
154 long ddmTemplateClassNameId = PortalUtil.getClassNameId(
155 DDMTemplate.class);
156
157 if (classNameId == ddmStructureClassNameId) {
158 DDMStructure structure = DDMStructureLocalServiceUtil.getStructure(
159 classPK);
160
161 DDMForm ddmForm = structure.getFullHierarchyDDMForm();
162
163 return ddmForm;
164 }
165 else if (classNameId == ddmTemplateClassNameId) {
166 DDMTemplate template = DDMTemplateLocalServiceUtil.getTemplate(
167 classPK);
168
169 return DDMFormJSONDeserializerUtil.deserialize(
170 template.getScript());
171 }
172
173 return null;
174 }
175
176 @Override
177 public DDMForm getDDMForm(PortletRequest portletRequest)
178 throws PortalException {
179
180 try {
181 String definition = ParamUtil.getString(
182 portletRequest, "definition");
183
184 return DDMFormJSONDeserializerUtil.deserialize(definition);
185 }
186 catch (PortalException pe) {
187 throw new StructureDefinitionException(pe);
188 }
189 }
190
191 @Override
192 public JSONArray getDDMFormFieldsJSONArray(
193 DDMStructure ddmStructure, String script) {
194
195 DDMForm ddmForm = null;
196
197 if (ddmStructure != null) {
198 ddmForm = ddmStructure.getDDMForm();
199 }
200
201 return getDDMFormFieldsJSONArray(ddmForm, script);
202 }
203
204 @Override
205 public JSONArray getDDMFormFieldsJSONArray(
206 DDMStructureVersion ddmStructureVersion, String script) {
207
208 DDMForm ddmForm = null;
209
210 if (ddmStructureVersion != null) {
211 ddmForm = ddmStructureVersion.getDDMForm();
212 }
213
214 return getDDMFormFieldsJSONArray(ddmForm, script);
215 }
216
217 @Override
218 public DDMPermissionHandler getDDMPermissionHandler(long classNameId) {
219 DDMDisplay ddmDisplay = getDDMDisplay(classNameId);
220
221 return ddmDisplay.getDDMPermissionHandler();
222 }
223
224 @Override
225 public DDMFormLayout getDefaultDDMFormLayout(DDMForm ddmForm) {
226 DDMFormLayout ddmFormLayout = new DDMFormLayout();
227
228 Locale defaultLocale = ddmForm.getDefaultLocale();
229
230 ddmFormLayout.setDefaultLocale(defaultLocale);
231
232 DDMFormLayoutPage ddmFormLayoutPage = new DDMFormLayoutPage();
233
234 LocalizedValue title = getDefaultDDMFormPageTitle(defaultLocale);
235
236 ddmFormLayoutPage.setTitle(title);
237
238 for (DDMFormField ddmFormField : ddmForm.getDDMFormFields()) {
239 ddmFormLayoutPage.addDDMFormLayoutRow(
240 getDefaultDDMFormLayoutRow(ddmFormField));
241 }
242
243 ddmFormLayout.addDDMFormLayoutPage(ddmFormLayoutPage);
244
245 return ddmFormLayout;
246 }
247
248 @Override
249 public Serializable getDisplayFieldValue(
250 ThemeDisplay themeDisplay, Serializable fieldValue, String type)
251 throws Exception {
252
253 if (fieldValue instanceof Date) {
254 Date valueDate = (Date)fieldValue;
255
256 DateFormat dateFormat = DateFormatFactoryUtil.getDate(
257 themeDisplay.getLocale());
258
259 fieldValue = dateFormat.format(valueDate);
260 }
261 else if (type.equals(DDMImpl.TYPE_CHECKBOX)) {
262 Boolean valueBoolean = (Boolean)fieldValue;
263
264 if (valueBoolean) {
265 fieldValue = LanguageUtil.get(themeDisplay.getLocale(), "yes");
266 }
267 else {
268 fieldValue = LanguageUtil.get(themeDisplay.getLocale(), "no");
269 }
270 }
271 else if (type.equals(DDMImpl.TYPE_DDM_DOCUMENTLIBRARY)) {
272 if (Validator.isNull(fieldValue)) {
273 return StringPool.BLANK;
274 }
275
276 String valueString = String.valueOf(fieldValue);
277
278 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
279 valueString);
280
281 String uuid = jsonObject.getString("uuid");
282 long groupId = jsonObject.getLong("groupId");
283
284 FileEntry fileEntry =
285 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
286 uuid, groupId);
287
288 fieldValue = DLUtil.getPreviewURL(
289 fileEntry, fileEntry.getFileVersion(), null, StringPool.BLANK,
290 false, true);
291 }
292 else if (type.equals(DDMImpl.TYPE_DDM_LINK_TO_PAGE)) {
293 if (Validator.isNull(fieldValue)) {
294 return StringPool.BLANK;
295 }
296
297 String valueString = String.valueOf(fieldValue);
298
299 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
300 valueString);
301
302 long groupId = jsonObject.getLong("groupId");
303 boolean privateLayout = jsonObject.getBoolean("privateLayout");
304 long layoutId = jsonObject.getLong("layoutId");
305
306 Layout layout = LayoutLocalServiceUtil.getLayout(
307 groupId, privateLayout, layoutId);
308
309 fieldValue = PortalUtil.getLayoutFriendlyURL(layout, themeDisplay);
310 }
311 else if (type.equals(DDMImpl.TYPE_RADIO) ||
312 type.equals(DDMImpl.TYPE_SELECT)) {
313
314 String valueString = String.valueOf(fieldValue);
315
316 JSONArray jsonArray = JSONFactoryUtil.createJSONArray(valueString);
317
318 String[] stringArray = ArrayUtil.toStringArray(jsonArray);
319
320 fieldValue = stringArray[0];
321 }
322
323 return fieldValue;
324 }
325
326 @Override
327 public Fields getFields(
328 long ddmStructureId, long ddmTemplateId,
329 ServiceContext serviceContext)
330 throws PortalException {
331
332 return getFields(
333 ddmStructureId, ddmTemplateId, StringPool.BLANK, serviceContext);
334 }
335
336 @Override
337 public Fields getFields(
338 long ddmStructureId, long ddmTemplateId, String fieldNamespace,
339 ServiceContext serviceContext)
340 throws PortalException {
341
342 DDMStructure ddmStructure = getDDMStructure(
343 ddmStructureId, ddmTemplateId);
344
345 Set<String> fieldNames = ddmStructure.getFieldNames();
346
347 boolean translating = true;
348
349 String defaultLanguageId = (String)serviceContext.getAttribute(
350 "defaultLanguageId");
351 String toLanguageId = (String)serviceContext.getAttribute(
352 "toLanguageId");
353
354 if (Validator.isNull(toLanguageId) ||
355 Validator.equals(defaultLanguageId, toLanguageId)) {
356
357 translating = false;
358 }
359
360 Fields fields = new Fields();
361
362 for (String fieldName : fieldNames) {
363 boolean localizable = GetterUtil.getBoolean(
364 ddmStructure.getFieldProperty(fieldName, "localizable"), true);
365
366 if (!localizable && translating &&
367 !fieldName.startsWith(StringPool.UNDERLINE)) {
368
369 continue;
370 }
371
372 List<Serializable> fieldValues = getFieldValues(
373 ddmStructure, fieldName, fieldNamespace, serviceContext);
374
375 if ((fieldValues == null) || fieldValues.isEmpty()) {
376 continue;
377 }
378
379 Field field = createField(
380 ddmStructure, fieldName, fieldValues, serviceContext);
381
382 fields.put(field);
383 }
384
385 return fields;
386 }
387
388 @Override
389 public Fields getFields(long ddmStructureId, ServiceContext serviceContext)
390 throws PortalException {
391
392 String serializedDDMFormValues = GetterUtil.getString(
393 serviceContext.getAttribute("ddmFormValues"));
394
395 if (Validator.isNotNull(serializedDDMFormValues)) {
396 return getFields(ddmStructureId, serializedDDMFormValues);
397 }
398
399 return getFields(ddmStructureId, 0, serviceContext);
400 }
401
402 @Override
403 public Fields getFields(
404 long ddmStructureId, String fieldNamespace,
405 ServiceContext serviceContext)
406 throws PortalException {
407
408 String serializedDDMFormValues = GetterUtil.getString(
409 serviceContext.getAttribute(fieldNamespace + "ddmFormValues"));
410
411 if (Validator.isNotNull(serializedDDMFormValues)) {
412 return getFields(ddmStructureId, serializedDDMFormValues);
413 }
414
415 return getFields(ddmStructureId, 0, fieldNamespace, serviceContext);
416 }
417
418 @Override
419 public String[] getFieldsDisplayValues(Field fieldsDisplayField)
420 throws Exception {
421
422 DDMStructure ddmStructure = fieldsDisplayField.getDDMStructure();
423
424 List<String> fieldsDisplayValues = new ArrayList<>();
425
426 String[] values = splitFieldsDisplayValue(fieldsDisplayField);
427
428 for (String value : values) {
429 String fieldName = StringUtil.extractFirst(
430 value, DDMImpl.INSTANCE_SEPARATOR);
431
432 if (ddmStructure.hasField(fieldName)) {
433 fieldsDisplayValues.add(fieldName);
434 }
435 }
436
437 return fieldsDisplayValues.toArray(
438 new String[fieldsDisplayValues.size()]);
439 }
440
441 @Override
442 public Serializable getIndexedFieldValue(
443 Serializable fieldValue, String type)
444 throws Exception {
445
446 if (fieldValue instanceof Date) {
447 Date valueDate = (Date)fieldValue;
448
449 DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat(
450 "yyyyMMddHHmmss");
451
452 fieldValue = dateFormat.format(valueDate);
453 }
454 else if (type.equals(DDMImpl.TYPE_RADIO) ||
455 type.equals(DDMImpl.TYPE_SELECT)) {
456
457 String valueString = (String)fieldValue;
458
459 JSONArray jsonArray = JSONFactoryUtil.createJSONArray(valueString);
460
461 String[] stringArray = ArrayUtil.toStringArray(jsonArray);
462
463 fieldValue = stringArray[0];
464 }
465
466 return fieldValue;
467 }
468
469 @Override
470 public OrderByComparator<DDMStructure> getStructureOrderByComparator(
471 String orderByCol, String orderByType) {
472
473 boolean orderByAsc = false;
474
475 if (orderByType.equals("asc")) {
476 orderByAsc = true;
477 }
478
479 OrderByComparator<DDMStructure> orderByComparator = null;
480
481 if (orderByCol.equals("id")) {
482 orderByComparator = new StructureIdComparator(orderByAsc);
483 }
484 else if (orderByCol.equals("modified-date")) {
485 orderByComparator = new StructureModifiedDateComparator(orderByAsc);
486 }
487
488 return orderByComparator;
489 }
490
491 @Override
492 public OrderByComparator<DDMTemplate> getTemplateOrderByComparator(
493 String orderByCol, String orderByType) {
494
495 boolean orderByAsc = false;
496
497 if (orderByType.equals("asc")) {
498 orderByAsc = true;
499 }
500
501 OrderByComparator<DDMTemplate> orderByComparator = null;
502
503 if (orderByCol.equals("id")) {
504 orderByComparator = new TemplateIdComparator(orderByAsc);
505 }
506 else if (orderByCol.equals("modified-date")) {
507 orderByComparator = new TemplateModifiedDateComparator(orderByAsc);
508 }
509
510 return orderByComparator;
511 }
512
513 @Override
514 public Fields mergeFields(Fields newFields, Fields existingFields) {
515 String[] newFieldsDisplayValues = splitFieldsDisplayValue(
516 newFields.get(DDMImpl.FIELDS_DISPLAY_NAME));
517
518 String[] existingFieldsDisplayValues = splitFieldsDisplayValue(
519 existingFields.get(DDMImpl.FIELDS_DISPLAY_NAME));
520
521 Iterator<Field> itr = newFields.iterator(true);
522
523 while (itr.hasNext()) {
524 Field newField = itr.next();
525
526 Field existingField = existingFields.get(newField.getName());
527
528 if ((existingField == null) || newField.isPrivate()) {
529 existingFields.put(newField);
530
531 continue;
532 }
533
534 existingField.setDefaultLocale(newField.getDefaultLocale());
535
536 Map<Locale, List<Serializable>> mergedFieldValuesMap =
537 getMergedFieldValuesMap(
538 newField, newFieldsDisplayValues, existingField,
539 existingFieldsDisplayValues);
540
541 existingField.setValuesMap(mergedFieldValuesMap);
542 }
543
544 return existingFields;
545 }
546
547 protected void addDDMFormFieldLocalizedProperties(
548 JSONObject jsonObject, DDMFormField ddmFormField, Locale locale,
549 Locale defaultLocale) {
550
551 addDDMFormFieldLocalizedProperty(
552 jsonObject, "label", ddmFormField.getLabel(), locale, defaultLocale,
553 ddmFormField.getType());
554 addDDMFormFieldLocalizedProperty(
555 jsonObject, "predefinedValue", ddmFormField.getPredefinedValue(),
556 locale, defaultLocale, ddmFormField.getType());
557 addDDMFormFieldLocalizedProperty(
558 jsonObject, "tip", ddmFormField.getTip(), locale, defaultLocale,
559 ddmFormField.getType());
560 }
561
562 protected void addDDMFormFieldLocalizedProperty(
563 JSONObject jsonObject, String propertyName,
564 LocalizedValue localizedValue, Locale locale, Locale defaultLocale,
565 String type) {
566
567 String propertyValue = localizedValue.getString(locale);
568
569 if (Validator.isNull(propertyValue)) {
570 propertyValue = localizedValue.getString(defaultLocale);
571 }
572
573 if (type.equals(DDMImpl.TYPE_RADIO) ||
574 type.equals(DDMImpl.TYPE_SELECT)) {
575
576 if (propertyName.equals("predefinedValue")) {
577 try {
578 jsonObject.put(
579 propertyName,
580 JSONFactoryUtil.createJSONArray(propertyValue));
581 }
582 catch (Exception e) {
583 }
584
585 return;
586 }
587 }
588
589 jsonObject.put(propertyName, propertyValue);
590 }
591
592 protected void addDDMFormFieldOptions(
593 JSONObject jsonObject, DDMFormField ddmFormField,
594 Set<Locale> availableLocales, Locale defaultLocale) {
595
596 String type = ddmFormField.getType();
597
598 if (!(type.equals(DDMImpl.TYPE_RADIO) ||
599 type.equals(DDMImpl.TYPE_SELECT))) {
600
601 return;
602 }
603
604 String fieldName = ddmFormField.getName();
605
606 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
607
608 DDMFormFieldOptions ddmFormFieldOptions =
609 ddmFormField.getDDMFormFieldOptions();
610
611 for (String optionValue : ddmFormFieldOptions.getOptionsValues()) {
612 JSONObject optionJSONObject = JSONFactoryUtil.createJSONObject();
613
614 String name = fieldName.concat(StringUtil.randomString());
615
616 optionJSONObject.put("id", name);
617 optionJSONObject.put("name", name);
618 optionJSONObject.put("type", "option");
619 optionJSONObject.put("value", optionValue);
620
621 addDDMFormFieldLocalizedProperty(
622 optionJSONObject, "label",
623 ddmFormFieldOptions.getOptionLabels(optionValue), defaultLocale,
624 defaultLocale, "option");
625
626 JSONObject localizationMapJSONObject =
627 JSONFactoryUtil.createJSONObject();
628
629 for (Locale availableLocale : availableLocales) {
630 JSONObject localeMap = JSONFactoryUtil.createJSONObject();
631
632 addDDMFormFieldLocalizedProperty(
633 localeMap, "label",
634 ddmFormFieldOptions.getOptionLabels(optionValue),
635 availableLocale, defaultLocale, "option");
636
637 localizationMapJSONObject.put(
638 LocaleUtil.toLanguageId(availableLocale), localeMap);
639 }
640
641 optionJSONObject.put("localizationMap", localizationMapJSONObject);
642
643 jsonArray.put(optionJSONObject);
644 }
645
646 jsonObject.put("options", jsonArray);
647 }
648
649 protected int countFieldRepetition(
650 String[] fieldsDisplayValues, String fieldName) {
651
652 int count = 0;
653
654 for (String fieldsDisplayValue : fieldsDisplayValues) {
655 String prefix = StringUtil.extractFirst(
656 fieldsDisplayValue, INSTANCE_SEPARATOR);
657
658 if (prefix.equals(fieldName)) {
659 count++;
660 }
661 }
662
663 return count;
664 }
665
666 protected Field createField(
667 DDMStructure ddmStructure, String fieldName,
668 List<Serializable> fieldValues, ServiceContext serviceContext) {
669
670 Field field = new Field();
671
672 field.setDDMStructureId(ddmStructure.getStructureId());
673
674 String languageId = GetterUtil.getString(
675 serviceContext.getAttribute("languageId"),
676 serviceContext.getLanguageId());
677
678 Locale locale = LocaleUtil.fromLanguageId(languageId);
679
680 String defaultLanguageId = GetterUtil.getString(
681 serviceContext.getAttribute("defaultLanguageId"));
682
683 Locale defaultLocale = LocaleUtil.fromLanguageId(defaultLanguageId);
684
685 if (fieldName.startsWith(StringPool.UNDERLINE)) {
686 locale = LocaleUtil.getSiteDefault();
687
688 defaultLocale = LocaleUtil.getSiteDefault();
689 }
690
691 field.setDefaultLocale(defaultLocale);
692
693 field.setName(fieldName);
694 field.setValues(locale, fieldValues);
695
696 return field;
697 }
698
699 protected JSONArray getDDMFormFieldsJSONArray(
700 DDMForm ddmForm, String script) {
701
702 if (Validator.isNull(script)) {
703 return null;
704 }
705
706 JSONArray defaultDDMFormFieldsJSONArray = null;
707
708 if (ddmForm != null) {
709 defaultDDMFormFieldsJSONArray = getDDMFormFieldsJSONArray(
710 ddmForm.getDDMFormFields(), ddmForm.getAvailableLocales(),
711 ddmForm.getDefaultLocale());
712 }
713
714 try {
715 DDMForm scriptDDMForm = DDMFormJSONDeserializerUtil.deserialize(
716 script);
717
718 return getDDMFormFieldsJSONArray(
719 scriptDDMForm.getDDMFormFields(),
720 scriptDDMForm.getAvailableLocales(),
721 scriptDDMForm.getDefaultLocale());
722 }
723 catch (PortalException pe) {
724 if (_log.isWarnEnabled()) {
725 _log.warn("Unable to deserialize script", pe);
726 }
727
728 return defaultDDMFormFieldsJSONArray;
729 }
730 }
731
732 protected JSONArray getDDMFormFieldsJSONArray(
733 List<DDMFormField> ddmFormFields, Set<Locale> availableLocales,
734 Locale defaultLocale) {
735
736 JSONArray ddmFormFieldsJSONArray = JSONFactoryUtil.createJSONArray();
737
738 for (DDMFormField ddmFormField : ddmFormFields) {
739 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
740
741 jsonObject.put("dataType", ddmFormField.getDataType());
742 jsonObject.put("id", ddmFormField.getName());
743 jsonObject.put("indexType", ddmFormField.getIndexType());
744 jsonObject.put("localizable", ddmFormField.isLocalizable());
745 jsonObject.put("multiple", ddmFormField.isMultiple());
746 jsonObject.put("name", ddmFormField.getName());
747 jsonObject.put("repeatable", ddmFormField.isRepeatable());
748 jsonObject.put("required", ddmFormField.isRequired());
749 jsonObject.put("showLabel", ddmFormField.isShowLabel());
750 jsonObject.put("type", ddmFormField.getType());
751
752 addDDMFormFieldLocalizedProperties(
753 jsonObject, ddmFormField, defaultLocale, defaultLocale);
754
755 addDDMFormFieldOptions(
756 jsonObject, ddmFormField, availableLocales, defaultLocale);
757
758 JSONObject localizationMapJSONObject =
759 JSONFactoryUtil.createJSONObject();
760
761 for (Locale availableLocale : availableLocales) {
762 JSONObject localeMap = JSONFactoryUtil.createJSONObject();
763
764 addDDMFormFieldLocalizedProperties(
765 localeMap, ddmFormField, availableLocale, defaultLocale);
766
767 localizationMapJSONObject.put(
768 LocaleUtil.toLanguageId(availableLocale), localeMap);
769 }
770
771 jsonObject.put("localizationMap", localizationMapJSONObject);
772
773 jsonObject.put(
774 "fields",
775 getDDMFormFieldsJSONArray(
776 ddmFormField.getNestedDDMFormFields(), availableLocales,
777 defaultLocale));
778
779 ddmFormFieldsJSONArray.put(jsonObject);
780 }
781
782 return ddmFormFieldsJSONArray;
783 }
784
785 protected DDMStructure getDDMStructure(
786 long ddmStructureId, long ddmTemplateId)
787 throws PortalException {
788
789 DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(
790 ddmStructureId);
791
792 DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.fetchDDMTemplate(
793 ddmTemplateId);
794
795 if (ddmTemplate != null) {
796
797
798
799 ddmStructure = (DDMStructure)ddmStructure.clone();
800
801 ddmStructure.setDefinition(ddmTemplate.getScript());
802 }
803
804 return ddmStructure;
805 }
806
807 protected DDMFormLayoutRow getDefaultDDMFormLayoutRow(
808 DDMFormField ddmFormField) {
809
810 DDMFormLayoutRow ddmFormLayoutRow = new DDMFormLayoutRow();
811
812 ddmFormLayoutRow.addDDMFormLayoutColumn(
813 new DDMFormLayoutColumn(
814 DDMFormLayoutColumn.FULL, ddmFormField.getName()));
815
816 return ddmFormLayoutRow;
817 }
818
819 protected LocalizedValue getDefaultDDMFormPageTitle(Locale defaultLocale) {
820 LocalizedValue title = new LocalizedValue(defaultLocale);
821
822 title.addString(defaultLocale, StringPool.BLANK);
823
824 return title;
825 }
826
827 protected int getExistingFieldValueIndex(
828 String[] newFieldsDisplayValues, String[] existingFieldsDisplayValues,
829 String fieldName, int index) {
830
831 String instanceId = getFieldIntanceId(
832 newFieldsDisplayValues, fieldName, index);
833
834 return getFieldValueIndex(
835 existingFieldsDisplayValues, fieldName, instanceId);
836 }
837
838 protected String getFieldIntanceId(
839 String[] fieldsDisplayValues, String fieldName, int index) {
840
841 String prefix = fieldName.concat(INSTANCE_SEPARATOR);
842
843 for (String fieldsDisplayValue : fieldsDisplayValues) {
844 if (fieldsDisplayValue.startsWith(prefix)) {
845 index--;
846
847 if (index < 0) {
848 return StringUtil.extractLast(
849 fieldsDisplayValue, DDMImpl.INSTANCE_SEPARATOR);
850 }
851 }
852 }
853
854 return null;
855 }
856
857 protected List<String> getFieldNames(
858 String fieldNamespace, String fieldName,
859 ServiceContext serviceContext) {
860
861 String[] fieldsDisplayValues = StringUtil.split(
862 (String)serviceContext.getAttribute(
863 fieldNamespace + FIELDS_DISPLAY_NAME));
864
865 List<String> privateFieldNames = ListUtil.fromArray(
866 new String[] {FIELDS_DISPLAY_NAME});
867
868 List<String> fieldNames = new ArrayList<>();
869
870 if ((fieldsDisplayValues.length == 0) ||
871 privateFieldNames.contains(fieldName)) {
872
873 fieldNames.add(fieldNamespace + fieldName);
874 }
875 else {
876 for (String namespacedFieldName : fieldsDisplayValues) {
877 String fieldNameValue = StringUtil.extractFirst(
878 namespacedFieldName, INSTANCE_SEPARATOR);
879
880 if (fieldNameValue.equals(fieldName)) {
881 fieldNames.add(fieldNamespace + namespacedFieldName);
882 }
883 }
884 }
885
886 return fieldNames;
887 }
888
889 protected Fields getFields(
890 long ddmStructureId, String serializedDDMFormValues)
891 throws PortalException {
892
893 DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(
894 ddmStructureId);
895
896 DDMFormValues ddmFormValues =
897 DDMFormValuesJSONDeserializerUtil.deserialize(
898 ddmStructure.getFullHierarchyDDMForm(),
899 serializedDDMFormValues);
900
901 return DDMFormValuesToFieldsConverterUtil.convert(
902 ddmStructure, ddmFormValues);
903 }
904
905 protected int getFieldValueIndex(
906 String[] fieldsDisplayValues, String fieldName, String instanceId) {
907
908 if (instanceId == null) {
909 return -1;
910 }
911
912 int offset = 0;
913
914 String prefix = fieldName.concat(INSTANCE_SEPARATOR);
915
916 for (String fieldsDisplayValue : fieldsDisplayValues) {
917 if (fieldsDisplayValue.startsWith(prefix)) {
918 String fieldIstanceId = StringUtil.extractLast(
919 fieldsDisplayValue, DDMImpl.INSTANCE_SEPARATOR);
920
921 if (fieldIstanceId.equals(instanceId)) {
922 return offset;
923 }
924
925 offset++;
926 }
927 }
928
929 return -1;
930 }
931
932 protected List<Serializable> getFieldValues(
933 DDMStructure ddmStructure, String fieldName, String fieldNamespace,
934 ServiceContext serviceContext)
935 throws PortalException {
936
937 DDMFormField ddmFormField = ddmStructure.getDDMFormField(fieldName);
938
939 String fieldDataType = ddmFormField.getDataType();
940 String fieldType = ddmFormField.getType();
941
942 LocalizedValue predefinedValue = ddmFormField.getPredefinedValue();
943
944 List<String> fieldNames = getFieldNames(
945 fieldNamespace, fieldName, serviceContext);
946
947 List<Serializable> fieldValues = new ArrayList<>(fieldNames.size());
948
949 for (String fieldNameValue : fieldNames) {
950 Serializable fieldValue = serviceContext.getAttribute(
951 fieldNameValue);
952
953 if (fieldValue == null) {
954 fieldValue = predefinedValue.getString(
955 serviceContext.getLocale());
956 }
957
958 if (fieldType.equals(DDMImpl.TYPE_CHECKBOX) &&
959 Validator.isNull(fieldValue)) {
960
961 fieldValue = "false";
962 }
963 else if (fieldDataType.equals(FieldConstants.DATE)) {
964 Date fieldValueDate = null;
965
966 if (fieldValue == null) {
967 int fieldValueMonth = GetterUtil.getInteger(
968 serviceContext.getAttribute(fieldNameValue + "Month"));
969 int fieldValueDay = GetterUtil.getInteger(
970 serviceContext.getAttribute(fieldNameValue + "Day"));
971 int fieldValueYear = GetterUtil.getInteger(
972 serviceContext.getAttribute(fieldNameValue + "Year"));
973
974 fieldValueDate = PortalUtil.getDate(
975 fieldValueMonth, fieldValueDay, fieldValueYear);
976 }
977 else {
978 try {
979 fieldValueDate = DateUtil.parseDate(
980 String.valueOf(fieldValue),
981 serviceContext.getLocale());
982 }
983 catch (ParseException pe) {
984 if (_log.isErrorEnabled()) {
985 _log.error("Unable to parse date " + fieldValue);
986 }
987 }
988 }
989
990 if (fieldValueDate != null) {
991 fieldValue = String.valueOf(fieldValueDate.getTime());
992 }
993 }
994 else if (fieldDataType.equals(FieldConstants.IMAGE) &&
995 Validator.isNull(fieldValue)) {
996
997 HttpServletRequest request = serviceContext.getRequest();
998
999 if (request instanceof UploadRequest) {
1000 String imageFieldValue = getImageFieldValue(
1001 (UploadRequest)request, fieldNameValue);
1002
1003 if (Validator.isNotNull(imageFieldValue)) {
1004 fieldValue = imageFieldValue;
1005 }
1006 }
1007 }
1008
1009 if (fieldValue == null) {
1010 return null;
1011 }
1012
1013 if (DDMImpl.TYPE_RADIO.equals(fieldType) ||
1014 DDMImpl.TYPE_SELECT.equals(fieldType)) {
1015
1016 String predefinedValueString = predefinedValue.getString(
1017 serviceContext.getLocale());
1018
1019 if (!fieldValue.equals(predefinedValueString) &&
1020 (fieldValue instanceof String)) {
1021
1022 fieldValue = new String[] {String.valueOf(fieldValue)};
1023
1024 fieldValue = JSONFactoryUtil.serialize(fieldValue);
1025 }
1026 }
1027
1028 Serializable fieldValueSerializable =
1029 FieldConstants.getSerializable(
1030 fieldDataType, GetterUtil.getString(fieldValue));
1031
1032 fieldValues.add(fieldValueSerializable);
1033 }
1034
1035 return fieldValues;
1036 }
1037
1038 protected List<Serializable> getFieldValues(Field field, Locale locale) {
1039 Map<Locale, List<Serializable>> fieldValuesMap = field.getValuesMap();
1040
1041 return fieldValuesMap.get(locale);
1042 }
1043
1044 protected byte[] getImageBytes(
1045 UploadRequest uploadRequest, String fieldNameValue)
1046 throws Exception {
1047
1048 File file = uploadRequest.getFile(fieldNameValue + "File");
1049
1050 byte[] bytes = FileUtil.getBytes(file);
1051
1052 if (ArrayUtil.isNotEmpty(bytes)) {
1053 return bytes;
1054 }
1055
1056 String url = uploadRequest.getParameter(fieldNameValue + "URL");
1057
1058 long imageId = GetterUtil.getLong(
1059 HttpUtil.getParameter(url, "img_id", false));
1060
1061 Image image = ImageLocalServiceUtil.fetchImage(imageId);
1062
1063 if (image == null) {
1064 return null;
1065 }
1066
1067 return image.getTextObj();
1068 }
1069
1070 protected String getImageFieldValue(
1071 UploadRequest uploadRequest, String fieldNameValue) {
1072
1073 try {
1074 byte[] bytes = getImageBytes(uploadRequest, fieldNameValue);
1075
1076 if (ArrayUtil.isNotEmpty(bytes)) {
1077 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
1078
1079 jsonObject.put(
1080 "alt", uploadRequest.getParameter(fieldNameValue + "Alt"));
1081 jsonObject.put("data", UnicodeFormatter.bytesToHex(bytes));
1082
1083 return jsonObject.toString();
1084 }
1085 }
1086 catch (Exception e) {
1087 }
1088
1089 return StringPool.BLANK;
1090 }
1091
1092 protected Set<Locale> getMergedAvailableLocales(
1093 Set<Locale> newFieldAvailableLocales,
1094 Set<Locale> existingFieldAvailableLocales) {
1095
1096 Set<Locale> mergedAvailableLocales = new HashSet<>();
1097
1098 mergedAvailableLocales.addAll(newFieldAvailableLocales);
1099 mergedAvailableLocales.addAll(existingFieldAvailableLocales);
1100
1101 return mergedAvailableLocales;
1102 }
1103
1104 protected List<Serializable> getMergedFieldValues(
1105 String fieldName, List<Serializable> newFieldValues,
1106 String[] newFieldsDisplayValues, List<Serializable> existingFieldValues,
1107 String[] existingFieldsDisplayValues,
1108 List<Serializable> defaultFieldValues) {
1109
1110 if (existingFieldValues == null) {
1111 return newFieldValues;
1112 }
1113
1114 List<Serializable> mergedLocaleValues = new ArrayList<>();
1115
1116 int repetition = countFieldRepetition(
1117 newFieldsDisplayValues, fieldName);
1118
1119 for (int i = 0; i < repetition; i++) {
1120 int existingFieldValueIndex = getExistingFieldValueIndex(
1121 newFieldsDisplayValues, existingFieldsDisplayValues, fieldName,
1122 i);
1123
1124 if (existingFieldValueIndex == -1) {
1125 mergedLocaleValues.add(i, defaultFieldValues.get(i));
1126 }
1127 else {
1128 if (newFieldValues != null) {
1129 mergedLocaleValues.add(i, newFieldValues.get(i));
1130 }
1131 else {
1132 Serializable existingValue = existingFieldValues.get(
1133 existingFieldValueIndex);
1134
1135 mergedLocaleValues.add(i, existingValue);
1136 }
1137 }
1138 }
1139
1140 return mergedLocaleValues;
1141 }
1142
1143 protected Map<Locale, List<Serializable>> getMergedFieldValuesMap(
1144 Field newField, String[] newFieldsDisplayValues, Field existingField,
1145 String[] existingFieldsDisplayValues) {
1146
1147 Set<Locale> availableLocales = getMergedAvailableLocales(
1148 newField.getAvailableLocales(),
1149 existingField.getAvailableLocales());
1150
1151 for (Locale locale : availableLocales) {
1152 List<Serializable> newFieldValues = getFieldValues(
1153 newField, locale);
1154
1155 List<Serializable> existingFieldValues = getFieldValues(
1156 existingField, locale);
1157
1158 List<Serializable> defaultFieldValues = getFieldValues(
1159 newField, newField.getDefaultLocale());
1160
1161 List<Serializable> mergedLocaleValues = getMergedFieldValues(
1162 newField.getName(), newFieldValues, newFieldsDisplayValues,
1163 existingFieldValues, existingFieldsDisplayValues,
1164 defaultFieldValues);
1165
1166 existingField.setValues(locale, mergedLocaleValues);
1167 }
1168
1169 return existingField.getValuesMap();
1170 }
1171
1172 protected String[] splitFieldsDisplayValue(Field fieldsDisplayField) {
1173 String value = (String)fieldsDisplayField.getValue();
1174
1175 return StringUtil.split(value);
1176 }
1177
1178 private static final Log _log = LogFactoryUtil.getLog(DDMImpl.class);
1179
1180 }