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