com.opensymphony.xwork2.util
Class LocalizedTextUtil

java.lang.Object
  extended by com.opensymphony.xwork2.util.LocalizedTextUtil

public class LocalizedTextUtil
extends Object

Provides support for localization in XWork. Resource bundles are searched in the following order:

  1. ActionClass.properties
  2. Interface.properties (every interface and sub-interface)
  3. BaseClass.properties (all the way to Object.properties)
  4. ModelDriven's model (if implements ModelDriven), for the model object repeat from 1
  5. package.properties (of the directory where class is located and every parent directory all the way to the root directory)
  6. search up the i18n message key hierarchy itself
  7. global resource properties

To clarify #5, while traversing the package hierarchy, Struts 2 will look for a file package.properties:

com/
  acme/
    package.properties
    actions/
      package.properties
      FooAction.java
      FooAction.properties

If FooAction.properties does not exist, com/acme/action/package.properties will be searched for, if not found com/acme/package.properties, if not found com/package.properties, etc.

A global resource bundle could be specified programatically, as well as the locale.

Version:
$Date: 2007-11-16 21:10:07 +0100 (Fri, 16 Nov 2007) $ $Id: LocalizedTextUtil.java 1667 2007-11-16 20:10:07Z mrdon $
Author:
Jason Carreira, Mark Woon, Rainer Hermanns, tm_jee

Nested Class Summary
(package private) static class LocalizedTextUtil.GetDefaultMessageReturnArg
           
(package private) static class LocalizedTextUtil.MessageFormatKey
           
 
Field Summary
private static List DEFAULT_RESOURCE_BUNDLES
           
private static Logger LOG
           
private static Map messageFormats
           
private static Map<String,String> misses
           
private static boolean reloadBundles
           
 
Constructor Summary
LocalizedTextUtil()
           
 
Method Summary
static void addDefaultResourceBundle(String resourceBundleName)
          Add's the bundle to the internal list of default bundles.
private static MessageFormat buildMessageFormat(String pattern, Locale locale)
           
static void clearDefaultResourceBundles()
          Clears the internal list of resource bundles.
private static void clearMap(Class cl, Object obj, String name)
           
private static void clearTomcatCache()
           
private static String createMissesKey(String aBundleName, Locale locale)
          Creates a key to used for lookup/storing in the bundle misses cache.
static String findDefaultText(String aTextName, Locale locale)
          Returns a localized message for the specified key, aTextName.
static String findDefaultText(String aTextName, Locale locale, Object[] params)
          Returns a localized message for the specified key, aTextName, substituting variables from the array of params into the message.
private static String findMessage(Class clazz, String key, String indexedKey, Locale locale, Object[] args, Set checked, ValueStack valueStack)
          Traverse up class hierarchy looking for message.
static ResourceBundle findResourceBundle(String aBundleName, Locale locale)
          Finds the given resorce bundle by it's name.
static String findText(Class aClass, String aTextName, Locale locale)
          Calls findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args) with aTextName as the default message.
static String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args)
          Finds a localized text message for the given key, aTextName.
static String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args, ValueStack valueStack)
          Finds a localized text message for the given key, aTextName.
static String findText(ResourceBundle bundle, String aTextName, Locale locale)
          Finds a localized text message for the given key, aTextName, in the specified resource bundle with aTextName as the default message.
static String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args)
          Finds a localized text message for the given key, aTextName, in the specified resource bundle.
static String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args, ValueStack valueStack)
          Finds a localized text message for the given key, aTextName, in the specified resource bundle.
private static LocalizedTextUtil.GetDefaultMessageReturnArg getDefaultMessage(String key, Locale locale, ValueStack valueStack, Object[] args, String defaultMessage)
          Gets the default message.
private static String getMessage(String bundleName, Locale locale, String key, ValueStack valueStack, Object[] args)
          Gets the message from the named resource bundle.
static Locale localeFromString(String localeStr, Locale defaultLocale)
          Builds a Locale from a String of the form en_US_foo into a Locale with language "en", country "US" and variant "foo".
private static void reloadBundles()
           
static void reset()
          Clears all the internal lists.
static void setReloadBundles(boolean reloadBundles)
          Should resorce bundles be reloaded.
private static boolean unableToFindTextForKey(LocalizedTextUtil.GetDefaultMessageReturnArg result)
          Determines if we found the text in the bundles.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFAULT_RESOURCE_BUNDLES

private static List DEFAULT_RESOURCE_BUNDLES

LOG

private static final Logger LOG

reloadBundles

private static boolean reloadBundles

misses

private static final Map<String,String> misses

messageFormats

