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