001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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                    dynamicElementElement.addAttribute(
508                            "type", _ddmTypesToJournalTypes.get(fieldType));
509                    dynamicElementElement.addAttribute("index-type", indexType);
510    
511                    for (Locale locale : ddmField.getAvailableLocales()) {
512                            Element dynamicContentElement = dynamicElementElement.addElement(
513                                    "dynamic-content");
514    
515                            dynamicContentElement.addAttribute(
516                                    "language-id", LocaleUtil.toLanguageId(locale));
517    
518                            int count = ddmFieldsCounter.get(fieldName);
519    
520                            Serializable fieldValue = ddmField.getValue(locale, count);
521    
522                            if (fieldValue instanceof Date) {
523                                    Date valueDate = (Date)fieldValue;
524    
525                                    fieldValue = valueDate.getTime();
526                            }
527    
528                            String valueString = String.valueOf(fieldValue);
529    
530                            updateDynamicContentValue(
531                                    dynamicContentElement, fieldType, valueString.trim());
532                    }
533    
534                    ddmFieldsCounter.incrementKey(fieldName);
535            }
536    
537            protected void updateContentDynamicElement(
538                            Element dynamicElementElement, DDMStructure ddmStructure,
539                            Fields ddmFields, DDMFieldsCounter ddmFieldsCounter)
540                    throws Exception {
541    
542                    String fieldName = dynamicElementElement.attributeValue("name");
543    
544                    for (String childFieldName :
545                                    ddmStructure.getChildrenFieldNames(fieldName)) {
546    
547                            int count = ddmFieldsCounter.get(fieldName);
548    
549                            int repetitions = countFieldRepetition(
550                                    ddmFields, childFieldName, fieldName, count);
551    
552                            for (int i = 0; i < repetitions; i++) {
553                                    Element childDynamicElementElement =
554                                            dynamicElementElement.addElement("dynamic-element");
555    
556                                    childDynamicElementElement.addAttribute("name", childFieldName);
557                                    childDynamicElementElement.addAttribute(
558                                            "index", String.valueOf(i));
559    
560                                    updateContentDynamicElement(
561                                            childDynamicElementElement, ddmStructure, ddmFields,
562                                            ddmFieldsCounter);
563                            }
564                    }
565    
566                    updateContentDynamicElement(
567                            dynamicElementElement, ddmStructure, ddmFields.get(fieldName),
568                            ddmFieldsCounter);
569            }
570    
571            protected void updateDDMXSDDynamicElement(
572                    Element dynamicElementElement, String defaultLocale) {
573    
574                    // Metadata
575    
576                    List<Element> metadataElements = dynamicElementElement.elements(
577                            "meta-data");
578    
579                    for (Element metadataElement : metadataElements) {
580                            String locale = metadataElement.attributeValue("locale");
581    
582                            if (locale.equals(defaultLocale)) {
583                                    getJournalMetadataElement(metadataElement);
584                            }
585                            else {
586                                    dynamicElementElement.remove(metadataElement);
587                            }
588                    }
589    
590                    Element parentElement = dynamicElementElement.getParent();
591    
592                    String parentType = parentElement.attributeValue("type");
593    
594                    if (Validator.equals(parentType, "list") ||
595                            Validator.equals(parentType, "multi-list")) {
596    
597                            String repeatable = parentElement.attributeValue("repeatable");
598    
599                            String value = dynamicElementElement.attributeValue("value");
600    
601                            dynamicElementElement.addAttribute("name", value);
602                            dynamicElementElement.addAttribute("repeatable", repeatable);
603                            dynamicElementElement.addAttribute("type", "value");
604    
605                            removeAttribute(dynamicElementElement, "value");
606    
607                            for (Element metadataElement :
608                                            dynamicElementElement.elements("meta-data")) {
609    
610                                    dynamicElementElement.remove(metadataElement);
611                            }
612    
613                            return;
614                    }
615    
616                    // Index type
617    
618                    String indexType = GetterUtil.getString(
619                            dynamicElementElement.attributeValue("indexType"));
620    
621                    removeAttribute(dynamicElementElement, "indexType");
622    
623                    dynamicElementElement.addAttribute("index-type", indexType);
624    
625                    // Type
626    
627                    String type = dynamicElementElement.attributeValue("type");
628    
629                    boolean multiple = GetterUtil.getBoolean(
630                            dynamicElementElement.attributeValue("multiple"));
631    
632                    String newType = _ddmTypesToJournalTypes.get(type);
633    
634                    if (newType.equals("list") && multiple) {
635                            newType = "multi-list";
636                    }
637    
638                    dynamicElementElement.addAttribute("type", newType);
639    
640                    // Removable attributes
641    
642                    String[] removableAttributeNames = new String[] {
643                            "dataType", "fieldNamespace", "multiple", "readOnly", "required",
644                            "showLabel", "width"
645                    };
646    
647                    for (String removableAttributeName : removableAttributeNames) {
648                            removeAttribute(dynamicElementElement, removableAttributeName);
649                    }
650    
651                    List<Element> childrenDynamicElementElements =
652                            dynamicElementElement.elements("dynamic-element");
653    
654                    for (Element childrenDynamicElementElement :
655                                    childrenDynamicElementElements) {
656    
657                            updateDDMXSDDynamicElement(
658                                    childrenDynamicElementElement, defaultLocale);
659                    }
660            }
661    
662            protected void updateDynamicContentValue(
663                            Element dynamicContentElement, String fieldType, String fieldValue)
664                    throws Exception {
665    
666                    if (DDMImpl.TYPE_CHECKBOX.equals(fieldType)) {
667                            if (fieldValue.equals(Boolean.FALSE.toString())) {
668                                    fieldValue = StringPool.BLANK;
669                            }
670    
671                            dynamicContentElement.addCDATA(fieldValue);
672                    }
673                    else if (DDMImpl.TYPE_DDM_DOCUMENTLIBRARY.equals(fieldType) &&
674                                     Validator.isNotNull(fieldValue)) {
675    
676                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
677                                    fieldValue);
678    
679                            String uuid = jsonObject.getString("uuid");
680                            long groupId = jsonObject.getLong("groupId");
681    
682                            FileEntry fileEntry =
683                                    DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
684                                            uuid, groupId);
685    
686                            fieldValue = DLUtil.getPreviewURL(
687                                    fileEntry, fileEntry.getFileVersion(), null, StringPool.BLANK,
688                                    false, true);
689    
690                            dynamicContentElement.addCDATA(fieldValue);
691                    }
692                    else if (DDMImpl.TYPE_DDM_LINK_TO_PAGE.equals(fieldType) &&
693                                     Validator.isNotNull(fieldValue)) {
694    
695                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
696                                    fieldValue);
697    
698                            long groupId = jsonObject.getLong("groupId");
699    
700                            String layoutId = jsonObject.getString("layoutId");
701    
702                            boolean privateLayout = jsonObject.getBoolean("privateLayout");
703    
704                            StringBundler sb = new StringBundler((groupId > 0) ? 5 : 3);
705    
706                            sb.append(layoutId);
707                            sb.append(StringPool.AT);
708    
709                            if (privateLayout) {
710                                    sb.append("private");
711                            }
712                            else {
713                                    sb.append("public");
714                            }
715    
716                            if (groupId > 0) {
717                                    sb.append(StringPool.AT);
718                                    sb.append(groupId);
719                            }
720    
721                            dynamicContentElement.addCDATA(sb.toString());
722                    }
723                    else if (DDMImpl.TYPE_SELECT.equals(fieldType) &&
724                                     Validator.isNotNull(fieldValue)) {
725    
726                            JSONArray jsonArray = JSONFactoryUtil.createJSONArray(fieldValue);
727    
728                            if (jsonArray.length() > 1) {
729                                    for (int i = 0; i <jsonArray.length(); i++) {
730                                            Element optionElement = dynamicContentElement.addElement(
731                                                    "option");
732    
733                                            optionElement.addCDATA(jsonArray.getString(i));
734                                    }
735                            }
736                            else {
737                                    dynamicContentElement.addCDATA(jsonArray.getString(0));
738                            }
739                    }
740                    else {
741                            dynamicContentElement.addCDATA(fieldValue);
742                    }
743            }
744    
745            protected void updateFieldsDisplay(Fields ddmFields, String fieldName) {
746                    String fieldsDisplayValue =
747                            fieldName.concat(DDMImpl.INSTANCE_SEPARATOR).concat(
748                                    StringUtil.randomString());
749    
750                    Field fieldsDisplayField = ddmFields.get(DDMImpl.FIELDS_DISPLAY_NAME);
751    
752                    String[] fieldsDisplayValues = StringUtil.split(
753                            (String)fieldsDisplayField.getValue());
754    
755                    fieldsDisplayValues = ArrayUtil.append(
756                            fieldsDisplayValues, fieldsDisplayValue);
757    
758                    fieldsDisplayField.setValue(StringUtil.merge(fieldsDisplayValues));
759            }
760    
761            protected void updateJournalXSDDynamicElement(Element element) {
762                    Locale defaultLocale = LocaleUtil.getSiteDefault();
763    
764                    String name = element.attributeValue("name");
765                    String type = element.attributeValue("type");
766    
767                    Element metadataElement = element.element("meta-data");
768    
769                    if (metadataElement == null) {
770                            metadataElement = element.addElement("meta-data");
771                    }
772    
773                    if (type.equals("multi-list")) {
774                            element.addAttribute("multiple", "true");
775                    }
776                    else if (type.equals("selection_break")) {
777                            Element parentElement = element.getParent();
778    
779                            parentElement.remove(element);
780    
781                            return;
782                    }
783                    else {
784                            Element parentElement = element.getParent();
785    
786                            String parentType = parentElement.attributeValue("type");
787    
788                            if ((parentType != null) && parentType.equals("select")) {
789                                    metadataElement.addAttribute(
790                                            "locale", defaultLocale.toString());
791    
792                                    addMetadataEntry(metadataElement, "label", name);
793    
794                                    element.addAttribute("name", "option" + StringUtil.randomId());
795                                    element.addAttribute("type", "option");
796                                    element.addAttribute("value", name);
797    
798                                    return;
799                            }
800                    }
801    
802                    String indexType = StringPool.BLANK;
803    
804                    Attribute indexTypeAttribute = element.attribute("index-type");
805    
806                    if (indexTypeAttribute != null) {
807                            indexType = indexTypeAttribute.getValue();
808    
809                            element.remove(indexTypeAttribute);
810                    }
811    
812                    element.remove(element.attribute("type"));
813    
814                    element.addAttribute("dataType", _ddmDataTypes.get(type));
815                    element.addAttribute("indexType", indexType);
816    
817                    String required = "false";
818    
819                    Element requiredElement = fetchMetadataEntry(
820                            metadataElement, "name", "required");
821    
822                    if (requiredElement != null) {
823                            required = requiredElement.getText();
824                    }
825    
826                    element.addAttribute("required", required);
827    
828                    element.addAttribute("showLabel", "true");
829    
830                    String newType = _journalTypesToDDMTypes.get(type);
831    
832                    element.addAttribute("type", newType);
833    
834                    if (newType.startsWith("ddm")) {
835                            element.addAttribute("fieldNamespace", "ddm");
836                    }
837    
838                    metadataElement.addAttribute("locale", defaultLocale.toString());
839    
840                    List<Element> entryElements = metadataElement.elements();
841    
842                    if (entryElements.isEmpty()) {
843                            addMetadataEntry(metadataElement, "label", name);
844                    }
845                    else {
846                            for (Element entryElement : entryElements) {
847                                    String oldEntryName = entryElement.attributeValue("name");
848    
849                                    String newEntryName = _ddmMetadataAttributes.get(oldEntryName);
850    
851                                    if (newEntryName == null) {
852                                            metadataElement.remove(entryElement);
853                                    }
854                                    else {
855                                            entryElement.addAttribute("name", newEntryName);
856                                    }
857                            }
858                    }
859    
860                    if (newType.equals("ddm-date") || newType.equals("ddm-decimal") ||
861                            newType.equals("ddm-integer") ||
862                            newType.equals("ddm-link-to-page") ||
863                            newType.equals("ddm-number") || newType.equals("ddm-text-html") ||
864                            newType.equals("text") || newType.equals("textarea")) {
865    
866                            element.addAttribute("width", "25");
867                    }
868                    else if (newType.equals("wcm-image")) {
869                            element.addAttribute("fieldNamespace", "wcm");
870                            element.addAttribute("readOnly", "false");
871                    }
872    
873                    List<Element> dynamicElementElements = element.elements(
874                            "dynamic-element");
875    
876                    for (Element dynamicElementElement : dynamicElementElements) {
877                            updateJournalXSDDynamicElement(dynamicElementElement);
878                    }
879            }
880    
881            private static Log _log = LogFactoryUtil.getLog(JournalConverterImpl.class);
882    
883            private Map<String, String> _ddmDataTypes;
884            private Map<String, String> _ddmMetadataAttributes;
885            private Map<String, String> _ddmTypesToJournalTypes;
886            private Map<String, String> _journalTypesToDDMTypes;
887    
888    }