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.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.templateparser.BaseTransformerListener;
022    import com.liferay.portal.kernel.util.ArrayUtil;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.LocaleUtil;
025    import com.liferay.portal.kernel.util.StringUtil;
026    import com.liferay.portal.kernel.xml.Document;
027    import com.liferay.portal.kernel.xml.Element;
028    import com.liferay.portal.kernel.xml.SAXReaderUtil;
029    import com.liferay.portal.service.ClassNameLocalServiceUtil;
030    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
031    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
032    import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
033    import com.liferay.portlet.journal.model.JournalArticle;
034    
035    import java.util.List;
036    import java.util.Map;
037    
038    /**
039     * @author Raymond Aug??
040     */
041    public class LocaleTransformerListener extends BaseTransformerListener {
042    
043            @Override
044            public String onScript(
045                    String script, String xml, String languageId,
046                    Map<String, String> tokens) {
047    
048                    if (_log.isDebugEnabled()) {
049                            _log.debug("onScript");
050                    }
051    
052                    return StringUtil.replace(script, "@language_id@", languageId);
053            }
054    
055            @Override
056            public String onXml(
057                    String xml, String languageId, Map<String, String> tokens) {
058    
059                    if (_log.isDebugEnabled()) {
060                            _log.debug("onXml");
061                    }
062    
063                    xml = filterByLocalizability(xml, tokens);
064    
065                    return filterByLanguage(xml, languageId);
066            }
067    
068            protected void filter(
069                            Element dynamicElementElement, DDMStructure ddmStructure,
070                            String name, String defaultLanguageId)
071                    throws PortalException, SystemException {
072    
073                    boolean localizable = GetterUtil.getBoolean(
074                            ddmStructure.getFieldProperty(name, "localizable"), true);
075    
076                    List<Element> dynamicContentElements = dynamicElementElement.elements(
077                            "dynamic-content");
078    
079                    for (Element dynamicContentElement : dynamicContentElements) {
080                            String languageId = dynamicContentElement.attributeValue(
081                                    "language-id", defaultLanguageId);
082    
083                            if (!localizable && !languageId.equals(defaultLanguageId)) {
084                                    dynamicElementElement.remove(dynamicContentElement);
085                            }
086                    }
087            }
088    
089            protected void filterByLanguage(
090                    Element root, String languageId, String defaultLanguageId) {
091    
092                    Element defaultLanguageElement = null;
093    
094                    boolean hasLanguageIdElement = false;
095    
096                    for (Element element : root.elements()) {
097                            String tempLanguageId = element.attributeValue(
098                                    "language-id", languageId);
099    
100                            if (StringUtil.equalsIgnoreCase(tempLanguageId, languageId)) {
101                                    hasLanguageIdElement = true;
102    
103                                    filterByLanguage(element, languageId, defaultLanguageId);
104                            }
105                            else {
106                                    if (StringUtil.equalsIgnoreCase(
107                                                    tempLanguageId, defaultLanguageId)) {
108    
109                                            defaultLanguageElement = element;
110                                    }
111    
112                                    root.remove(element);
113                            }
114                    }
115    
116                    if (!hasLanguageIdElement && (defaultLanguageElement != null)) {
117                            root.add(defaultLanguageElement);
118    
119                            filterByLanguage(
120                                    defaultLanguageElement, languageId, defaultLanguageId);
121                    }
122            }
123    
124            protected String filterByLanguage(String xml, String languageId) {
125                    if (xml == null) {
126                            return xml;
127                    }
128    
129                    try {
130                            Document document = SAXReaderUtil.read(xml);
131    
132                            Element rootElement = document.getRootElement();
133    
134                            String defaultLanguageId = LocaleUtil.toLanguageId(
135                                    LocaleUtil.getSiteDefault());
136    
137                            String[] availableLanguageIds = StringUtil.split(
138                                    rootElement.attributeValue(
139                                            "available-locales", defaultLanguageId));
140    
141                            String articleDefaultLanguageId = rootElement.attributeValue(
142                                    "default-locale", defaultLanguageId);
143    
144                            if (!ArrayUtil.contains(availableLanguageIds, languageId)) {
145                                    filterByLanguage(
146                                            rootElement, articleDefaultLanguageId, defaultLanguageId);
147                            }
148                            else {
149                                    filterByLanguage(rootElement, languageId, defaultLanguageId);
150                            }
151    
152                            xml = DDMXMLUtil.formatXML(document);
153                    }
154                    catch (Exception e) {
155                            _log.error(e);
156                    }
157    
158                    return xml;
159            }
160    
161            protected String filterByLocalizability(
162                    String xml, Map<String, String> tokens) {
163    
164                    if ((xml == null) || (tokens == null)) {
165                            return xml;
166                    }
167    
168                    try {
169                            Document document = SAXReaderUtil.read(xml);
170    
171                            long groupId = GetterUtil.getLong(tokens.get("article_group_id"));
172                            long classNameId = ClassNameLocalServiceUtil.getClassNameId(
173                                    JournalArticle.class);
174                            String ddmStructureKey = tokens.get("structure_id");
175    
176                            DDMStructure ddmStructure =
177                                    DDMStructureLocalServiceUtil.fetchStructure(
178                                            groupId, classNameId, ddmStructureKey, true);
179    
180                            if (ddmStructure == null) {
181                                    if (_log.isWarnEnabled()) {
182                                            _log.warn(
183                                                    "Not checking localization because dynamic data " +
184                                                            "mapping structure is not available");
185                                    }
186    
187                                    return xml;
188                            }
189    
190                            Element rootElement = document.getRootElement();
191    
192                            String defaultLanguageId = LocaleUtil.toLanguageId(
193                                    LocaleUtil.getSiteDefault());
194    
195                            String articleDefaultLanguageId = rootElement.attributeValue(
196                                    "default-locale", defaultLanguageId);
197    
198                            filterByLocalizability(
199                                    rootElement, articleDefaultLanguageId, ddmStructure);
200    
201                            xml = DDMXMLUtil.formatXML(document);
202                    }
203                    catch (Exception e) {
204                            _log.error(e);
205                    }
206    
207                    return xml;
208            }
209    
210            protected void filterByLocalizability(
211                            Element root, String defaultLanguageId, DDMStructure ddmStructure)
212                    throws PortalException, SystemException {
213    
214                    for (Element element : root.elements("dynamic-element")) {
215                            String name = element.attributeValue("name");
216    
217                            if (!ddmStructure.hasField(name)) {
218                                    continue;
219                            }
220    
221                            if (!ddmStructure.isFieldTransient(name)) {
222                                    filter(element, ddmStructure, name, defaultLanguageId);
223                            }
224    
225                            filterByLocalizability(element, defaultLanguageId, ddmStructure);
226                    }
227            }
228    
229            private static Log _log = LogFactoryUtil.getLog(
230                    LocaleTransformerListener.class);
231    
232    }