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

org.nuiton.i18n.I18nLanguage 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.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.i18n.bundle.I18nBundleEntry;

import java.awt.datatransfer.StringSelection;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Properties;

/**
 * Represents a language in i18n system with all his translations.
 *
 * To obtain a translation, use the method {@link #translate(String)}
 *
 * @author Tony Chemit - [email protected]
 * @since 1.1
 */
public class I18nLanguage {

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

    /** toutes les traductions pour cette langue */
    protected Properties resource;

    /** la locale de la langue */
    protected final Locale locale;

    /** Indique le chemin du fichier dans lequel ecrire les entrees non trouvees */
    protected String recordFilePath;

    /**
     * Used to know null should be returned when a key is not found.
     *
     * @since 2.4.1
     */
    protected boolean missingKeyReturnNull;

    public I18nLanguage(Locale l) {
        this(l, null);
    }

    public I18nLanguage(Locale l, boolean missingKeyReturnNull) {
        this(l, null, missingKeyReturnNull);
    }

    public I18nLanguage(Locale locale, String recordFilePath) {
        this(locale, recordFilePath, false);
    }

    public I18nLanguage(Locale locale, String recordFilePath, boolean missingKeyReturnNull) {
        this.locale = locale;
        this.recordFilePath = recordFilePath;
        this.missingKeyReturnNull = missingKeyReturnNull;
    }

    /**
     * charge les traductions de la languea partir d'une liste donnee de
     * fichiers de traduction.
     *
     * @param bundleEntries the used bundles entries to load
     * @deprecated since 2.4 use {@link #load(I18nBundleEntry[], Charset)} instead,
     *             charset must be provided to avoid encoding problems
     */
    @Deprecated
    public void load(I18nBundleEntry[] bundleEntries) {
        load(bundleEntries, I18nUtil.DEFAULT_CHARSET);
    }

    /**
     * charge les traductions de la languea partir d'une liste donnee de
     * fichiers de traduction.
     *
     * @param bundleEntries the used bundles entries to load
     * @param encoding      Charset to use for Properties loading
     * @since 2.4
     */
    public void load(I18nBundleEntry[] bundleEntries, Charset encoding) {

        // use a recursive properties
        // inspired from nuiton-utils:org.nuiton.util.RecursiveProperties
        // thanks to Arnaud Thimel
        resource = new Properties() {
            private static final long serialVersionUID = 1L;

            @Override
            public String getProperty(String key) {
                String result = super.getProperty(key);
                if (result == null) {
                    return null;
                }
                //Ex : result="My name is ${myName}."
                int pos = result.indexOf("${", 0);
                //Ex : pos=11
                while (pos != -1) {
                    int posEnd = result.indexOf("}", pos + 1);
                    //Ex : posEnd=19
                    if (posEnd != -1) {
                        String value =
                                getProperty(result.substring(pos + 2, posEnd));
                        // Ex : getProperty("myName");
                        if (value != null) {
                            // Ex : value="Thimel"
                            result = result.substring(0, pos) + value +
                                     result.substring(posEnd + 1);
                            // Ex : result="My name is " + "Thimel" + "."
                            pos = result.indexOf("${", pos + value.length());
                            // Ex : pos=-1
                        } else {
                            // Ex : value=null
                            pos = result.indexOf("${", posEnd + 1);
                            // Ex : pos=-1
                        }
                        // Ex : pos=-1
                    }
                }
                return result;
            }
        };

        // load resources

        try {
            if (log.isInfoEnabled()) {
                log.info("Encoding " + encoding + " will be used to load files");
            }
            for (I18nBundleEntry e : bundleEntries) {
                e.load(resource, encoding);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Translate takes a sentence and returns its translation if found, the very
     * same string otherwise.
     *
     * @param sentence sentence to translate
     * @return translated sentence
     */
    public String translate(String sentence) {
        if (resource == null) {
            recordNotFound(sentence);
            return sentence;
        }
        try {
            String result = resource.getProperty(sentence);
            // Empty String is also considered as missing
            if (result == null || "".equals(result)) {
                recordNotFound(sentence);
                if (missingKeyReturnNull) {
                    result = null;
                } else {
                    result = sentence;
                }
            }
            return result;
        } catch (MissingResourceException eee) {
            if (log.isWarnEnabled()) {
                log.warn("Resource " + sentence + " unavailable", eee);
            }
            return sentence;
        } catch (Exception eee) {
            if (log.isErrorEnabled()) {
                log.error("Unexpected error while translating : ", eee);
            }
            return sentence;
        }
    }

    protected void recordNotFound(String key) {
        if (recordFilePath != null && key != null && !"".equals(key)) {
            File f = new File(recordFilePath);
            Properties recordProps = new Properties();
            try {
                if (f.exists()) {
                    FileInputStream fis = new FileInputStream(f);
                    try {
                        recordProps.load(fis);
                    } finally {
                        fis.close();
                    }
                }
                recordProps.put(key, "");
                FileOutputStream fos = new FileOutputStream(f);
                try {
                    recordProps.store(fos, "Adding the key : " + key);
                } finally {
                    fos.close();
                }
            } catch (FileNotFoundException e) {
                if (log.isErrorEnabled()) {
                    log.error(e);
                }
            } catch (IOException e) {
                if (log.isErrorEnabled()) {
                    log.error(e);
                }
            }
        }
    }

    /**
     * Untranslate takes a translated sentence and returns the original one if
     * found, the very same string otherwise.
     *
     * @param sentence sentence to untranslate
     * @return untranslated sentence
     */
    public String untranslate(String sentence) {
        if (resource == null) {
            return sentence;
        }
        try {
            Enumeration e = resource.propertyNames();
            // Look for the given sentence through all translations
            while (e.hasMoreElements()) {
                String key = (String) e.nextElement();
                String translation = resource.getProperty(key);
                // If found returns the corresponding key
                if (sentence.equals(translation)) {
                    return key;
                }
            }
        } catch (MissingResourceException eee) {
            // Well, this can't happen...
        }
        // No such translated sentence in our resourceBundle
        return sentence;
    }

    public Locale getLocale() {
        return locale;
    }

    public int size() {
        return resource == null ? 0 : resource.size();
    }

    public void close() {
        if (resource != null) {
            if (log.isInfoEnabled()) {
                log.info("closing " + this);
            }
            resource.clear();
            resource = null;
        }
    }

    public boolean hasRecord(String sentence) {
        boolean result = false;
        if (sentence != null) {
            result = resource.containsKey(sentence);
            // Empty String is considered as missing
            String value = resource.getProperty(sentence);
            result &= !"".equals(value);
        }
        return result;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        close();
    }

    @Override
    public boolean equals(Object o) {
        return this == o ||
               o instanceof I18nLanguage &&
               locale.equals(((I18nLanguage) o).locale);
    }

    @Override
    public int hashCode() {
        return locale.hashCode();
    }

    @Override
    public String toString() {
        return "I18nLanguage ';
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy