Dirt McCrasse Dirt McCrasse - 10 months ago 43
Java Question

Formatting recursively using Locale in MessageFormat

We're using

MessageFormat
to manage translations in our application. We have a wrapper class (
TranslationWrapper
) containing the translation key and its parameters.

When displaying a translated message, it is formated with this command

String message = new MessageFormat( translationKey, aLocale ).format( parameters );


Where
translationKey
is in a format similar to "message {0} {1}", and parameters is an Object array containing the values for {0} and {1}.

Since any object may used as a parameter, we often use our
TranslationWrapper
as a parameter. This allows us to create localized Strings based on imbricaed translation keys.

For any object passed as a parameter, the
toString()
method is called. The
toString()
method of the
TranslationWrapper
automatically translate using the current user's Locale, but I would sometimes like to use another Locale.

Since I pass this different Locale to the
MessageFormat
in its constructor, I would like to know if there is a way to have a handle on the way the parameters' strings are generated in
MessageFormat
when replacing values like {0}. Instead of calling the
toString()
method on the
TranslationWrapper
, I would like to call something like:

toString(locale);


where locale is the Locale I passed in the constructor.

Answer Source

This is rather ugly solution but you can set current locale into thread local variable to use it inside toString method (if it is set):

private static final ThreadLocal<Locale> threadLocale = new ThreadLocal<Locale>();

...

public String translate(String translationKey, Locale aLocale, Object ...parameters) {

    Locale previousLocale = threadLocale.get();
    try {
        threadLocale.set(aLocale);
        return new MessageFormat( translationKey, aLocale ).format( parameters);
        ...
    } finally {
        threadLocale.set(previousLocale);
    }
}

// somewhere in toString method threadLocale.get() will return you current Locale