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

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

The newest version!
/*
 * #%L
 * I18n :: Api
 * %%
 * Copyright (C) 2004 - 2017 Code Lutin, Ultreia.io
 * %%
 * 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 java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Enumeration;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Properties;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.nuiton.i18n.bundle.I18nBundleEntry;

/**
 * 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 Logger log = LogManager.getLogger(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()) { try (BufferedReader fis = Files.newBufferedReader(f.toPath(), StandardCharsets.UTF_8)) { recordProps.load(fis); } } recordProps.put(key, ""); try (FileOutputStream fos = new FileOutputStream(f)) { recordProps.store(fos, "Adding the key : " + key); } } 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 - 2025 Weber Informatics LLC | Privacy Policy