com.liferay.portal.util.LocalizationImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.portal.util.LocalizationImpl.java

Source

/**
 * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package com.liferay.portal.util;

import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.language.LanguageUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.Localization;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
import com.liferay.portal.kernel.util.PrefsParamUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Tuple;
import com.liferay.portal.kernel.util.Validator;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

import org.apache.commons.collections.map.ReferenceMap;

/**
 * @author Alexander Chow
 * @author Jorge Ferrer
 * @author Mauro Mariuzzo
 * @author Julio Camarero
 * @author Brian Wing Shun Chan
 * @author Connor McKay
 */
public class LocalizationImpl implements Localization {

    public Object deserialize(JSONObject jsonObject) {
        Locale[] locales = LanguageUtil.getAvailableLocales();

        Map<Locale, String> map = new HashMap<Locale, String>();

        for (Locale locale : locales) {
            String languageId = LocaleUtil.toLanguageId(locale);

            String value = jsonObject.getString(languageId);

            if (Validator.isNotNull(value)) {
                map.put(locale, value);
            }
        }

        return map;
    }

    public String[] getAvailableLocales(String xml) {
        String attributeValue = _getRootAttribute(xml, _AVAILABLE_LOCALES, StringPool.BLANK);

        return StringUtil.split(attributeValue);
    }

    public String getDefaultLocale(String xml) {
        String defaultLanguageId = LocaleUtil.toLanguageId(LocaleUtil.getDefault());

        return _getRootAttribute(xml, _DEFAULT_LOCALE, defaultLanguageId);
    }

    public String getLocalization(String xml, String requestedLanguageId) {
        return getLocalization(xml, requestedLanguageId, true);
    }

    public String getLocalization(String xml, String requestedLanguageId, boolean useDefault) {

        String value = _getCachedValue(xml, requestedLanguageId, useDefault);

        if (value != null) {
            return value;
        } else {
            value = StringPool.BLANK;
        }

        String systemDefaultLanguageId = LocaleUtil.toLanguageId(LocaleUtil.getDefault());

        String priorityLanguageId = null;

        Locale requestedLocale = LocaleUtil.fromLanguageId(requestedLanguageId);

        if (useDefault && LanguageUtil.isDuplicateLanguageCode(requestedLocale.getLanguage())) {

            Locale priorityLocale = LanguageUtil.getLocale(requestedLocale.getLanguage());

            if (!requestedLanguageId.equals(priorityLanguageId)) {
                priorityLanguageId = LocaleUtil.toLanguageId(priorityLocale);
            }
        }

        if (!Validator.isXml(xml)) {
            if (useDefault || requestedLanguageId.equals(systemDefaultLanguageId)) {

                value = xml;
            }

            _setCachedValue(xml, requestedLanguageId, useDefault, value);

            return value;
        }

        XMLStreamReader xmlStreamReader = null;

        ClassLoader portalClassLoader = PortalClassLoaderUtil.getClassLoader();

        Thread currentThread = Thread.currentThread();

        ClassLoader contextClassLoader = currentThread.getContextClassLoader();

        try {
            if (contextClassLoader != portalClassLoader) {
                currentThread.setContextClassLoader(portalClassLoader);
            }

            XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();

            xmlStreamReader = xmlInputFactory.createXMLStreamReader(new UnsyncStringReader(xml));

            String defaultLanguageId = StringPool.BLANK;

            // Skip root node

            if (xmlStreamReader.hasNext()) {
                xmlStreamReader.nextTag();

                defaultLanguageId = xmlStreamReader.getAttributeValue(null, _DEFAULT_LOCALE);

                if (Validator.isNull(defaultLanguageId)) {
                    defaultLanguageId = systemDefaultLanguageId;
                }
            }

            // Find specified language and/or default language

            String defaultValue = StringPool.BLANK;
            String priorityValue = StringPool.BLANK;

            while (xmlStreamReader.hasNext()) {
                int event = xmlStreamReader.next();

                if (event == XMLStreamConstants.START_ELEMENT) {
                    String languageId = xmlStreamReader.getAttributeValue(null, _LANGUAGE_ID);

                    if (Validator.isNull(languageId)) {
                        languageId = defaultLanguageId;
                    }

                    if (languageId.equals(defaultLanguageId) || languageId.equals(priorityLanguageId)
                            || languageId.equals(requestedLanguageId)) {

                        String text = xmlStreamReader.getElementText();

                        if (languageId.equals(defaultLanguageId)) {
                            defaultValue = text;
                        }

                        if (languageId.equals(priorityLanguageId)) {
                            priorityValue = text;
                        }

                        if (languageId.equals(requestedLanguageId)) {
                            value = text;
                        }

                        if (Validator.isNotNull(value)) {
                            break;
                        }
                    }
                } else if (event == XMLStreamConstants.END_DOCUMENT) {
                    break;
                }
            }

            if (useDefault && Validator.isNotNull(priorityLanguageId) && Validator.isNull(value)
                    && Validator.isNotNull(priorityValue)) {

                value = priorityValue;
            }

            if (useDefault && Validator.isNull(value)) {
                value = defaultValue;
            }
        } catch (Exception e) {
            if (_log.isWarnEnabled()) {
                _log.warn(e, e);
            }
        } finally {
            if (contextClassLoader != portalClassLoader) {
                currentThread.setContextClassLoader(contextClassLoader);
            }

            if (xmlStreamReader != null) {
                try {
                    xmlStreamReader.close();
                } catch (Exception e) {
                }
            }
        }

        _setCachedValue(xml, requestedLanguageId, useDefault, value);

        return value;
    }

