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

org.jbasics.localize.LocalizedMessageAccessor Maven / Gradle / Ivy

Go to download

jBasics is a collection of useful utility classes for Java. This includes helper for XML, mathematic functions, restful web services helper, pattern oriented programming interfaces and more. Currently Java7 and up is supported. Version 1.0 will required at leaset Java8.

There is a newer version: 2.0.0p3
Show newest version
/*
 * Copyright (c) 2009-2015
 * 	IT-Consulting Stephan Schloepke (http://www.schloepke.de/)
 * 	klemm software consulting Mirko Klemm (http://www.klemm-scs.com/)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.jbasics.localize;

import org.jbasics.arrays.ArrayConstants;

import java.io.Serializable;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Logger;

/**
 * A convenient helper to access a message from a {@link ResourceBundle} and format it with arguments in a single call.
 * 

All methods are fail save. Any exception is suppressed and in worst case the key is returned. Exception raised * trying to load the {@link ResourceBundle} or determine the current {@link ClassLoader} are logged with the finest * level for debugging purpose. It is wise to not use this logging in production systems.

This class is all you * need for localization. It is in most cases not really helpful to implement some sort of localization framework. The * {@link ResourceBundle} of java already offer such a framework by far more useful than most frameworks I have seen in * the past. If you need a special localization like key values in a database it is much better to supply your own * derived Implementation of the resource bundle class than actually creating you own framework.

* * @author Stephan Schloepke * @since 1.0 */ public class LocalizedMessageAccessor { /** * The prefix attached to the class name for creating bundle names. * * @since 1.0 */ public static final String CLASS_NAME_BUNDLE_PREFIX = "Messages"; /** * A {@link ThreadLocal} container holding the current thread locale (defaults to the default locale if not set by * {@link #setCurrentThreadDefaultLocale(Locale)}). * * @since 1.0 */ private static final ThreadLocal CURRENT_THREAD_LOCALE = new ThreadLocal() { @Override protected Locale initialValue() { return Locale.getDefault(); } }; /** * Returns a String identical to the class name of the given instance concatenated with the {@link * #CLASS_NAME_BUNDLE_PREFIX}. If the supplied instance is null only the {@link #CLASS_NAME_BUNDLE_PREFIX} is * returned. The bundle than is searched in the default package. * * @param instance The instance for which to create a bundle name (should not be null) * * @return The {@link String#intern() interned} String for the bundle name of the given class (guaranteed to * be not null) * * @see String#intern() * @since 1.0 */ public static String getMessageBundleName(final Object instance) { return ((instance != null ? instance.getClass().getName() : "") + LocalizedMessageAccessor.CLASS_NAME_BUNDLE_PREFIX).intern(); } /** * Returns a String identical to the given class name concatenated with the {@link #CLASS_NAME_BUNDLE_PREFIX}. If * the supplied class is null only the {@link #CLASS_NAME_BUNDLE_PREFIX} is returned. The bundle than is searched in * the default package. * * @param clazz The class for which to create a bundle name (should not be null) * * @return The interned ({@link String#intern()} String for the bundle name of the given class (guaranteed to * be not null) * * @see String#intern() * @since 1.0 */ public static String getMessageBundleName(final Class clazz) { return ((clazz != null ? clazz.getName() : "") + LocalizedMessageAccessor.CLASS_NAME_BUNDLE_PREFIX).intern(); } /** * Returns the message formatted for the US english {@link Locale} and the given {@link ResourceBundle} name and * key.

This method is particular useful if in a certain case you want to offer a message understood by mostly * all countries and humans. This is often the case if the message is intended to be read by a software developer. * In the localized exceptions it is used for example where the getMessage method always returns an english message * while the getLocalizedMessage returns the message formatted for the default locale.

* * @param bundle The {@link ResourceBundle} name or class name. * @param key The key to look up the message text. * @param arguments The arguments handled to format * * @return The formatted string or the key if any error occurred trying to format the message or lookup the bundle * (guaranteed to be not null) * * @since 1.0 */ public static String getUSEnglishMessage(final String bundle, final String key, final Object... arguments) { return LocalizedMessageAccessor.getLocalizedMessage(Locale.US, bundle, key, arguments); } /** * Returns the formatted String in the given {@link Locale} with the given {@link ResourceBundle} bundle and key. * * @param locale The {@link Locale} to format the message in. If null the current default {@link Locale} is * used. * @param bundle The {@link ResourceBundle} name or class name. * @param key The key to look up the message text. * @param arguments The arguments handled to format * * @return The formatted string or the key if any error occurred trying to format the message or lookup the bundle * (guaranteed to be not null) * * @since 1.0 */ public static String getLocalizedMessage(final Locale locale, final String bundle, final String key, final Object... arguments) { String result = key; if (bundle != null) { try { ResourceBundle b = ResourceBundle.getBundle(bundle, locale == null ? LocalizedMessageAccessor.getCurrentThreadDefaultLocale() : locale, LocalizedMessageAccessor.getContextClassloader()); if (b != null) { result = MessageFormat.format(b.getString(key), arguments); } } catch (RuntimeException e) { Logger.getLogger(LocalizedMessageAccessor.class.getName()).finest( "Cannot find ResourceBundle " + bundle + " due to exception " + e.getMessage()); } } return result; } /** * Get the default {@link Locale} for the current thread (unless set with {@link * #setCurrentThreadDefaultLocale(Locale)} this is always the JVMs default {@link Locale} ).

This is particular * useful in server environments where multiple users with different languages use the same application. The main * problem in such a case is that if for instance you want to throw a {@link LocalizedRuntimeException} to the * client that the client would not see his or hers language but the default language of the server. If the client * is web client that would be the case always. In case of a richt client it would be possible to format the message * on the client with the default locale of the user. However this could lead to the problem that an argument maybe * is not {@link Serializable} and therefor would raise an exception trying to send the bundle name and its * arguments to the client. For this reason the message is created on construction of the exception and uses the * current threads default locale.

* * @return The current threads default {@link Locale} if set with {@link #setCurrentThreadDefaultLocale(Locale)} or * the default locale of the JVM. * * @see #setCurrentThreadDefaultLocale(Locale) * @since 1.0 */ public static Locale getCurrentThreadDefaultLocale() { return LocalizedMessageAccessor.CURRENT_THREAD_LOCALE.get(); } /** * Returns the current context class loader.

The method first tries to get the current context class loader from * the current thread. If that fails or if null is returned the class loader of this class is returned.

Any * exception raised trying to get the class loader of the current thread is suppressed and logged with the finest * level.

* * @return The context class loader or the class loader of this instance (guaranteed to be not null) * * @since 1.0 */ public static ClassLoader getContextClassloader() { ClassLoader loader = null; try { loader = Thread.currentThread().getContextClassLoader(); } catch (Exception e) { Logger.getLogger(LocalizedMessageAccessor.class.getName()).finest( "Could not get the context class loader due to exception " + e.getMessage()); } if (loader == null) { loader = LocalizedMessageAccessor.class.getClassLoader(); } return loader; } /** * Set the default {@link Locale} for the current thread (if null is supplied the JVM default locale is set). * * @param locale The {@link Locale} to set. * * @see #getCurrentThreadDefaultLocale() * @since 1.0 */ public static void setCurrentThreadDefaultLocale(final Locale locale) { LocalizedMessageAccessor.CURRENT_THREAD_LOCALE.set(locale == null ? Locale.getDefault() : locale); } /** * Returns the message formatted for the US english {@link Locale} and the given {@link ResourceBundle} name and * key.

This method is particular useful if in a certain case you want to offer a message understood by mostly * all countries and humans. This is often the case if the message is intended to be read by a software developer. * In the localized exceptions it is used for example where the getMessage method always returns an english message * while the getLocalizedMessage returns the message formatted for the default locale.

* * @param bundle The {@link ResourceBundle} name or class name. * @param key The key to look up the message text. * * @return The formatted string or the key if any error occurred trying to format the message or lookup the bundle * (guaranteed to be not null) * * @since 1.0 */ public static String getUSEnglishMessage(final String bundle, final String key) { return LocalizedMessageAccessor.getLocalizedMessage(Locale.US, bundle, key); } /** * Returns the formatted String in the given {@link Locale} with the given {@link ResourceBundle} bundle and key. * * @param locale The {@link Locale} to format the message in. If null the current default {@link Locale} is used. * @param bundle The {@link ResourceBundle} name or class name. * @param key The key to look up the message text. * * @return The formatted string or the key if any error occurred trying to format the message or lookup the bundle * (guaranteed to be not null) * * @since 1.0 */ public static String getLocalizedMessage(final Locale locale, final String bundle, final String key) { return LocalizedMessageAccessor.getLocalizedMessage(locale, bundle, key, ArrayConstants.ZERO_LENGTH_OBJECT_ARRAY); } /** * Returns the message formatted for the current default {@link Locale} and the given {@link ResourceBundle} name * and key. * * @param bundle The {@link ResourceBundle} name or class name. * @param key The key to look up the message text. * @param arguments The arguments handled to format * * @return The formatted string or the key if any error occurred trying to format the message or lookup the bundle * (guaranteed to be not null) * * @since 1.0 */ public static String getLocalizedMessage(final String bundle, final String key, final Object... arguments) { return LocalizedMessageAccessor.getLocalizedMessage(null, bundle, key, arguments); } /** * Returns the message formatted for the current default {@link Locale} and the given {@link ResourceBundle} name * and key. * * @param bundle The {@link ResourceBundle} name or class name. * @param key The key to look up the message text. * * @return The formatted string or the key if any error occurred trying to format the message or lookup the bundle * (guaranteed to be not null) * * @since 1.0 */ public static String getLocalizedMessage(final String bundle, final String key) { return LocalizedMessageAccessor.getLocalizedMessage(null, bundle, key); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy