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