    public Map<Locale, String> getLocalizationMap(PortletPreferences preferences, String parameter) {

        Locale[] locales = LanguageUtil.getAvailableLocales();

        Map<Locale, String> map = new HashMap<Locale, String>();

        for (Locale locale : locales) {
            String languageId = LocaleUtil.toLanguageId(locale);

            String localeParameter = parameter.concat(StringPool.UNDERLINE).concat(languageId);

            map.put(locale, preferences.getValue(localeParameter, StringPool.BLANK));
        }

        return map;
    }

    public Map<Locale, String> getLocalizationMap(PortletRequest portletRequest, String parameter) {

        Locale[] locales = LanguageUtil.getAvailableLocales();

        Map<Locale, String> map = new HashMap<Locale, String>();

        for (Locale locale : locales) {
            String languageId = LocaleUtil.toLanguageId(locale);

            String localeParameter = parameter.concat(StringPool.UNDERLINE).concat(languageId);

            map.put(locale, ParamUtil.getString(portletRequest, localeParameter));
        }

        return map;
    }

    public Map<Locale, String> getLocalizationMap(String xml) {
        Locale[] locales = LanguageUtil.getAvailableLocales();

        Map<Locale, String> map = new HashMap<Locale, String>();

        for (Locale locale : locales) {
            String languageId = LocaleUtil.toLanguageId(locale);

            map.put(locale, getLocalization(xml, languageId, false));
        }

        return map;
    }

    public String getLocalizationXmlFromPreferences(PortletPreferences preferences, PortletRequest portletRequest,
            String parameter) {

        String xml = StringPool.BLANK;

        Locale[] locales = LanguageUtil.getAvailableLocales();
        Locale defaultLocale = LocaleUtil.getDefault();
        String defaultLanguageId = LocaleUtil.toLanguageId(defaultLocale);

        for (Locale locale : locales) {
            String languageId = LocaleUtil.toLanguageId(locale);

            String localParameter = parameter + StringPool.UNDERLINE + languageId;

            String value = PrefsParamUtil.getString(preferences, portletRequest, localParameter);

            if (Validator.isNotNull(value)) {
                xml = updateLocalization(xml, parameter, value, languageId);
            }
        }

        if (Validator.isNull(getLocalization(xml, defaultLanguageId))) {
            String oldValue = PrefsParamUtil.getString(preferences, portletRequest, parameter);

            if (Validator.isNotNull(oldValue)) {
                xml = updateLocalization(xml, parameter, oldValue);
            }
        }

        return xml;
    }

    public Map<Locale, String> getLocalizedParameter(PortletRequest portletRequest, String parameter) {

        return getLocalizationMap(portletRequest, parameter);
    }

    public String getPreferencesKey(String key, String languageId) {
        String defaultLanguageId = LocaleUtil.toLanguageId(LocaleUtil.getDefault());

        if (!languageId.equals(defaultLanguageId)) {
            key += StringPool.UNDERLINE + languageId;
        }

        return key;
    }

    public String getPreferencesValue(PortletPreferences preferences, String key, String languageId) {

        return getPreferencesValue(preferences, key, languageId, true);
    }