private static final Map messageFormats
Constructor Detail

LocalizedTextUtil

public LocalizedTextUtil()
Method Detail

clearDefaultResourceBundles

public static void clearDefaultResourceBundles()
Clears the internal list of resource bundles.


setReloadBundles

public static void setReloadBundles(boolean reloadBundles)
Should resorce bundles be reloaded.

Parameters:
reloadBundles - reload bundles?

addDefaultResourceBundle

public static void addDefaultResourceBundle(String resourceBundleName)
Add's the bundle to the internal list of default bundles.

If the bundle already exists in the list it will be readded.

Parameters:
resourceBundleName - the name of the bundle to add.

localeFromString

public static Locale localeFromString(String localeStr,
                                      Locale defaultLocale)
Builds a Locale from a String of the form en_US_foo into a Locale with language "en", country "US" and variant "foo". This will parse the output of Locale.toString().

Parameters:
localeStr - The locale String to parse.
defaultLocale - The locale to use if localeStr is null.
Returns:
requested Locale

findDefaultText

public static String findDefaultText(String aTextName,
                                     Locale locale)
Returns a localized message for the specified key, aTextName. Neither the key nor the message is evaluated.

Parameters:
aTextName - the message key
locale - the locale the message should be for
Returns:
a localized message based on the specified key, or null if no localized message can be found for it

findDefaultText

public static String findDefaultText(String aTextName,
                                     Locale locale,
                                     Object[] params)
Returns a localized message for the specified key, aTextName, substituting variables from the array of params into the message. Neither the key nor the message is evaluated.

Parameters:
aTextName - the message key
locale - the locale the message should be for
params - an array of objects to be substituted into the message text
Returns:
A formatted message based on the specified key, or null if no localized message can be found for it

findResourceBundle

public static ResourceBundle findResourceBundle(String aBundleName,
                                                Locale locale)
Finds the given resorce bundle by it's name.

Will use Thread.currentThread().getContextClassLoader() as the classloader.

Parameters:
aBundleName - the name of the bundle (usually it's FQN classname).
locale - the locale.
Returns:
the bundle, null if not found.

createMissesKey

private static String createMissesKey(String aBundleName,
                                      Locale locale)
Creates a key to used for lookup/storing in the bundle misses cache.

Parameters:
aBundleName - the name of the bundle (usually it's FQN classname).
locale - the locale.
Returns:
the key to use for lookup/storing in the bundle misses cache.

findText

public static String findText(Class aClass,
                              String aTextName,
                              Locale locale)
Calls findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args) with aTextName as the default message.

See Also:
findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args)

findText

public static String findText(Class aClass,
                              String aTextName,
                              Locale locale,
                              String defaultMessage,
                              Object[] args)
Finds a localized text message for the given key, aTextName. Both the key and the message itself is evaluated as required. The following algorithm is used to find the requested message:

  1. Look for message in aClass' class hierarchy.
    1. Look for the message in a resource bundle for aClass
    2. If not found, look for the message in a resource bundle for any implemented interface
    3. If not found, traverse up the Class' hierarchy and repeat from the first sub-step
  2. If not found and aClass is a ModelDriven Action, then look for message in the model's class hierarchy (repeat sub-steps listed above).
  3. If not found, look for message in child property. This is determined by evaluating the message key as an OGNL expression. For example, if the key is user.address.state, then it will attempt to see if "user" can be resolved into an object. If so, repeat the entire process fromthe beginning with the object's class as aClass and "address.state" as the message key.
  4. If not found, look for the message in aClass' package hierarchy.
  5. If still not found, look for the message in the default resource bundles.
  6. Return defaultMessage

When looking for the message, if the key indexes a collection (e.g. user.phone[0]) and a message for that specific key cannot be found, the general form will also be looked up (i.e. user.phone[*]).

If a message is found, it will also be interpolated. Anything within ${...} will be treated as an OGNL expression and evaluated as such.

Parameters:
aClass - the class whose name to use as the start point for the search
aTextName - the key to find the text message for
locale - the locale the message should be for
defaultMessage - the message to be returned if no text message can be found in any resource bundle
Returns:
the localized text, or null if none can be found and no defaultMessage is provided

findText

public static String findText(Class aClass,
                              String aTextName,
                              Locale locale,
                              String defaultMessage,
                              Object[] args,
                              ValueStack valueStack)
