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.dynamicdatamapping.util;
016    
017    import com.liferay.portal.kernel.util.LocaleUtil;
018    import com.liferay.portal.kernel.util.StringBundler;
019    import com.liferay.portal.kernel.util.StringPool;
020    import com.liferay.portal.kernel.util.StringUtil;
021    import com.liferay.portal.kernel.xml.Attribute;
022    import com.liferay.portal.kernel.xml.Document;
023    import com.liferay.portal.kernel.xml.DocumentException;
024    import com.liferay.portal.kernel.xml.Element;
025    import com.liferay.portal.kernel.xml.SAXReaderUtil;
026    import com.liferay.util.xml.XMLFormatter;
027    
028    import java.io.IOException;
029    
030    import java.util.Locale;
031    
032    /**
033     * @author Bruno Basto
034     * @author Brian Wing Shun Chan
035     */
036    public class DDMXMLImpl implements DDMXML {
037    
038            @Override
039            public String formatXML(Document document) throws IOException {
040                    return document.formattedString(_XML_INDENT);
041            }
042    
043            @Override
044            public String formatXML(String xml) throws DocumentException, IOException {
045    
046                    // This is only supposed to format your xml, however, it will also
047                    // unwantingly change © and other characters like it into their
048                    // respective readable versions
049    
050                    xml = StringUtil.replace(xml, "&#", "[$SPECIAL_CHARACTER$]");
051    
052                    try {
053                            xml = XMLFormatter.toString(xml, _XML_INDENT);
054                    }
055                    catch (org.dom4j.DocumentException de) {
056                            throw new DocumentException(de.getMessage());
057                    }
058    
059                    xml = StringUtil.replace(xml, "[$SPECIAL_CHARACTER$]", "&#");
060    
061                    return xml;
062            }
063    
064            @Override
065            public String updateXMLDefaultLocale(
066                            String xml, Locale contentDefaultLocale,
067                            Locale contentNewDefaultLocale)
068                    throws DocumentException, IOException {
069    
070                    if (LocaleUtil.equals(contentDefaultLocale, contentNewDefaultLocale)) {
071                            return xml;
072                    }
073    
074                    Document document = SAXReaderUtil.read(xml);
075    
076                    Element rootElement = document.getRootElement();
077    
078                    Attribute availableLocalesAttribute = rootElement.attribute(
079                            _AVAILABLE_LOCALES);
080    
081                    String contentNewDefaultLanguageId = LocaleUtil.toLanguageId(
082                            contentNewDefaultLocale);
083    
084                    String availableLocalesAttributeValue =
085                            availableLocalesAttribute.getValue();
086    
087                    if (!availableLocalesAttributeValue.contains(
088                                    contentNewDefaultLanguageId)) {
089    
090                            StringBundler sb = new StringBundler(3);
091    
092                            sb.append(availableLocalesAttribute.getValue());
093                            sb.append(StringPool.COMMA);
094                            sb.append(contentNewDefaultLanguageId);
095    
096                            availableLocalesAttribute.setValue(sb.toString());
097                    }
098    
099                    Attribute defaultLocaleAttribute = rootElement.attribute(
100                            _DEFAULT_LOCALE);
101    
102                    defaultLocaleAttribute.setValue(contentNewDefaultLanguageId);
103    
104                    fixElementsDefaultLocale(
105                            rootElement, contentDefaultLocale, contentNewDefaultLocale);
106    
107                    return document.formattedString();
108            }
109    
110            protected void fixElementsDefaultLocale(
111                    Element element, Locale contentDefaultLocale,
112                    Locale contentNewDefaultLocale) {
113    
114                    for (Element dynamicElementElement :
115                                    element.elements(_DYNAMIC_ELEMENT)) {
116    
117                            Element importMetaDataElement =
118                                    (Element)dynamicElementElement.selectSingleNode(
119                                            "meta-data[@locale='" + contentNewDefaultLocale.toString() +
120                                                    "']");
121    
122                            if (importMetaDataElement == null) {
123                                    Element metaDataElement =
124                                            (Element)dynamicElementElement.selectSingleNode(
125                                                    "meta-data[@locale='" +
126                                                            contentDefaultLocale.toString() + "']");
127    
128                                    Element copiedMetadataElement = metaDataElement.createCopy();
129    
130                                    Attribute localeAttribute = copiedMetadataElement.attribute(
131                                            _LOCALE);
132    
133                                    String contentNewDefaultLanguageId = LocaleUtil.toLanguageId(
134                                            contentNewDefaultLocale);
135    
136                                    localeAttribute.setValue(contentNewDefaultLanguageId);
137    
138                                    dynamicElementElement.add(copiedMetadataElement);
139                            }
140    
141                            fixElementsDefaultLocale(
142                                    dynamicElementElement, contentDefaultLocale,
143                                    contentNewDefaultLocale);
144                    }
145            }
146    
147            private static final String _AVAILABLE_LOCALES = "available-locales";
148    
149            private static final String _DEFAULT_LOCALE = "default-locale";
150    
151            private static final String _DYNAMIC_ELEMENT = "dynamic-element";
152    
153            private static final String _LOCALE = "locale";
154    
155            private static final String _XML_INDENT = "  ";
156    
157    }