    public String getPreferencesValue(PortletPreferences preferences, String key, String languageId,
            boolean useDefault) {

        String localizedKey = getPreferencesKey(key, languageId);

        String value = preferences.getValue(localizedKey, StringPool.BLANK);

        if (useDefault && Validator.isNull(value)) {
            value = preferences.getValue(key, StringPool.BLANK);
        }

        return value;
    }

    public String[] getPreferencesValues(PortletPreferences preferences, String key, String languageId) {

        return getPreferencesValues(preferences, key, languageId, true);
    }

    public String[] getPreferencesValues(PortletPreferences preferences, String key, String languageId,
            boolean useDefault) {

        String localizedKey = getPreferencesKey(key, languageId);

        String[] values = preferences.getValues(localizedKey, new String[0]);

        if (useDefault && Validator.isNull(values)) {
            values = preferences.getValues(key, new String[0]);
        }

        return values;
    }

    public String removeLocalization(String xml, String key, String requestedLanguageId) {

        return removeLocalization(xml, key, requestedLanguageId, false);
    }

    public String removeLocalization(String xml, String key, String requestedLanguageId, boolean cdata) {

        return removeLocalization(xml, key, requestedLanguageId, cdata, true);
    }

    public String removeLocalization(String xml, String key, String requestedLanguageId, boolean cdata,
            boolean localized) {

        if (Validator.isNull(xml)) {
            return StringPool.BLANK;
        }

        xml = _sanitizeXML(xml);

        String systemDefaultLanguageId = LocaleUtil.toLanguageId(LocaleUtil.getDefault());

        XMLStreamReader xmlStreamReader = null;
        XMLStreamWriter xmlStreamWriter = null;

        ClassLoader portalClassLoader = PortalClassLoaderUtil.getClassLoader();

        Thread currentThread = Thread.currentThread();

        ClassLoader contextClassLoader = currentThread.getContextClassLoader();

        try {
            if (contextClassLoader != portalClassLoader) {
                currentThread.setContextClassLoader(portalClassLoader);
            }

            XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();

            xmlStreamReader = xmlInputFactory.createXMLStreamReader(new UnsyncStringReader(xml));

            String availableLocales = StringPool.BLANK;
            String defaultLanguageId = StringPool.BLANK;

            // Read root node

            if (xmlStreamReader.hasNext()) {
                xmlStreamReader.nextTag();

                availableLocales = xmlStreamReader.getAttributeValue(null, _AVAILABLE_LOCALES);
                defaultLanguageId = xmlStreamReader.getAttributeValue(null, _DEFAULT_LOCALE);

                if (Validator.isNull(defaultLanguageId)) {
                    defaultLanguageId = systemDefaultLanguageId;
                }
            }

            if ((availableLocales != null) && (availableLocales.indexOf(requestedLanguageId) != -1)) {

                availableLocales = StringUtil.remove(availableLocales, requestedLanguageId, StringPool.COMMA);

                UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();

                XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();

                xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(unsyncStringWriter);

                xmlStreamWriter.writeStartDocument();
                xmlStreamWriter.writeStartElement(_ROOT);

                if (localized) {
                    xmlStreamWriter.writeAttribute(_AVAILABLE_LOCALES, availableLocales);
                    xmlStreamWriter.writeAttribute(_DEFAULT_LOCALE, defaultLanguageId);
                }

                _copyNonExempt(xmlStreamReader, xmlStreamWriter, requestedLanguageId, defaultLanguageId, cdata);

                xmlStreamWriter.writeEndElement();
                xmlStreamWriter.writeEndDocument();

                xmlStreamWriter.close();
                xmlStreamWriter = null;

                xml = unsyncStringWriter.toString();
            }
        } catch (Exception e) {
            if (_log.isWarnEnabled()) {
                _log.warn(e, e);
            }
        } finally {
            if (contextClassLoader != portalClassLoader) {
                currentThread.setContextClassLoader(contextClassLoader);
            }

            if (xmlStreamReader != null) {
                try {
                    xmlStreamReader.close();
                } catch (Exception e) {
                }
            }

            if (xmlStreamWriter != null) {
                try {
                    xmlStreamWriter.close();
                } catch (Exception e) {
                }
            }
        }

        return xml;
    }

    public void setLocalizedPreferencesValues(PortletRequest portletRequest, PortletPreferences preferences,
            String parameter) throws Exception {

        Map<Locale, String> map = getLocalizationMap(portletRequest, parameter);

        for (Map.Entry<Locale, String> entry : map.entrySet()) {
            String languageId = LocaleUtil.toLanguageId(entry.getKey());
            String value = entry.getValue();

            setPreferencesValue(preferences, parameter, languageId, value);
        }
    }

    public void setPreferencesValue(PortletPreferences preferences, String key, String languageId, String value)
            throws Exception {

        preferences.setValue(getPreferencesKey(key, languageId), value);
    }

    public void setPreferencesValues(PortletPreferences preferences, String key, String languageId, String[] values)
            throws Exception {

        preferences.setValues(getPreferencesKey(key, languageId), values);
    }

    public String updateLocalization(String xml, String key, String value) {
        String defaultLanguageId = LocaleUtil.toLanguageId(LocaleUtil.getDefault());

        return updateLocalization(xml, key, value, defaultLanguageId, defaultLanguageId);
    }

    public String updateLocalization(String xml, String key, String value, String requestedLanguageId) {

        String defaultLanguageId = LocaleUtil.toLanguageId(LocaleUtil.getDefault());

        return updateLocalization(xml, key, value, requestedLanguageId, defaultLanguageId);
    }

    public String updateLocalization(String xml, String key, String value, String requestedLanguageId,
            String defaultLanguageId) {

        return updateLocalization(xml, key, value, requestedLanguageId, defaultLanguageId, false);
    }

    public String updateLocalization(String xml, String key, String value, String requestedLanguageId,
            String defaultLanguageId, boolean cdata) {

        return updateLocalization(xml, key, value, requestedLanguageId, defaultLanguageId, cdata, true);
    }

    public String updateLocalization(String xml, String key, String value, String requestedLanguageId,
            String defaultLanguageId, boolean cdata, boolean localized) {

        xml = _sanitizeXML(xml);

        XMLStreamReader xmlStreamReader = null;
        XMLStreamWriter xmlStreamWriter = null;

        ClassLoader portalClassLoader = PortalClassLoaderUtil.getClassLoader();

        Thread currentThread = Thread.currentThread();

        ClassLoader contextClassLoader = currentThread.getContextClassLoader();

        try {
            if (contextClassLoader != portalClassLoader) {
                currentThread.setContextClassLoader(portalClassLoader);
            }

            XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();

            xmlStreamReader = xmlInputFactory.createXMLStreamReader(new UnsyncStringReader(xml));

            String availableLocales = StringPool.BLANK;

            // Read root node

            if (xmlStreamReader.hasNext()) {
                xmlStreamReader.nextTag();

                availableLocales = xmlStreamReader.getAttributeValue(null, _AVAILABLE_LOCALES);

                if (Validator.isNull(availableLocales)) {
                    availableLocales = defaultLanguageId;
                }

                if (availableLocales.indexOf(requestedLanguageId) == -1) {
                    availableLocales = StringUtil.add(availableLocales, requestedLanguageId, StringPool.COMMA);
                }
            }

            UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();

            XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();

            xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(unsyncStringWriter);

            xmlStreamWriter.writeStartDocument();
            xmlStreamWriter.writeStartElement(_ROOT);

            if (localized) {
                xmlStreamWriter.writeAttribute(_AVAILABLE_LOCALES, availableLocales);
                xmlStreamWriter.writeAttribute(_DEFAULT_LOCALE, defaultLanguageId);
            }

            _copyNonExempt(xmlStreamReader, xmlStreamWriter, requestedLanguageId, defaultLanguageId, cdata);

            xmlStreamWriter.writeStartElement(key);

            if (localized) {
                xmlStreamWriter.writeAttribute(_LANGUAGE_ID, requestedLanguageId);
            }

            if (cdata) {
                xmlStreamWriter.writeCData(value);
            } else {
                xmlStreamWriter.writeCharacters(value);
            }

            xmlStreamWriter.writeEndElement();
            xmlStreamWriter.writeEndElement();
            xmlStreamWriter.writeEndDocument();

            xmlStreamWriter.close();
            xmlStreamWriter = null;

            xml = unsyncStringWriter.toString();
        } catch (Exception e) {
            if (_log.isWarnEnabled()) {
                _log.warn(e, e);
            }
        } finally {
            if (contextClassLoader != portalClassLoader) {
                currentThread.setContextClassLoader(contextClassLoader);
            }

            if (xmlStreamReader != null) {
                try {
                    xmlStreamReader.close();
                } catch (Exception e) {
                }
            }

            if (xmlStreamWriter != null) {
                try {
                    xmlStreamWriter.close();
                } catch (Exception e) {
                }
            }
        }

        return xml;
    }

    private void _copyNonExempt(XMLStreamReader xmlStreamReader, XMLStreamWriter xmlStreamWriter,
            String exemptLanguageId, String defaultLanguageId, boolean cdata) throws XMLStreamException {

        while (xmlStreamReader.hasNext()) {
            int event = xmlStreamReader.next();

            if (event == XMLStreamConstants.START_ELEMENT) {
                String languageId = xmlStreamReader.getAttributeValue(null, _LANGUAGE_ID);

                if (Validator.isNull(languageId)) {
                    languageId = defaultLanguageId;
                }

                if (!languageId.equals(exemptLanguageId)) {
                    xmlStreamWriter.writeStartElement(xmlStreamReader.getLocalName());
                    xmlStreamWriter.writeAttribute(_LANGUAGE_ID, languageId);

                    while (xmlStreamReader.hasNext()) {
                        event = xmlStreamReader.next();

                        if ((event == XMLStreamConstants.CHARACTERS) || (event == XMLStreamConstants.CDATA)) {

                            String text = xmlStreamReader.getText();

                            if (cdata) {
                                xmlStreamWriter.writeCData(text);
                            } else {
                                xmlStreamWriter.writeCharacters(xmlStreamReader.getText());
                            }

                            break;
                        } else if (event == XMLStreamConstants.END_ELEMENT) {
                            break;
                        }
                    }

                    xmlStreamWriter.writeEndElement();
                }
            } else if (event == XMLStreamConstants.END_DOCUMENT) {
                break;
            }
        }
    }

    private String _getCachedValue(String xml, String requestedLanguageId, boolean useDefault) {

        String value = null;

        Map<Tuple, String> valueMap = _cache.get(xml);

        if (valueMap != null) {
            Tuple subkey = new Tuple(useDefault, requestedLanguageId);

            value = valueMap.get(subkey);
        }

        return value;
    }

    private String _getRootAttribute(String xml, String name, String defaultValue) {

        String value = null;

        XMLStreamReader xmlStreamReader = null;

        ClassLoader portalClassLoader = PortalClassLoaderUtil.getClassLoader();

        Thread currentThread = Thread.currentThread();

        ClassLoader contextClassLoader = currentThread.getContextClassLoader();

        try {
            if (contextClassLoader != portalClassLoader) {
                currentThread.setContextClassLoader(portalClassLoader);
            }

            XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();

            xmlStreamReader = xmlInputFactory.createXMLStreamReader(new UnsyncStringReader(xml));

            if (xmlStreamReader.hasNext()) {
                xmlStreamReader.nextTag();

                value = xmlStreamReader.getAttributeValue(null, name);
            }
        } catch (Exception e) {
            if (_log.isWarnEnabled()) {
                _log.warn(e, e);
            }
        } finally {
            if (contextClassLoader != portalClassLoader) {
                currentThread.setContextClassLoader(contextClassLoader);
            }

            if (xmlStreamReader != null) {
                try {
                    xmlStreamReader.close();
                } catch (Exception e) {
                }
            }
        }

        if (Validator.isNull(value)) {
            value = defaultValue;
        }

        return value;
    }

    private String _sanitizeXML(String xml) {
        if (Validator.isNull(xml) || (xml.indexOf("<root") == -1)) {
            xml = _EMPTY_ROOT_NODE;
        }

        return xml;
    }

    private void _setCachedValue(String xml, String requestedLanguageId, boolean useDefault, String value) {

        if (Validator.isNotNull(xml) && !xml.equals(_EMPTY_ROOT_NODE)) {
            synchronized (_cache) {
                Map<Tuple, String> map = _cache.get(xml);

                if (map == null) {
                    map = new HashMap<Tuple, String>();
                }

                Tuple subkey = new Tuple(useDefault, requestedLanguageId);

                map.put(subkey, value);

                _cache.put(xml, map);
            }
        }
    }

    private static final String _AVAILABLE_LOCALES = "available-locales";

    private static final String _DEFAULT_LOCALE = "default-locale";

    private static final String _EMPTY_ROOT_NODE = "<root />";

    private static final String _LANGUAGE_ID = "language-id";

    private static final String _ROOT = "root";

    private static Log _log = LogFactoryUtil.getLog(LocalizationImpl.class);

    private Map<String, Map<Tuple, String>> _cache = new ReferenceMap(ReferenceMap.SOFT, ReferenceMap.HARD);

}