Finds a localized text message for the given key, aTextName. Both the key and the message itself is evaluated as required. The following algorithm is used to find the requested message:

  1. Look for message in aClass' class hierarchy.
    1. Look for the message in a resource bundle for aClass
    2. If not found, look for the message in a resource bundle for any implemented interface
    3. If not found, traverse up the Class' hierarchy and repeat from the first sub-step
  2. If not found and aClass is a ModelDriven Action, then look for message in the model's class hierarchy (repeat sub-steps listed above).
  3. If not found, look for message in child property. This is determined by evaluating the message key as an OGNL expression. For example, if the key is user.address.state, then it will attempt to see if "user" can be resolved into an object. If so, repeat the entire process fromthe beginning with the object's class as aClass and "address.state" as the message key.
  4. If not found, look for the message in aClass' package hierarchy.
  5. If still not found, look for the message in the default resource bundles.
  6. Return defaultMessage

When looking for the message, if the key indexes a collection (e.g. user.phone[0]) and a message for that specific key cannot be found, the general form will also be looked up (i.e. user.phone[*]).

If a message is found, it will also be interpolated. Anything within ${...} will be treated as an OGNL expression and evaluated as such.

If a message is not found a WARN log will be logged.

Parameters:
aClass - the class whose name to use as the start point for the search
aTextName - the key to find the text message for
locale - the locale the message should be for
defaultMessage - the message to be returned if no text message can be found in any resource bundle
valueStack - the value stack to use to evaluate expressions instead of the one in the ActionContext ThreadLocal
Returns:
the localized text, or null if none can be found and no defaultMessage is provided

unableToFindTextForKey

private static boolean unableToFindTextForKey(LocalizedTextUtil.GetDefaultMessageReturnArg result)
Determines if we found the text in the bundles.

Parameters:
result - the result so far
Returns:
true if we could not find the text, false if the text was found (=success).

findText

public static String findText(ResourceBundle bundle,
                              String aTextName,
                              Locale locale)
Finds a localized text message for the given key, aTextName, in the specified resource bundle with aTextName as the default message.

If a message is found, it will also be interpolated. Anything within ${...} will be treated as an OGNL expression and evaluated as such.

See Also:
findText(java.util.ResourceBundle, String, java.util.Locale, String, Object[])

findText

public static String findText(ResourceBundle bundle,
                              String aTextName,
                              Locale locale,
                              String defaultMessage,
                              Object[] args)
Finds a localized text message for the given key, aTextName, in the specified resource bundle.

If a message is found, it will also be interpolated. Anything within ${...} will be treated as an OGNL expression and evaluated as such.

If a message is not found a WARN log will be logged.

Parameters:
bundle - the bundle
aTextName - the key
locale - the locale
defaultMessage - the default message to use if no message was found in the bundle
args - arguments for the message formatter.

findText

public static String findText(ResourceBundle bundle,
                              String aTextName,
                              Locale locale,
                              String defaultMessage,
                              Object[] args,
                              ValueStack valueStack)
Finds a localized text message for the given key, aTextName, in the specified resource bundle.

If a message is found, it will also be interpolated. Anything within ${...} will be treated as an OGNL expression and evaluated as such.

If a message is not found a WARN log will be logged.

Parameters:
bundle - the bundle
aTextName - the key
locale - the locale
defaultMessage - the default message to use if no message was found in the bundle
args - arguments for the message formatter.
valueStack - the OGNL value stack.

getDefaultMessage

private static LocalizedTextUtil.GetDefaultMessageReturnArg getDefaultMessage(String key,
                                                                              Locale locale,
                                                                              ValueStack valueStack,
                                                                              Object[] args,
                                                                              String defaultMessage)
Gets the default message.


getMessage

private static String getMessage(String bundleName,
                                 Locale locale,
                                 String key,
                                 ValueStack valueStack,
                                 Object[] args)
Gets the message from the named resource bundle.


buildMessageFormat

private static MessageFormat buildMessageFormat(String pattern,
                                                Locale locale)

findMessage

private static String findMessage(Class clazz,
                                  String key,
                                  String indexedKey,
                                  Locale locale,
                                  Object[] args,
                                  Set checked,
                                  ValueStack valueStack)
Traverse up class hierarchy looking for message. Looks at class, then implemented interface, before going up hierarchy.


reloadBundles

private static void reloadBundles()

clearTomcatCache

private static void clearTomcatCache()

clearMap

private static void clearMap(Class cl,
                             Object obj,
                             String name)
                      throws NoSuchFieldException,
                             IllegalAccessException,
                             NoSuchMethodException,
                             InvocationTargetException
Throws:
NoSuchFieldException
IllegalAccessException
NoSuchMethodException
InvocationTargetException

reset

public static void reset()
Clears all the internal lists.



Copyright © 2000-2008 Apache Software Foundation. All Rights Reserved.