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