All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.i18n.I18nStore Maven / Gradle / Ivy

There is a newer version: 4.2
Show newest version
/*
 * #%L
 * I18n :: Api
 * 
 * $Id$
 * $HeadURL$
 * %%
 * Copyright (C) 2004 - 2010 CodeLutin
 * %%
 * This program 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 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program 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 General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */

package org.nuiton.i18n;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.i18n.bundle.I18nBundle;
import org.nuiton.i18n.bundle.I18nBundleEntry;
import org.nuiton.i18n.bundle.I18nBundleUtil;
import org.nuiton.i18n.init.I18nInitializer;

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

/**
 * Represents the store of languages of the i18n system.
 *
 * Replace the {@code org.nuiton.i18n.I18nLoader} class from project
 * http://maven-site.nuiton.org/nuiton-utils
 *
 * @author Tony Chemit - [email protected]
 * @since 1.1
 */
public class I18nStore {

    /** Logger. */
    private static final Log log = LogFactory.getLog(I18nStore.class);

    /** le language actuellement utilise */
    protected I18nLanguage language;

    /** le cache de languages deja charges */
    protected Map languages;

    /** le cache de bundles deja charges */
    protected I18nBundle[] bundles;

    /** la locale par defaut a utiliser. */
    protected Locale defaultLocale;

    /** le resolver de bundles */
    protected I18nInitializer resolver;

    /**
     * @param defaultLocale default locale
     * @param resolver      resolver of bundles
     */
    public I18nStore(Locale defaultLocale, I18nInitializer resolver) {
        this.defaultLocale = defaultLocale == null ? Locale.getDefault() : defaultLocale;
        this.resolver = resolver;
    }

    /**
     * Obtain the current language setted in the store.
     *
     * This language is used for all translations without locale information
     * (says the method {@link I18n#t(String, Object...)}).
     *
     * @return the current language or {@code null} if none is defined
     * @since 2.1
     */
    public I18nLanguage getCurrentLanguage() {
        return language;
    }

    /**
     * Obtain the current locale setted in the store.
     *
     * This locale is coming from the current language and is used for all
     * translations without locale information (says the method {@link I18n#t(String, Object...)}.
     *
     * @return the current locale or {@code null} if no current language is setted
     * @since 2.1
     */
    public Locale getCurrentLocale() {
        return language == null ? null : language.getLocale();
    }

    /**
     * Sets the current locale for the store.
     *
     * This will set the current language with this given locale.
     *
     * @param locale the new current locale
     * @since 2.1
     */
    public void setCurrentLocale(Locale locale) {
        Locale currentLocale = getCurrentLocale();
        if (locale.equals(currentLocale)) {

            // nothing to do, alreayd using this locale
            return;
        }

        // set the new current language
        init();

        if (log.isDebugEnabled()) {
            log.debug("locale: " + locale);
        }
        I18nLanguage result = getLanguage(locale);
        language = result;
        //TC-20090702 the selected language is the default locale, usefull for
        // objects dealing with the default locale (swing widgets,...)
        Locale.setDefault(locale);
    }

    /**
     * @return current language loaded or null, if no language was load.
     * @deprecated since 2.1, will be removed in version 3.0, prefer use now
     *             the method {@link #getCurrentLanguage()}.
     */
    @Deprecated
    public I18nLanguage getLanguage() {
        return language;
    }

    /** @return le cache de language actuellement pris en charge. */
    public I18nLanguage[] getLanguages() {
        Collection values = getLanguagesCache().values();
        return values.toArray(new I18nLanguage[values.size()]);
    }

    /** @return the default locale of the store */
    public Locale getDefaultLocale() {
        return defaultLocale;
    }

    public boolean isEmpty() {
        boolean isEmpty = I18nBundleUtil.isEmpty(getBundles());
        return isEmpty;
    }

    /** @return array of all locales loaded */
    public Locale[] getLocales() {
        Locale[] result = I18nBundleUtil.getLocales(getBundles());
        return result;
    }

    public I18nBundle[] getBundles() {
        checkInit();
        return bundles;
    }

    public I18nBundle[] getBundles(Locale l) {
        I18nBundle[] result = I18nBundleUtil.getBundles(l, getBundles());
        return result;
    }

    public I18nBundleEntry[] getBundleEntries() {
        I18nBundleEntry[] result = I18nBundleUtil.getBundleEntries(getBundles());
        return result;
    }

    public I18nBundleEntry[] getBundleEntries(Locale l) {
        I18nBundleEntry[] result =
                I18nBundleUtil.getBundleEntries(l, getDefaultLocale(),
                                                getBundles());
        return result;
    }

    protected void init() {

        if (isInit()) {
            // already init
            return;
        }

        if (resolver == null) {
            throw new NullPointerException(
                    "resolver can not be null in " +
                    "org.nuiton.i18n.I18nStore.init method");
        }

        try {
            bundles = resolver.resolvBundles();
        } catch (Exception e) {
            throw new RuntimeException(
                    "Could not init store for reason " + e.getMessage(), e);
        }

        if (log.isInfoEnabled()) {
            log.info(bundles.length + " bundle(s) found, [" +
                     getBundleEntries().length + " file(s)].");
        }
    }

    /**
     * Set a new language in store, given a locale.
     *
     * @param locale la locale du language requis
     * @deprecated since 2.1, will be removed in version 3.0, use now the
     *             method {@link #setCurrentLocale(Locale)}.
     */
    @Deprecated
    protected void setLanguage(Locale locale) {
        init();
        if (log.isDebugEnabled()) {
            log.debug("locale: " + locale);
        }
        I18nLanguage result = getLanguage(locale);
        language = result;
        //TC-20090702 the selected language is the default locale, usefull for
        // objects dealing with the default locale (swing widgets,...)
        Locale.setDefault(locale);
    }

    /**
     * Close store and release cache ofg language.
     *
     * Current language will be also cleaned.
     */
    protected void close() {
        if (languages != null) {
            if (log.isInfoEnabled()) {
                log.info("will close " + languages.size() + " language(s).");
            }
            for (I18nLanguage l : languages.values()) {
                l.close();
            }
            languages.clear();
            languages = null;
        }
        if (bundles != null) {
            bundles = null;
        }
        language = null;
    }

    /** @return le cache de language avec instanciation paresseuse */
    protected Map getLanguagesCache() {
        if (languages == null) {
            languages = new HashMap();
        }
        return languages;
    }

    /**
     * Recherche un object de type {@link I18nLanguage} pour la locale donnée
     * en paramètre dans le cache des langues chargées ({@link #languages}).
     *
     * Si un tel objet n'existe pas, alors on en crée un et on le place dans le
     * cache.
     *
     * @param locale la locale du language recherche
     * @return le language trouve dans le cache.
     */
    protected I18nLanguage getLanguage(Locale locale) {

        I18nLanguage result = null;

        if (MapUtils.isNotEmpty(languages)) {

            // take the already registred language
            result = languages.get(locale);
        }

        if (result == null) {

            // add a new language for the given locale
            result = addLanguage(locale);

        } else {
            if (log.isDebugEnabled()) {
                log.debug("using cached language : " + result);
            }
        }

        return result;
    }

    protected I18nLanguage addLanguage(Locale locale) {

        if (!isInit()) {

            // always init the store
            init();
        }

        I18nLanguage result;
        result = new I18nLanguage(locale, resolver.isMissingKeyReturnNull());
        I18nBundleEntry[] entries = getBundleEntries(locale);
        result.load(entries, resolver.getEncoding());

        if (log.isInfoEnabled()) {
            log.info(result + ", nbEntries: " + entries.length +
                     ", nbSentences: " + result.size() + ".");
        }
        getLanguagesCache().put(locale, result);
        return result;
    }

    protected boolean isInit() {
        return bundles != null;
    }

    protected void checkInit() {
        if (!isInit()) {
            throw new IllegalStateException(
                    "should call init method on " + I18nStore.class);
        }
    }

    public I18nInitializer getResolver() {
        return resolver;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy