From 77a13ecedf2aef6ebbe242e6fcb57270c853e824 Mon Sep 17 00:00:00 2001 From: Hugo Hirsch Date: Mon, 11 Jan 2016 21:43:18 +0100 Subject: [PATCH] Issue #22: Add LocalizationHelper from fotorenamer * Migrate to Spamprotector/spamschutz --- .../util/LocalizationHelper.java | 143 ++++++++++++++++++ src/main/resources/spamprotector.properties | 61 ++++++++ .../util/LocalizationHelperTest.java | 83 ++++++++++ 3 files changed, 287 insertions(+) create mode 100644 src/main/java/de/aikiit/spamprotector/util/LocalizationHelper.java create mode 100644 src/main/resources/spamprotector.properties create mode 100644 src/test/java/de/aikiit/spamprotector/util/LocalizationHelperTest.java diff --git a/src/main/java/de/aikiit/spamprotector/util/LocalizationHelper.java b/src/main/java/de/aikiit/spamprotector/util/LocalizationHelper.java new file mode 100644 index 000000000..e4957d2f3 --- /dev/null +++ b/src/main/java/de/aikiit/spamprotector/util/LocalizationHelper.java @@ -0,0 +1,143 @@ +/** + * SpamSchutz - simple way to protect your mail adresses from naiive spammers + * Copyright (C) 2011, Aiki IT + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.aikiit.spamprotector.util; + +import com.google.common.base.Strings; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.text.MessageFormat; +import java.util.Locale; +import java.util.ResourceBundle; + +/** + * Helper to deal with localizations and ease the usage of + * resource bundles within spamprotector. + * + * @author hirsch + * @version 23.08.11 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class LocalizationHelper { + + /** + * Logger. + */ + private static final Logger LOG = + LogManager.getLogger(LocalizationHelper.class); + + /** + * ResourceBundle used for this application. + */ + private static final String BASE_NAME = "spamprotector"; + private static final Locale FALLBACK_LOCALE = Locale.GERMANY; + + private static ResourceBundle BUNDLE; + private static Locale LOCALE; + private static MessageFormat FORMAT; + + static { + setLocale(); + } + + /** + * Set locale depending on system properties, in case of errors fallback is Locale.GERMANY. + */ + public static void setLocale() { + String userLanguage = System.getProperty("user.language"); + String userCountry = System.getProperty("user.country"); + + LOG.info(String.format("Your system emits the following l10n-properties: language=%s, country=%s", userLanguage, userCountry)); + + if (Strings.isNullOrEmpty(userLanguage) || Strings.isNullOrEmpty(userCountry)) { + LOCALE = FALLBACK_LOCALE; + LOG.info("Falling back to locale " + LOCALE); + } else { + LOCALE = new Locale(userLanguage, userCountry); + LOG.info("Setting locale to " + LOCALE); + } + + BUNDLE = ResourceBundle.getBundle(BASE_NAME, LOCALE); + FORMAT = new MessageFormat(""); + FORMAT.setLocale(LOCALE); + } + + /** + * @return the currently set Locale of this application. Fallback is Locale.GERMANY. + */ + public static Locale getLocale() { + if (LOCALE == null) { + LOG.warn("Returning fallback Locale for Germany - please make sure you've configured your environment correctly via system properties 'user.country'/'user.language'."); + return FALLBACK_LOCALE; + } + return LOCALE; + } + + /** + * @return the currently set language + */ + public static String getLanguage() { + return getLocale().getLanguage(); + } + + /** + * Helper function to retrieve a given key + * from the underlying resource bundle. + * + * @param key Key to retrieve from the bundle, + * e.g. spamprotector.foo.title + * @return Returns the value from the bundle. + */ + public static String getBundleString(final String key) { + LOG.debug("Retrieving key " + key); + return BUNDLE.getString(key); + // l18n basics: + // http://www.kodejava.org/examples/220.html + // l18n buttons: + // http://www.java2s.com/Code/Java/I18N/Createonebuttoninternationalizedly.htm + // l18n with parameters: + // http://www.java2s.com/Code/Java/I18N/ResourceBundlewithparameterposition.htm + // parameters are a but uneasier than with grails - + // http://download.oracle.com/javase/tutorial/i18n/format/messageFormat.html + // encoding issues / eclipse plugin: + // http://stackoverflow.com/questions/863838/problem-with-java-properties-utf8-encoding-in-eclipse + } + + /** + * Helper function to retrieve a given key + * from the underlying resource bundle while + * applying localization parameters. + * + * @param key Key to retrieve from the bundle, + * e.g. fotorenamer.foo.parameteredtitle. + * @param parameters Object array with all parameters. + * @return Returns the value from the bundle + * with the given parameters applied. + * @see + * I18N-tutorial + */ + public static String getParameterizedBundleString(final String key, final Object... parameters) { + LOG.debug("Applying " + ((parameters == null) ? null : parameters + .length) + " parameters to " + key); + FORMAT.applyPattern(getBundleString(key)); + return FORMAT.format(parameters); + } + +} diff --git a/src/main/resources/spamprotector.properties b/src/main/resources/spamprotector.properties new file mode 100644 index 000000000..45f4e5e01 --- /dev/null +++ b/src/main/resources/spamprotector.properties @@ -0,0 +1,61 @@ +# for testing +fotorenamer.test.param={0} und dann folgt noch die {1} + +# ProgressBar.java +fotorenamer.ui.progress=Fortschritt +fotorenamer.ui.progress.title=Dateien werden umbenannt... + +# ImageDirectorySelector.java +fotorenamer.ui.selector.title=Verzeichnisauswahl +fotorenamer.ui.selector.title.mnemonic=V +fotorenamer.ui.selector.directory=Bitte ein Verzeichnis ausw\u00e4hlen. +fotorenamer.ui.selector.file=Bitte eine Datei ausw\u00e4hlen. +fotorenamer.ui.selector.select=Ausw\u00e4hlen + +# HelpWindow.java +fotorenamer.ui.help.title=Programmhilfe +fotorenamer.ui.help.close=Schlie\u00dfen +fotorenamer.ui.help.close.mnemonic=S +fotorenamer.ui.help.error=Fehler in der Hilfe: {0} ({1}) + +# AbstractImageRenamer.java +fotorenamer.ui.rename.error.title=Fehler beim Umbenennen +fotorenamer.ui.rename.error=W\u00e4hrend der Bearbeitung der Datei\n {0} trat ein Fehler beim Umbennen auf. +fotorenamer.ui.rename.success.title=Erfolg +fotorenamer.ui.rename.success.message=Es wurden {0} Dateien\nim Verzeichnis: {1}\numbenannt. +fotorenamer.ui.rename.success.message.one=Es wurde eine Datei im Verzeichnis: {0}\nerfolgreich umbenannt. +fotorenamer.ui.rename.success.message.none=Im Verzeichnis: {0}\nwurden keine Dateien umbenannt. + +# MainUIWindow.java +fotorenamer.ui.main.version.title=Versionsinfo +fotorenamer.ui.main.title=fotorenamer-DateinamenKonverter {0} +fotorenamer.ui.main.version={0} / SCM-rev: {1} / Build-Timestamp: {2} +fotorenamer.ui.main.progress=in progress +fotorenamer.ui.main.menu.help=Hilfe +fotorenamer.ui.main.menu.help.mnemonic=H +fotorenamer.ui.main.menu.info=Info +fotorenamer.ui.main.menu.info.mnemonic=I +fotorenamer.ui.main.menu.end=Ende +fotorenamer.ui.main.menu.end.mnemonic=E +fotorenamer.ui.main.menu.start=Starten +fotorenamer.ui.main.menu.start.mnemonic=S +fotorenamer.ui.main.menu.revert=R\u00fcckg\u00e4ngig machen +fotorenamer.ui.main.menu.revert.mnemonic=R +fotorenamer.ui.error.nofiles=Im Verzeichnis {0} existieren keine umbenennbaren Dateien - bitte erneut versuchen. +fotorenamer.ui.error.nofiles.title=Keine Dateien vorhanden +fotorenamer.ui.error.invaliddirectory=Das eingegebene Verzeichnis {0} ist ung\u00fcltig - bitte erneut versuchen. +fotorenamer.ui.error.invaliddirectory.title=Ung\u00fcltiges Verzeichnis angegegen +fotorenamer.ui.error.nodirectory=Bitte ein Verzeichnis eingeben und\ndann starten. +fotorenamer.ui.error.nodirectory.title=Kein Verzeichnis angegegen +fotorenamer.ui.about=bildbearbeiter - fotorenamer\n\nVersion: {0}\n\nAutor: P.Ottlinger,\nURL: http://www.aiki-it.de\n (C) 1996-{1} + +# RemoveExifPrefixRenamer.java + +# Test Umlauts +fotorenamer.test.umlauts=\u00df\u00e4\u00fc + +# FIXME: problems with German Umlauts, http://www.utf8-zeichentabelle.de/unicode-utf8-table.pl +# szett = \u00df +# ae = \u00e4 +# ue = \u00fc + diff --git a/src/test/java/de/aikiit/spamprotector/util/LocalizationHelperTest.java b/src/test/java/de/aikiit/spamprotector/util/LocalizationHelperTest.java new file mode 100644 index 000000000..3b1219a54 --- /dev/null +++ b/src/test/java/de/aikiit/spamprotector/util/LocalizationHelperTest.java @@ -0,0 +1,83 @@ +/** + * SpamSchutz - simple way to protect your mail adresses from naiive spammers + * Copyright (C) 2011, Aiki IT + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.aikiit.spamprotector.util; + +import org.junit.Test; + +import java.util.Locale; + +import static de.aikiit.spamprotector.util.LocalizationHelper.*; + +import static org.junit.Assert.assertEquals; + +/** + * Testing resource bundling. + * + * @author hirsch + * @version 23.08.11 + */ +public class LocalizationHelperTest { + + /** + * Retrieve a plain i18n-value. + */ + @Test + public final void checkValueRetrievingFromBundle() { + assertEquals("Fortschritt", getBundleString("fotorenamer.ui.progress")); + } + + /** + * Retrieve a i18n-value with parameters set. + */ + @Test + public final void checkParametrizedValueExtraction() { + assertEquals("Erfolg und dann folgt noch die 7", getParameterizedBundleString("fotorenamer.test.param", + "Erfolg", 7)); + // ignore warning, we want to test what happens here! An empty String or null changes the output. + assertEquals("{0} und dann folgt noch die {1}", getParameterizedBundleString("fotorenamer.test.param", + new Object[]{})); + } + + @Test + public final void fallbackLocale() { + // WHEN: reset system properties + System.setProperty("user.language", ""); + System.setProperty("user.country", ""); + setLocale(); + + assertEquals(Locale.GERMANY, getLocale()); + assertEquals("de", getLanguage()); + } + + @Test + public final void setLocaleViaSystemProperties() { + // WHEN: reset system properties + final String french = "fr"; + System.setProperty("user.language", french); + System.setProperty("user.country", "CA"); + setLocale(); + + assertEquals(Locale.CANADA_FRENCH, getLocale()); + assertEquals(french, getLanguage()); + } + + @Test + public final void umlautEncodingWorksCorrectly() { + assertEquals("ßäü", getBundleString("fotorenamer.test.umlauts")); + } +}