001
014
015 package com.liferay.portlet.journal.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.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.util.ArrayUtil;
026 import com.liferay.portal.kernel.util.CharPool;
027 import com.liferay.portal.kernel.util.GetterUtil;
028 import com.liferay.portal.kernel.util.HtmlUtil;
029 import com.liferay.portal.kernel.util.HttpUtil;
030 import com.liferay.portal.kernel.util.LocaleUtil;
031 import com.liferay.portal.kernel.util.SetUtil;
032 import com.liferay.portal.kernel.util.StringBundler;
033 import com.liferay.portal.kernel.util.StringPool;
034 import com.liferay.portal.kernel.util.StringUtil;
035 import com.liferay.portal.kernel.util.Validator;
036 import com.liferay.portal.kernel.xml.Attribute;
037 import com.liferay.portal.kernel.xml.Document;
038 import com.liferay.portal.kernel.xml.Element;
039 import com.liferay.portal.kernel.xml.SAXReaderUtil;
040 import com.liferay.portal.kernel.xml.XPath;
041 import com.liferay.portal.model.Group;
042 import com.liferay.portal.service.GroupLocalServiceUtil;
043 import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
044 import com.liferay.portlet.documentlibrary.util.DLUtil;
045 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
046 import com.liferay.portlet.dynamicdatamapping.storage.Field;
047 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
048 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
049 import com.liferay.portlet.dynamicdatamapping.util.DDMFieldsCounter;
050 import com.liferay.portlet.dynamicdatamapping.util.DDMImpl;
051 import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
052 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
053
054 import java.io.Serializable;
055
056 import java.util.Date;
057 import java.util.HashMap;
058 import java.util.List;
059 import java.util.Locale;
060 import java.util.Map;
061 import java.util.Set;
062 import java.util.regex.Matcher;
063 import java.util.regex.Pattern;
064
065
069 public class JournalConverterImpl implements JournalConverter {
070
071 public static String getDDMXSD(String journalXSD, Locale defaultLocale)
072 throws Exception {
073
074 Document document = SAXReaderUtil.read(journalXSD);
075
076 Element rootElement = document.getRootElement();
077
078 rootElement.addAttribute("available-locales", defaultLocale.toString());
079 rootElement.addAttribute("default-locale", defaultLocale.toString());
080
081 List<Element> dynamicElementElements = rootElement.elements(
082 "dynamic-element");
083
084 for (Element dynamicElementElement : dynamicElementElements) {
085 updateJournalXSDDynamicElement(
086 dynamicElementElement, defaultLocale.toString());
087 }
088
089 return DDMXMLUtil.formatXML(document);
090 }
091
092 public JournalConverterImpl() {
093 _ddmDataTypes = new HashMap<String, String>();
094
095 _ddmDataTypes.put("boolean", "boolean");
096 _ddmDataTypes.put("document_library", "document-library");
097 _ddmDataTypes.put("image", "image");
098 _ddmDataTypes.put("link_to_layout", "link-to-page");
099 _ddmDataTypes.put("list", "string");
100 _ddmDataTypes.put("multi-list", "string");
101 _ddmDataTypes.put("text", "string");
102 _ddmDataTypes.put("text_area", "html");
103 _ddmDataTypes.put("text_box", "string");
104
105 _ddmMetadataAttributes = new HashMap<String, String>();
106
107 _ddmMetadataAttributes.put("instructions", "tip");
108 _ddmMetadataAttributes.put("label", "label");
109 _ddmMetadataAttributes.put("predefinedValue", "predefinedValue");
110
111 _ddmTypesToJournalTypes = new HashMap<String, String>();
112
113 _ddmTypesToJournalTypes.put("checkbox", "boolean");
114 _ddmTypesToJournalTypes.put("ddm-documentlibrary", "document_library");
115 _ddmTypesToJournalTypes.put("ddm-link-to-page", "link_to_layout");
116 _ddmTypesToJournalTypes.put("ddm-separator", "selection_break");
117 _ddmTypesToJournalTypes.put("ddm-text-html", "text_area");
118 _ddmTypesToJournalTypes.put("select", "list");
119 _ddmTypesToJournalTypes.put("text", "text");
120 _ddmTypesToJournalTypes.put("textarea", "text_box");
121 _ddmTypesToJournalTypes.put("wcm-image", "image");
122
123 _journalTypesToDDMTypes = new HashMap<String, String>();
124
125 _journalTypesToDDMTypes.put("boolean", "checkbox");
126 _journalTypesToDDMTypes.put("document_library", "ddm-documentlibrary");
127 _journalTypesToDDMTypes.put("image", "wcm-image");
128 _journalTypesToDDMTypes.put("image_gallery", "ddm-documentlibrary");
129 _journalTypesToDDMTypes.put("link_to_layout", "ddm-link-to-page");
130 _journalTypesToDDMTypes.put("list", "select");
131 _journalTypesToDDMTypes.put("multi-list", "select");
132 _journalTypesToDDMTypes.put("selection_break", "ddm-separator");
133 _journalTypesToDDMTypes.put("text", "text");
134 _journalTypesToDDMTypes.put("text_area", "ddm-text-html");
135 _journalTypesToDDMTypes.put("text_box", "textarea");
136 }
137
138 @Override
139 public String getContent(DDMStructure ddmStructure, Fields ddmFields)
140 throws Exception {
141
142 Document document = SAXReaderUtil.createDocument();
143
144 Element rootElement = document.addElement("root");
145
146 String availableLocales = getAvailableLocales(ddmFields);
147
148 rootElement.addAttribute("available-locales", availableLocales);
149
150 Locale defaultLocale = ddmFields.getDefaultLocale();
151
152 rootElement.addAttribute(
153 "default-locale", LocaleUtil.toLanguageId(defaultLocale));
154
155 DDMFieldsCounter ddmFieldsCounter = new DDMFieldsCounter();
156
157 for (String fieldName : ddmStructure.getRootFieldNames()) {
158 int repetitions = countFieldRepetition(
159 ddmFields, fieldName, null, -1);
160
161 for (int i = 0; i < repetitions; i++) {
162 Element dynamicElementElement = rootElement.addElement(
163 "dynamic-element");
164
165 dynamicElementElement.addAttribute("name", fieldName);
166
167 updateContentDynamicElement(
168 dynamicElementElement, ddmStructure, ddmFields,
169 ddmFieldsCounter);
170 }
171 }
172
173 return DDMXMLUtil.formatXML(document.asXML());
174 }
175
176 @Override
177 public Fields getDDMFields(DDMStructure ddmStructure, String content)
178 throws Exception {
179
180 Document document = SAXReaderUtil.read(content);
181
182 Field fieldsDisplayField = new Field(
183 ddmStructure.getStructureId(), DDMImpl.FIELDS_DISPLAY_NAME,
184 StringPool.BLANK);
185
186 Fields ddmFields = new Fields();
187
188 ddmFields.put(fieldsDisplayField);
189
190 Element rootElement = document.getRootElement();
191
192 String[] availableLanguageIds = StringUtil.split(
193 rootElement.attributeValue("available-locales"));
194 String defaultLanguageId = rootElement.attributeValue("default-locale");
195
196 List<Element> dynamicElementElements = rootElement.elements(
197 "dynamic-element");
198
199 for (Element dynamicElementElement : dynamicElementElements) {
200 addDDMFields(
201 dynamicElementElement, ddmStructure, ddmFields,
202 availableLanguageIds, defaultLanguageId);
203 }
204
205 return ddmFields;
206 }
207
208 @Override
209 public String getDDMXSD(String journalXSD) throws Exception {
210 Locale defaultLocale = LocaleUtil.getSiteDefault();
211
212 return getDDMXSD(journalXSD, defaultLocale);
213 }
214
215 @Override
216 public String getJournalXSD(String ddmXSD) throws Exception {
217 Document document = SAXReaderUtil.read(ddmXSD);
218
219 Element rootElement = document.getRootElement();
220
221 String defaultLanguageId = rootElement.attributeValue("default-locale");
222
223 removeAttribute(rootElement, "available-locales");
224 removeAttribute(rootElement, "default-locale");
225
226 List<Element> dynamicElementElements = rootElement.elements(
227 "dynamic-element");
228
229 for (Element dynamicElementElement : dynamicElementElements) {
230 updateDDMXSDDynamicElement(
231 dynamicElementElement, defaultLanguageId);
232 }
233
234 return DDMXMLUtil.formatXML(document);
235 }
236
237 public String updateDynamicElements(String content) throws Exception {
238 Document document = SAXReaderUtil.read(content);
239
240 Element rootElement = document.getRootElement();
241
242 List<Element> dynamicElements = rootElement.elements("dynamic-element");
243
244 if ((dynamicElements == null) || dynamicElements.isEmpty()) {
245 return content;
246 }
247
248 Element firstElement = dynamicElements.get(0);
249
250 if (Validator.isNotNull(firstElement.attributeValue("instance-id"))) {
251 return content;
252 }
253
254 for (Element dynamicElement : dynamicElements) {
255 updateElement(dynamicElement);
256 }
257
258 return document.asXML();
259 }
260
261 protected static void addMetadataEntry(
262 Element metadataElement, String name, String value) {
263
264 Element entryElement = metadataElement.addElement("entry");
265
266 entryElement.addAttribute("name", name);
267 entryElement.addCDATA(value);
268 }
269
270 protected static String decodeURL(String url) {
271 try {
272 return HttpUtil.decodeURL(url);
273 }
274 catch (IllegalArgumentException iae) {
275 return url;
276 }
277 }
278
279 protected static Element fetchMetadataEntry(
280 Element parentElement, String attributeName, String attributeValue) {
281
282 StringBundler sb = new StringBundler();
283
284 sb.append("entry[@");
285 sb.append(attributeName);
286 sb.append(StringPool.EQUAL);
287 sb.append(HtmlUtil.escapeXPathAttribute(attributeValue));
288 sb.append(StringPool.CLOSE_BRACKET);
289
290 XPath xPathSelector = SAXReaderUtil.createXPath(sb.toString());
291
292 return (Element)xPathSelector.selectSingleNode(parentElement);
293 }
294
295 protected static void updateJournalXSDDynamicElement(
296 Element element, String defaultLanguageId) {
297
298 String name = element.attributeValue("name");
299 String type = element.attributeValue("type");
300
301 Element metadataElement = element.element("meta-data");
302
303 if (metadataElement == null) {
304 metadataElement = element.addElement("meta-data");
305 }
306
307 if (type.equals("multi-list")) {
308 element.addAttribute("multiple", "true");
309 }
310 else {
311 Element parentElement = element.getParent();
312
313 String parentType = parentElement.attributeValue("type");
314
315 if ((parentType != null) && parentType.equals("select")) {
316 metadataElement.addAttribute("locale", defaultLanguageId);
317
318 addMetadataEntry(metadataElement, "label", decodeURL(name));
319
320 Attribute indexTypeAttribute = element.attribute("index-type");
321
322 if (indexTypeAttribute != null) {
323 element.remove(indexTypeAttribute);
324 }
325
326 element.addAttribute(
327 "name",
328 "option" + parentElement.attributeValue("name") +
329 StringUtil.randomString(8));
330 element.addAttribute("type", "option");
331 element.addAttribute("value", decodeURL(type));
332
333 return;
334 }
335 }
336
337 String indexType = StringPool.BLANK;
338
339 Attribute indexTypeAttribute = element.attribute("index-type");
340
341 if (indexTypeAttribute != null) {
342 indexType = indexTypeAttribute.getValue();
343
344 element.remove(indexTypeAttribute);
345 }
346
347 element.remove(element.attribute("type"));
348
349 if (!type.equals("selection_break")) {
350 String dataType = _ddmDataTypes.get(type);
351
352 if (dataType == null) {
353 dataType = "string";
354 }
355
356 element.addAttribute("dataType", dataType);
357 }
358
359 element.addAttribute("indexType", indexType);
360
361 String required = "false";
362
363 Element requiredElement = fetchMetadataEntry(
364 metadataElement, "name", "required");
365
366 if (requiredElement != null) {
367 required = requiredElement.getText();
368 }
369
370 element.addAttribute("required", required);
371
372 element.addAttribute("showLabel", "true");
373
374 String newType = _journalTypesToDDMTypes.get(type);
375
376 if (newType == null) {
377 newType = type;
378 }
379
380 element.addAttribute("type", newType);
381
382 if (newType.startsWith("ddm")) {
383 element.addAttribute("fieldNamespace", "ddm");
384 }
385
386 metadataElement.addAttribute("locale", defaultLanguageId);
387
388 List<Element> entryElements = metadataElement.elements();
389
390 if (entryElements.isEmpty()) {
391 addMetadataEntry(metadataElement, "label", name);
392 }
393 else {
394 for (Element entryElement : entryElements) {
395 String oldEntryName = entryElement.attributeValue("name");
396
397 String newEntryName = _ddmMetadataAttributes.get(oldEntryName);
398
399 if (newEntryName == null) {
400 metadataElement.remove(entryElement);
401 }
402 else {
403 entryElement.addAttribute("name", newEntryName);
404 }
405 }
406 }
407
408 if (newType.equals("ddm-date") || newType.equals("ddm-decimal") ||
409 newType.equals("ddm-integer") ||
410 newType.equals("ddm-link-to-page") ||
411 newType.equals("ddm-number") || newType.equals("ddm-text-html") ||
412 newType.equals("text") || newType.equals("textarea")) {
413
414 element.addAttribute("width", "25");
415 }
416 else if (newType.equals("wcm-image")) {
417 element.addAttribute("fieldNamespace", "wcm");
418 element.addAttribute("readOnly", "false");
419 }
420
421 element.add(metadataElement.detach());
422
423 List<Element> dynamicElementElements = element.elements(
424 "dynamic-element");
425
426 for (Element dynamicElementElement : dynamicElementElements) {
427 updateJournalXSDDynamicElement(
428 dynamicElementElement, defaultLanguageId);
429 }
430 }
431
432 protected void addDDMFields(
433 Element dynamicElementElement, DDMStructure ddmStructure,
434 Fields ddmFields, String[] availableLanguageIds,
435 String defaultLanguageId)
436 throws Exception {
437
438 String name = dynamicElementElement.attributeValue("name");
439 String index = dynamicElementElement.attributeValue("index");
440 String instanceId = dynamicElementElement.attributeValue("instance-id");
441
442 if (!ddmStructure.hasField(name)) {
443 return;
444 }
445
446 if (!ddmStructure.isFieldTransient(name)) {
447 Field ddmField = getField(
448 dynamicElementElement, ddmStructure, availableLanguageIds,
449 defaultLanguageId);
450
451 String fieldName = ddmField.getName();
452
453 Field existingDDMField = ddmFields.get(fieldName);
454
455 if (existingDDMField != null) {
456 for (Locale locale : ddmField.getAvailableLocales()) {
457 existingDDMField.addValues(
458 locale, ddmField.getValues(locale));
459 }
460 }
461 else {
462 ddmFields.put(ddmField);
463 }
464 }
465
466 updateFieldsDisplay(ddmFields, name, index, instanceId);
467
468 List<Element> childrenDynamicElementElements =
469 dynamicElementElement.elements("dynamic-element");
470
471 for (Element childrenDynamicElementElement :
472 childrenDynamicElementElements) {
473
474 addDDMFields(
475 childrenDynamicElementElement, ddmStructure, ddmFields,
476 availableLanguageIds, defaultLanguageId);
477 }
478 }
479
480 protected void addMissingFieldValues(
481 Field ddmField, String defaultLanguageId,
482 Set<String> missingLanguageIds) {
483
484 if (missingLanguageIds.isEmpty()) {
485 return;
486 }
487
488 Locale defaultLocale = LocaleUtil.fromLanguageId(defaultLanguageId);
489
490 Serializable fieldValue = ddmField.getValue(defaultLocale);
491
492 for (String missingLanguageId : missingLanguageIds) {
493 Locale missingLocale = LocaleUtil.fromLanguageId(missingLanguageId);
494
495 ddmField.setValue(missingLocale, fieldValue);
496 }
497 }
498
499 protected int countFieldRepetition(
500 Fields ddmFields, String fieldName, String parentFieldName,
501 int parentOffset)
502 throws Exception {
503
504 Field fieldsDisplayField = ddmFields.get(DDMImpl.FIELDS_DISPLAY_NAME);
505
506 String[] fieldsDisplayValues = DDMUtil.getFieldsDisplayValues(
507 fieldsDisplayField);
508
509 int offset = -1;
510
511 int repetitions = 0;
512
513 for (int i = 0; i < fieldsDisplayValues.length; i++) {
514 String fieldDisplayName = fieldsDisplayValues[i];
515
516 if (offset > parentOffset) {
517 break;
518 }
519
520 if (fieldDisplayName.equals(parentFieldName)) {
521 offset++;
522 }
523
524 if (fieldDisplayName.equals(fieldName) &&
525 (offset == parentOffset)) {
526
527 repetitions++;
528 }
529 }
530
531 return repetitions;
532 }
533
534 protected String getAvailableLocales(Fields ddmFields) {
535 Set<Locale> availableLocales = ddmFields.getAvailableLocales();
536
537 Locale[] availableLocalesArray = new Locale[availableLocales.size()];
538
539 availableLocalesArray = availableLocales.toArray(availableLocalesArray);
540
541 String[] languageIds = LocaleUtil.toLanguageIds(availableLocalesArray);
542
543 return StringUtil.merge(languageIds);
544 }
545
546 protected Serializable getDocumentLibraryValue(String url) {
547 try {
548 FileEntry fileEntry = null;
549
550 if (url.contains("/c/document_library/get_file?") ||
551 url.contains("/image/image_gallery?")) {
552
553 fileEntry = getFileEntryByOldDocumentLibraryURL(url);
554 }
555 else if (url.contains("/documents/")) {
556 fileEntry = getFileEntryByDocumentLibraryURL(url);
557 }
558
559 if (fileEntry == null) {
560 return StringPool.BLANK;
561 }
562
563 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
564
565 jsonObject.put("groupId", fileEntry.getGroupId());
566 jsonObject.put("title", fileEntry.getTitle());
567 jsonObject.put("uuid", fileEntry.getUuid());
568 jsonObject.put("version", fileEntry.getVersion());
569
570 return jsonObject.toString();
571 }
572 catch (Exception e) {
573 if (_log.isWarnEnabled()) {
574 _log.warn("Error retrieving file entry", e);
575 }
576 }
577
578 return StringPool.BLANK;
579 }
580
581 protected Field getField(
582 Element dynamicElementElement, DDMStructure ddmStructure,
583 String[] availableLanguageIds, String defaultLanguageId)
584 throws Exception {
585
586 Field ddmField = new Field();
587
588 ddmField.setDDMStructureId(ddmStructure.getStructureId());
589 ddmField.setDefaultLocale(LocaleUtil.fromLanguageId(defaultLanguageId));
590
591 String name = dynamicElementElement.attributeValue("name");
592
593 ddmField.setName(name);
594
595 String dataType = ddmStructure.getFieldDataType(name);
596 String type = ddmStructure.getFieldType(name);
597
598 Set<String> missingLanguageIds = SetUtil.fromArray(
599 availableLanguageIds);
600
601 missingLanguageIds.remove(defaultLanguageId);
602
603 boolean localizable = GetterUtil.getBoolean(
604 ddmStructure.getFieldProperty(name, "localizable"), true);
605
606 List<Element> dynamicContentElements = dynamicElementElement.elements(
607 "dynamic-content");
608
609 for (Element dynamicContentElement : dynamicContentElements) {
610 Locale locale = LocaleUtil.fromLanguageId(defaultLanguageId);
611
612 String languageId = dynamicContentElement.attributeValue(
613 "language-id", defaultLanguageId);
614
615 if (!localizable && !languageId.equals(defaultLanguageId)) {
616 continue;
617 }
618
619 if (Validator.isNotNull(languageId)) {
620 locale = LocaleUtil.fromLanguageId(languageId);
621
622 missingLanguageIds.remove(languageId);
623 }
624
625 Serializable serializable = getFieldValue(
626 dataType, type, dynamicContentElement);
627
628 ddmField.addValue(locale, serializable);
629 }
630
631 addMissingFieldValues(ddmField, defaultLanguageId, missingLanguageIds);
632
633 return ddmField;
634 }
635
636 protected String getFieldInstanceId(
637 Fields ddmFields, String fieldName, int index) {
638
639 Field fieldsDisplayField = ddmFields.get(DDMImpl.FIELDS_DISPLAY_NAME);
640
641 String prefix = fieldName.concat(DDMImpl.INSTANCE_SEPARATOR);
642
643 String[] fieldsDisplayValues = DDMUtil.splitFieldsDisplayValue(
644 fieldsDisplayField);
645
646 for (String fieldsDisplayValue : fieldsDisplayValues) {
647 if (fieldsDisplayValue.startsWith(prefix)) {
648 index--;
649
650 if (index < 0) {
651 return StringUtil.extractLast(
652 fieldsDisplayValue, DDMImpl.INSTANCE_SEPARATOR);
653 }
654 }
655 }
656
657 return null;
658 }
659
660 protected Serializable getFieldValue(
661 String dataType, String type, Element dynamicContentElement)
662 throws Exception {
663
664 Serializable serializable = null;
665
666 if (DDMImpl.TYPE_DDM_DOCUMENTLIBRARY.equals(type)) {
667 serializable = getDocumentLibraryValue(
668 dynamicContentElement.getText());
669 }
670 else if (DDMImpl.TYPE_DDM_LINK_TO_PAGE.equals(type)) {
671 String[] values = StringUtil.split(
672 dynamicContentElement.getText(), CharPool.AT);
673
674 if (ArrayUtil.isEmpty(values)) {
675 return StringPool.BLANK;
676 }
677
678 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
679
680 if (values.length > 2) {
681 jsonObject.put("groupId", values[2]);
682 }
683
684 jsonObject.put("layoutId", values[0]);
685
686 if (values[1].equals("public")) {
687 jsonObject.put("privateLayout", false);
688 }
689 else {
690 jsonObject.put("privateLayout", true);
691 }
692
693 serializable = jsonObject.toString();
694 }
695 else if (DDMImpl.TYPE_SELECT.equals(type)) {
696 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
697
698 List<Element> optionElements = dynamicContentElement.elements(
699 "option");
700
701 if (optionElements.size() > 0) {
702 for (Element optionElement : optionElements) {
703 jsonArray.put(optionElement.getText());
704 }
705 }
706 else {
707 jsonArray.put(dynamicContentElement.getText());
708 }
709
710 serializable = jsonArray.toString();
711 }
712 else {
713 serializable = FieldConstants.getSerializable(
714 dataType, dynamicContentElement.getText());
715 }
716
717 return serializable;
718 }
719
720 protected FileEntry getFileEntryByDocumentLibraryURL(String url)
721 throws PortalException, SystemException {
722
723 int x = url.indexOf("/documents/");
724
725 int y = url.indexOf(StringPool.QUESTION);
726
727 if (y == -1) {
728 y = url.length();
729 }
730
731 url = url.substring(x, y);
732
733 String[] parts = StringUtil.split(url, CharPool.SLASH);
734
735 long groupId = GetterUtil.getLong(parts[2]);
736
737 return DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
738 parts[5], groupId);
739 }
740
741 protected FileEntry getFileEntryByOldDocumentLibraryURL(String url)
742 throws PortalException, SystemException {
743
744 Matcher matcher = _oldDocumentLibraryURLPattern.matcher(url);
745
746 if (!matcher.find()) {
747 return null;
748 }
749
750 long groupId = GetterUtil.getLong(matcher.group(2));
751
752 return DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
753 matcher.group(1), groupId);
754 }
755
756 protected void getJournalMetadataElement(Element metadataElement) {
757 removeAttribute(metadataElement, "locale");
758
759 Element dynamicElementElement = metadataElement.getParent();
760
761
762
763 boolean required = GetterUtil.getBoolean(
764 dynamicElementElement.attributeValue("required"));
765
766 addMetadataEntry(metadataElement, "required", String.valueOf(required));
767
768
769
770 Element tipElement = fetchMetadataEntry(metadataElement, "name", "tip");
771
772 if (tipElement != null) {
773 tipElement.addAttribute("name", "instructions");
774
775 addMetadataEntry(metadataElement, "displayAsTooltip", "true");
776 }
777 }
778
779 protected void removeAttribute(Element element, String attributeName) {
780 Attribute attribute = element.attribute(attributeName);
781
782 if (attribute == null) {
783 return;
784 }
785
786 element.remove(attribute);
787 }
788
789 protected void updateContentDynamicElement(
790 Element dynamicElementElement, DDMStructure ddmStructure,
791 Fields ddmFields, DDMFieldsCounter ddmFieldsCounter)
792 throws Exception {
793
794 String fieldName = dynamicElementElement.attributeValue("name");
795
796 for (String childFieldName :
797 ddmStructure.getChildrenFieldNames(fieldName)) {
798
799 int count = ddmFieldsCounter.get(fieldName);
800
801 int repetitions = countFieldRepetition(
802 ddmFields, childFieldName, fieldName, count);
803
804 for (int i = 0; i < repetitions; i++) {
805 Element childDynamicElementElement =
806 dynamicElementElement.addElement("dynamic-element");
807
808 childDynamicElementElement.addAttribute("name", childFieldName);
809 childDynamicElementElement.addAttribute(
810 "index", String.valueOf(i));
811
812 String instanceId = getFieldInstanceId(
813 ddmFields, fieldName, (count + i));
814
815 childDynamicElementElement.addAttribute(
816 "instance-id", instanceId);
817
818 updateContentDynamicElement(
819 childDynamicElementElement, ddmStructure, ddmFields,
820 ddmFieldsCounter);
821 }
822 }
823
824 updateContentDynamicElement(
825 dynamicElementElement, ddmStructure, ddmFields, fieldName,
826 ddmFieldsCounter);
827 }
828
829 protected void updateContentDynamicElement(
830 Element dynamicElementElement, DDMStructure ddmStructure,
831 Fields ddmFields, String fieldName,
832 DDMFieldsCounter ddmFieldsCounter)
833 throws Exception {
834
835 String fieldType = ddmStructure.getFieldType(fieldName);
836 String indexType = ddmStructure.getFieldProperty(
837 fieldName, "indexType");
838 boolean multiple = GetterUtil.getBoolean(
839 ddmStructure.getFieldProperty(fieldName, "multiple"));
840
841 String type = _ddmTypesToJournalTypes.get(fieldType);
842
843 if (type == null) {
844 type = fieldType;
845 }
846
847 dynamicElementElement.addAttribute("type", type);
848
849 dynamicElementElement.addAttribute("index-type", indexType);
850
851 int count = ddmFieldsCounter.get(fieldName);
852
853 dynamicElementElement.addAttribute("index", String.valueOf(count));
854
855 String instanceId = getFieldInstanceId(ddmFields, fieldName, count);
856
857 dynamicElementElement.addAttribute("instance-id", instanceId);
858
859 Field ddmField = ddmFields.get(fieldName);
860
861 if (!ddmStructure.isFieldTransient(fieldName) && (ddmField != null)) {
862 for (Locale locale : ddmField.getAvailableLocales()) {
863 Element dynamicContentElement =
864 dynamicElementElement.addElement("dynamic-content");
865
866 dynamicContentElement.addAttribute(
867 "language-id", LocaleUtil.toLanguageId(locale));
868
869 Serializable fieldValue = ddmField.getValue(locale, count);
870
871 if (fieldValue instanceof Date) {
872 Date valueDate = (Date)fieldValue;
873
874 fieldValue = valueDate.getTime();
875 }
876
877 String valueString = String.valueOf(fieldValue);
878
879 updateDynamicContentValue(
880 dynamicContentElement, fieldType, multiple,
881 valueString.trim());
882 }
883 }
884
885 ddmFieldsCounter.incrementKey(fieldName);
886 }
887
888 protected void updateDDMXSDDynamicElement(
889 Element dynamicElementElement, String defaultLanguageId) {
890
891
892
893 List<Element> metadataElements = dynamicElementElement.elements(
894 "meta-data");
895
896 for (Element metadataElement : metadataElements) {
897 String languageId = metadataElement.attributeValue("locale");
898
899 if (languageId.equals(defaultLanguageId)) {
900 getJournalMetadataElement(metadataElement);
901 }
902 else {
903 dynamicElementElement.remove(metadataElement);
904 }
905 }
906
907 Element parentElement = dynamicElementElement.getParent();
908
909 String parentType = parentElement.attributeValue("type");
910
911 if (Validator.equals(parentType, "list") ||
912 Validator.equals(parentType, "multi-list")) {
913
914 Element metadataElement = dynamicElementElement.element(
915 "meta-data");
916
917 Element labelElement = fetchMetadataEntry(
918 metadataElement, "name", "label");
919
920 String repeatable = parentElement.attributeValue("repeatable");
921
922 String value = dynamicElementElement.attributeValue("value");
923
924 dynamicElementElement.addAttribute("name", labelElement.getText());
925 dynamicElementElement.addAttribute("repeatable", repeatable);
926 dynamicElementElement.addAttribute("type", value);
927
928 removeAttribute(dynamicElementElement, "value");
929
930 dynamicElementElement.remove(metadataElement);
931
932 return;
933 }
934
935
936
937 String indexType = GetterUtil.getString(
938 dynamicElementElement.attributeValue("indexType"));
939
940 removeAttribute(dynamicElementElement, "indexType");
941
942 dynamicElementElement.addAttribute("index-type", indexType);
943
944
945
946 String type = dynamicElementElement.attributeValue("type");
947
948 boolean multiple = GetterUtil.getBoolean(
949 dynamicElementElement.attributeValue("multiple"));
950
951 String newType = _ddmTypesToJournalTypes.get(type);
952
953 if (newType.equals("list") && multiple) {
954 newType = "multi-list";
955 }
956
957 dynamicElementElement.addAttribute("type", newType);
958
959
960
961 String[] removableAttributeNames = new String[] {
962 "dataType", "fieldNamespace", "multiple", "readOnly", "required",
963 "showLabel", "width"
964 };
965
966 for (String removableAttributeName : removableAttributeNames) {
967 removeAttribute(dynamicElementElement, removableAttributeName);
968 }
969
970 List<Element> childrenDynamicElementElements =
971 dynamicElementElement.elements("dynamic-element");
972
973 for (Element childrenDynamicElementElement :
974 childrenDynamicElementElements) {
975
976 updateDDMXSDDynamicElement(
977 childrenDynamicElementElement, defaultLanguageId);
978 }
979 }
980
981 protected void updateDynamicContentValue(
982 Element dynamicContentElement, String fieldType, boolean multiple,
983 String fieldValue)
984 throws Exception {
985
986 if (DDMImpl.TYPE_CHECKBOX.equals(fieldType)) {
987 if (fieldValue.equals(Boolean.FALSE.toString())) {
988 fieldValue = StringPool.BLANK;
989 }
990
991 dynamicContentElement.addCDATA(fieldValue);
992 }
993 else if (DDMImpl.TYPE_DDM_DOCUMENTLIBRARY.equals(fieldType) &&
994 Validator.isNotNull(fieldValue)) {
995
996 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
997 fieldValue);
998
999 String uuid = jsonObject.getString("uuid");
1000 long groupId = jsonObject.getLong("groupId");
1001
1002 FileEntry fileEntry =
1003 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
1004 uuid, groupId);
1005
1006 fieldValue = DLUtil.getPreviewURL(
1007 fileEntry, fileEntry.getFileVersion(), null, StringPool.BLANK,
1008 false, true);
1009
1010 dynamicContentElement.addCDATA(fieldValue);
1011 }
1012 else if (DDMImpl.TYPE_DDM_IMAGE.equals(fieldType) &&
1013 Validator.isNotNull(fieldValue)) {
1014
1015 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
1016 fieldValue);
1017
1018 dynamicContentElement.addAttribute(
1019 "alt", jsonObject.getString("alt"));
1020 dynamicContentElement.addCDATA(jsonObject.getString("data"));
1021 }
1022 else if (DDMImpl.TYPE_DDM_LINK_TO_PAGE.equals(fieldType) &&
1023 Validator.isNotNull(fieldValue)) {
1024
1025 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
1026 fieldValue);
1027
1028 long groupId = jsonObject.getLong("groupId");
1029
1030 String layoutId = jsonObject.getString("layoutId");
1031
1032 boolean privateLayout = jsonObject.getBoolean("privateLayout");
1033
1034 StringBundler sb = new StringBundler((groupId > 0) ? 5 : 3);
1035
1036 sb.append(layoutId);
1037 sb.append(StringPool.AT);
1038
1039 if (privateLayout) {
1040 Group group = GroupLocalServiceUtil.fetchGroup(groupId);
1041
1042 if (group == null) {
1043 sb.append("private");
1044 }
1045 else if (group.isUser()) {
1046 sb.append("private-user");
1047 }
1048 else {
1049 sb.append("private-group");
1050 }
1051 }
1052 else {
1053 sb.append("public");
1054 }
1055
1056 if (groupId > 0) {
1057 sb.append(StringPool.AT);
1058 sb.append(groupId);
1059 }
1060
1061 dynamicContentElement.addCDATA(sb.toString());
1062 }
1063 else if (DDMImpl.TYPE_SELECT.equals(fieldType) &&
1064 Validator.isNotNull(fieldValue)) {
1065
1066 JSONArray jsonArray = JSONFactoryUtil.createJSONArray(fieldValue);
1067
1068 if (multiple) {
1069 for (int i = 0; i < jsonArray.length(); i++) {
1070 Element optionElement = dynamicContentElement.addElement(
1071 "option");
1072
1073 optionElement.addCDATA(jsonArray.getString(i));
1074 }
1075 }
1076 else {
1077 dynamicContentElement.addCDATA(jsonArray.getString(0));
1078 }
1079 }
1080 else {
1081 dynamicContentElement.addCDATA(fieldValue);
1082 }
1083 }
1084
1085 protected void updateElement(Element element) {
1086 List<Element> dynamicElementElements = element.elements(
1087 "dynamic-element");
1088
1089 for (Element dynamicElementElement : dynamicElementElements) {
1090 updateElement(dynamicElementElement);
1091 }
1092
1093 String instanceId = element.attributeValue("instance-id");
1094
1095 if (Validator.isNull(instanceId)) {
1096 element.addAttribute("instance-id", StringUtil.randomString(4));
1097 }
1098 }
1099
1100 protected void updateFieldsDisplay(
1101 Fields ddmFields, String fieldName, String index, String instanceId) {
1102
1103 if (Validator.isNull(instanceId)) {
1104 instanceId = fieldName.concat(GetterUtil.getString(index));
1105 }
1106
1107 String fieldsDisplayValue = fieldName.concat(
1108 DDMImpl.INSTANCE_SEPARATOR).concat(instanceId);
1109
1110 Field fieldsDisplayField = ddmFields.get(DDMImpl.FIELDS_DISPLAY_NAME);
1111
1112 String[] fieldsDisplayValues = DDMUtil.splitFieldsDisplayValue(
1113 fieldsDisplayField);
1114
1115 fieldsDisplayValues = ArrayUtil.append(
1116 fieldsDisplayValues, fieldsDisplayValue);
1117
1118 fieldsDisplayField.setValue(StringUtil.merge(fieldsDisplayValues));
1119 }
1120
1121 protected void updateJournalXSDDynamicElement(Element element) {
1122 Locale defaultLocale = LocaleUtil.getSiteDefault();
1123
1124 updateJournalXSDDynamicElement(
1125 element, LocaleUtil.toLanguageId(defaultLocale));
1126 }
1127
1128 private static Log _log = LogFactoryUtil.getLog(JournalConverterImpl.class);
1129
1130 private static Map<String, String> _ddmDataTypes;
1131 private static Map<String, String> _ddmMetadataAttributes;
1132 private static Map<String, String> _journalTypesToDDMTypes;
1133
1134 private Map<String, String> _ddmTypesToJournalTypes;
1135 private final Pattern _oldDocumentLibraryURLPattern = Pattern.compile(
1136 "uuid=([^&]+)&groupId=([^&]+)");
1137
1138 }