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
590 Locale defaultLocale = null;
591
592 if (defaultLanguageId == null) {
593 defaultLocale = LocaleUtil.getSiteDefault();
594 }
595 else {
596 defaultLocale = LocaleUtil.fromLanguageId(defaultLanguageId);
597 }
598
599 ddmField.setDefaultLocale(defaultLocale);
600
601 String name = dynamicElementElement.attributeValue("name");
602
603 ddmField.setName(name);
604
605 String dataType = ddmStructure.getFieldDataType(name);
606 String type = ddmStructure.getFieldType(name);
607
608 Set<String> missingLanguageIds = SetUtil.fromArray(
609 availableLanguageIds);
610
611 missingLanguageIds.remove(defaultLanguageId);
612
613 boolean localizable = GetterUtil.getBoolean(
614 ddmStructure.getFieldProperty(name, "localizable"), true);
615
616 List<Element> dynamicContentElements = dynamicElementElement.elements(
617 "dynamic-content");
618
619 for (Element dynamicContentElement : dynamicContentElements) {
620 Locale locale = defaultLocale;
621
622 String languageId = dynamicContentElement.attributeValue(
623 "language-id", defaultLanguageId);
624
625 if (!localizable && !languageId.equals(defaultLanguageId)) {
626 continue;
627 }
628
629 if (Validator.isNotNull(languageId)) {
630 locale = LocaleUtil.fromLanguageId(languageId);
631
632 missingLanguageIds.remove(languageId);
633 }
634
635 Serializable serializable = getFieldValue(
636 dataType, type, dynamicContentElement);
637
638 ddmField.addValue(locale, serializable);
639 }
640
641 addMissingFieldValues(ddmField, defaultLanguageId, missingLanguageIds);
642
643 return ddmField;
644 }
645
646 protected String getFieldInstanceId(
647 Fields ddmFields, String fieldName, int index) {
648
649 Field fieldsDisplayField = ddmFields.get(DDMImpl.FIELDS_DISPLAY_NAME);
650
651 String prefix = fieldName.concat(DDMImpl.INSTANCE_SEPARATOR);
652
653 String[] fieldsDisplayValues = DDMUtil.splitFieldsDisplayValue(
654 fieldsDisplayField);
655
656 for (String fieldsDisplayValue : fieldsDisplayValues) {
657 if (fieldsDisplayValue.startsWith(prefix)) {
658 index--;
659
660 if (index < 0) {
661 return StringUtil.extractLast(
662 fieldsDisplayValue, DDMImpl.INSTANCE_SEPARATOR);
663 }
664 }
665 }
666
667 return null;
668 }
669
670 protected Serializable getFieldValue(
671 String dataType, String type, Element dynamicContentElement)
672 throws Exception {
673
674 Serializable serializable = null;
675
676 if (DDMImpl.TYPE_DDM_DOCUMENTLIBRARY.equals(type)) {
677 serializable = getDocumentLibraryValue(
678 dynamicContentElement.getText());
679 }
680 else if (DDMImpl.TYPE_DDM_LINK_TO_PAGE.equals(type)) {
681 String[] values = StringUtil.split(
682 dynamicContentElement.getText(), CharPool.AT);
683
684 if (ArrayUtil.isEmpty(values)) {
685 return StringPool.BLANK;
686 }
687
688 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
689
690 if (values.length > 2) {
691 jsonObject.put("groupId", values[2]);
692 }
693
694 jsonObject.put("layoutId", values[0]);
695
696 if (values[1].equals("public")) {
697 jsonObject.put("privateLayout", false);
698 }
699 else {
700 jsonObject.put("privateLayout", true);
701 }
702
703 serializable = jsonObject.toString();
704 }
705 else if (DDMImpl.TYPE_SELECT.equals(type)) {
706 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
707
708 List<Element> optionElements = dynamicContentElement.elements(
709 "option");
710
711 if (optionElements.size() > 0) {
712 for (Element optionElement : optionElements) {
713 jsonArray.put(optionElement.getText());
714 }
715 }
716 else {
717 jsonArray.put(dynamicContentElement.getText());
718 }
719
720 serializable = jsonArray.toString();
721 }
722 else {
723 serializable = FieldConstants.getSerializable(
724 dataType, dynamicContentElement.getText());
725 }
726
727 return serializable;
728 }
729
730 protected FileEntry getFileEntryByDocumentLibraryURL(String url)
731 throws PortalException, SystemException {
732
733 int x = url.indexOf("/documents/");
734
735 int y = url.indexOf(StringPool.QUESTION);
736
737 if (y == -1) {
738 y = url.length();
739 }
740
741 url = url.substring(x, y);
742
743 String[] parts = StringUtil.split(url, CharPool.SLASH);
744
745 long groupId = GetterUtil.getLong(parts[2]);
746
747 return DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
748 parts[5], groupId);
749 }
750
751 protected FileEntry getFileEntryByOldDocumentLibraryURL(String url)
752 throws PortalException, SystemException {
753
754 Matcher matcher = _oldDocumentLibraryURLPattern.matcher(url);
755
756 if (!matcher.find()) {
757 return null;
758 }
759
760 long groupId = GetterUtil.getLong(matcher.group(2));
761
762 return DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
763 matcher.group(1), groupId);
764 }
765
766 protected void getJournalMetadataElement(Element metadataElement) {
767 removeAttribute(metadataElement, "locale");
768
769 Element dynamicElementElement = metadataElement.getParent();
770
771
772
773 boolean required = GetterUtil.getBoolean(
774 dynamicElementElement.attributeValue("required"));
775
776 addMetadataEntry(metadataElement, "required", String.valueOf(required));
777
778
779
780 Element tipElement = fetchMetadataEntry(metadataElement, "name", "tip");
781
782 if (tipElement != null) {
783 tipElement.addAttribute("name", "instructions");
784
785 addMetadataEntry(metadataElement, "displayAsTooltip", "true");
786 }
787 }
788
789 protected void removeAttribute(Element element, String attributeName) {
790 Attribute attribute = element.attribute(attributeName);
791
792 if (attribute == null) {
793 return;
794 }
795
796 element.remove(attribute);
797 }
798
799 protected void updateContentDynamicElement(
800 Element dynamicElementElement, DDMStructure ddmStructure,
801 Fields ddmFields, DDMFieldsCounter ddmFieldsCounter)
802 throws Exception {
803
804 String fieldName = dynamicElementElement.attributeValue("name");
805
806 for (String childFieldName :
807 ddmStructure.getChildrenFieldNames(fieldName)) {
808
809 int count = ddmFieldsCounter.get(fieldName);
810
811 int repetitions = countFieldRepetition(
812 ddmFields, childFieldName, fieldName, count);
813
814 for (int i = 0; i < repetitions; i++) {
815 Element childDynamicElementElement =
816 dynamicElementElement.addElement("dynamic-element");
817
818 childDynamicElementElement.addAttribute("name", childFieldName);
819 childDynamicElementElement.addAttribute(
820 "index", String.valueOf(i));
821
822 String instanceId = getFieldInstanceId(
823 ddmFields, fieldName, (count + i));
824
825 childDynamicElementElement.addAttribute(
826 "instance-id", instanceId);
827
828 updateContentDynamicElement(
829 childDynamicElementElement, ddmStructure, ddmFields,
830 ddmFieldsCounter);
831 }
832 }
833
834 updateContentDynamicElement(
835 dynamicElementElement, ddmStructure, ddmFields, fieldName,
836 ddmFieldsCounter);
837 }
838
839 protected void updateContentDynamicElement(
840 Element dynamicElementElement, DDMStructure ddmStructure,
841 Fields ddmFields, String fieldName,
842 DDMFieldsCounter ddmFieldsCounter)
843 throws Exception {
844
845 String fieldType = ddmStructure.getFieldType(fieldName);
846 String indexType = ddmStructure.getFieldProperty(
847 fieldName, "indexType");
848 boolean multiple = GetterUtil.getBoolean(
849 ddmStructure.getFieldProperty(fieldName, "multiple"));
850
851 String type = _ddmTypesToJournalTypes.get(fieldType);
852
853 if (type == null) {
854 type = fieldType;
855 }
856
857 dynamicElementElement.addAttribute("type", type);
858
859 dynamicElementElement.addAttribute("index-type", indexType);
860
861 int count = ddmFieldsCounter.get(fieldName);
862
863 dynamicElementElement.addAttribute("index", String.valueOf(count));
864
865 String instanceId = getFieldInstanceId(ddmFields, fieldName, count);
866
867 dynamicElementElement.addAttribute("instance-id", instanceId);
868
869 Field ddmField = ddmFields.get(fieldName);
870
871 if (!ddmStructure.isFieldTransient(fieldName) && (ddmField != null)) {
872 for (Locale locale : ddmField.getAvailableLocales()) {
873 Element dynamicContentElement =
874 dynamicElementElement.addElement("dynamic-content");
875
876 dynamicContentElement.addAttribute(
877 "language-id", LocaleUtil.toLanguageId(locale));
878
879 Serializable fieldValue = ddmField.getValue(locale, count);
880
881 if (fieldValue instanceof Date) {
882 Date valueDate = (Date)fieldValue;
883
884 fieldValue = valueDate.getTime();
885 }
886
887 String valueString = String.valueOf(fieldValue);
888
889 updateDynamicContentValue(
890 dynamicContentElement, fieldType, multiple,
891 valueString.trim());
892 }
893 }
894
895 ddmFieldsCounter.incrementKey(fieldName);
896 }
897
898 protected void updateDDMXSDDynamicElement(
899 Element dynamicElementElement, String defaultLanguageId) {
900
901
902
903 List<Element> metadataElements = dynamicElementElement.elements(
904 "meta-data");
905
906 for (Element metadataElement : metadataElements) {
907 String languageId = metadataElement.attributeValue("locale");
908
909 if (languageId.equals(defaultLanguageId)) {
910 getJournalMetadataElement(metadataElement);
911 }
912 else {
913 dynamicElementElement.remove(metadataElement);
914 }
915 }
916
917 Element parentElement = dynamicElementElement.getParent();
918
919 String parentType = parentElement.attributeValue("type");
920
921 if (Validator.equals(parentType, "list") ||
922 Validator.equals(parentType, "multi-list")) {
923
924 Element metadataElement = dynamicElementElement.element(
925 "meta-data");
926
927 Element labelElement = fetchMetadataEntry(
928 metadataElement, "name", "label");
929
930 String repeatable = parentElement.attributeValue("repeatable");
931
932 String value = dynamicElementElement.attributeValue("value");
933
934 dynamicElementElement.addAttribute("name", labelElement.getText());
935 dynamicElementElement.addAttribute("repeatable", repeatable);
936 dynamicElementElement.addAttribute("type", value);
937
938 removeAttribute(dynamicElementElement, "value");
939
940 dynamicElementElement.remove(metadataElement);
941
942 return;
943 }
944
945
946
947 String indexType = GetterUtil.getString(
948 dynamicElementElement.attributeValue("indexType"));
949
950 removeAttribute(dynamicElementElement, "indexType");
951
952 dynamicElementElement.addAttribute("index-type", indexType);
953
954
955
956 String type = dynamicElementElement.attributeValue("type");
957
958 boolean multiple = GetterUtil.getBoolean(
959 dynamicElementElement.attributeValue("multiple"));
960
961 String newType = _ddmTypesToJournalTypes.get(type);
962
963 if (newType.equals("list") && multiple) {
964 newType = "multi-list";
965 }
966
967 dynamicElementElement.addAttribute("type", newType);
968
969
970
971 String[] removableAttributeNames = new String[] {
972 "dataType", "fieldNamespace", "multiple", "readOnly", "required",
973 "showLabel", "width"
974 };
975
976 for (String removableAttributeName : removableAttributeNames) {
977 removeAttribute(dynamicElementElement, removableAttributeName);
978 }
979
980 List<Element> childrenDynamicElementElements =
981 dynamicElementElement.elements("dynamic-element");
982
983 for (Element childrenDynamicElementElement :
984 childrenDynamicElementElements) {
985
986 updateDDMXSDDynamicElement(
987 childrenDynamicElementElement, defaultLanguageId);
988 }
989 }
990
991 protected void updateDynamicContentValue(
992 Element dynamicContentElement, String fieldType, boolean multiple,
993 String fieldValue)
994 throws Exception {
995
996 if (DDMImpl.TYPE_CHECKBOX.equals(fieldType)) {
997 if (fieldValue.equals(Boolean.FALSE.toString())) {
998 fieldValue = StringPool.BLANK;
999 }
1000
1001 dynamicContentElement.addCDATA(fieldValue);
1002 }
1003 else if (DDMImpl.TYPE_DDM_DOCUMENTLIBRARY.equals(fieldType) &&
1004 Validator.isNotNull(fieldValue)) {
1005
1006 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
1007 fieldValue);
1008
1009 String uuid = jsonObject.getString("uuid");
1010 long groupId = jsonObject.getLong("groupId");
1011
1012 FileEntry fileEntry =
1013 DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
1014 uuid, groupId);
1015
1016 fieldValue = DLUtil.getPreviewURL(
1017 fileEntry, fileEntry.getFileVersion(), null, StringPool.BLANK,
1018 false, true);
1019
1020 dynamicContentElement.addCDATA(fieldValue);
1021 }
1022 else if (DDMImpl.TYPE_DDM_IMAGE.equals(fieldType) &&
1023 Validator.isNotNull(fieldValue)) {
1024
1025 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
1026 fieldValue);
1027
1028 dynamicContentElement.addAttribute(
1029 "alt", jsonObject.getString("alt"));
1030 dynamicContentElement.addCDATA(jsonObject.getString("data"));
1031 }
1032 else if (DDMImpl.TYPE_DDM_LINK_TO_PAGE.equals(fieldType) &&
1033 Validator.isNotNull(fieldValue)) {
1034
1035 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
1036 fieldValue);
1037
1038 long groupId = jsonObject.getLong("groupId");
1039
1040 String layoutId = jsonObject.getString("layoutId");
1041
1042 boolean privateLayout = jsonObject.getBoolean("privateLayout");
1043
1044 StringBundler sb = new StringBundler((groupId > 0) ? 5 : 3);
1045
1046 sb.append(layoutId);
1047 sb.append(StringPool.AT);
1048
1049 if (privateLayout) {
1050 Group group = GroupLocalServiceUtil.fetchGroup(groupId);
1051
1052 if (group == null) {
1053 sb.append("private");
1054 }
1055 else if (group.isUser()) {
1056 sb.append("private-user");
1057 }
1058 else {
1059 sb.append("private-group");
1060 }
1061 }
1062 else {
1063 sb.append("public");
1064 }
1065
1066 if (groupId > 0) {
1067 sb.append(StringPool.AT);
1068 sb.append(groupId);
1069 }
1070
1071 dynamicContentElement.addCDATA(sb.toString());
1072 }
1073 else if (DDMImpl.TYPE_SELECT.equals(fieldType) &&
1074 Validator.isNotNull(fieldValue)) {
1075
1076 JSONArray jsonArray = JSONFactoryUtil.createJSONArray(fieldValue);
1077
1078 if (multiple) {
1079 for (int i = 0; i < jsonArray.length(); i++) {
1080 Element optionElement = dynamicContentElement.addElement(
1081 "option");
1082
1083 optionElement.addCDATA(jsonArray.getString(i));
1084 }
1085 }
1086 else {
1087 dynamicContentElement.addCDATA(jsonArray.getString(0));
1088 }
1089 }
1090 else {
1091 dynamicContentElement.addCDATA(fieldValue);
1092 }
1093 }
1094
1095 protected void updateElement(Element element) {
1096 List<Element> dynamicElementElements = element.elements(
1097 "dynamic-element");
1098
1099 for (Element dynamicElementElement : dynamicElementElements) {
1100 updateElement(dynamicElementElement);
1101 }
1102
1103 String instanceId = element.attributeValue("instance-id");
1104
1105 if (Validator.isNull(instanceId)) {
1106 element.addAttribute("instance-id", StringUtil.randomString(4));
1107 }
1108 }
1109
1110 protected void updateFieldsDisplay(
1111 Fields ddmFields, String fieldName, String index, String instanceId) {
1112
1113 if (Validator.isNull(instanceId)) {
1114 instanceId = fieldName.concat(GetterUtil.getString(index));
1115 }
1116
1117 String fieldsDisplayValue = fieldName.concat(
1118 DDMImpl.INSTANCE_SEPARATOR).concat(instanceId);
1119
1120 Field fieldsDisplayField = ddmFields.get(DDMImpl.FIELDS_DISPLAY_NAME);
1121
1122 String[] fieldsDisplayValues = DDMUtil.splitFieldsDisplayValue(
1123 fieldsDisplayField);
1124
1125 fieldsDisplayValues = ArrayUtil.append(
1126 fieldsDisplayValues, fieldsDisplayValue);
1127
1128 fieldsDisplayField.setValue(StringUtil.merge(fieldsDisplayValues));
1129 }
1130
1131 protected void updateJournalXSDDynamicElement(Element element) {
1132 Locale defaultLocale = LocaleUtil.getSiteDefault();
1133
1134 updateJournalXSDDynamicElement(
1135 element, LocaleUtil.toLanguageId(defaultLocale));
1136 }
1137
1138 private static Log _log = LogFactoryUtil.getLog(JournalConverterImpl.class);
1139
1140 private static Map<String, String> _ddmDataTypes;
1141 private static Map<String, String> _ddmMetadataAttributes;
1142 private static Map<String, String> _journalTypesToDDMTypes;
1143
1144 private Map<String, String> _ddmTypesToJournalTypes;
1145 private final Pattern _oldDocumentLibraryURLPattern = Pattern.compile(
1146 "uuid=([^&]+)&groupId=([^&]+)");
1147
1148 }