Commits

Anonymous committed 7c3eb9a

Make findText in LocalizedTextUtil not throw NPE if ActionContext.getActionInvocation() returns null, which happens in Sitemesh decorators.

git-svn-id: http://svn.opensymphony.com/svn/xwork/trunk@331e221344d-f017-0410-9bd5-d282ab1896d7

  • Participants
  • Parent commits 38c1310

Comments (0)

Files changed (1)

File src/java/com/opensymphony/xwork/util/LocalizedTextUtil.java

 
 import com.opensymphony.xwork.Action;
 import com.opensymphony.xwork.ActionContext;
+import com.opensymphony.xwork.ActionInvocation;
 import com.opensymphony.xwork.ModelDriven;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+
 import java.text.MessageFormat;
+
 import java.util.*;
 
 
     }
 
     /**
-     * Returns a localized message for the specified key, aTextName.  Neither the key nor the
-     * message is evaluated.
-     *
-     * @param aTextName the message key
-     * @param locale    the locale the message should be for
-     * @return a localized message based on the specified key
-     * @throws MissingResourceException if no message can be found for the specified key
-     */
+ * Returns a localized message for the specified key, aTextName.  Neither the key nor the
+ * message is evaluated.
+ *
+ * @param aTextName the message key
+ * @param locale    the locale the message should be for
+ * @return a localized message based on the specified key
+ * @throws MissingResourceException if no message can be found for the specified key
+ */
     public static String findDefaultText(String aTextName, Locale locale) throws MissingResourceException {
         MissingResourceException e = null;
         List localList = new ArrayList(DEFAULT_RESOURCE_BUNDLES);
     }
 
     /**
-     * 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.
-     *
-     * @param aTextName the message key
-     * @param locale    the locale the message should be for
-     * @param params    an array of objects to be substituted into the message text
-     * @return A formatted message based on the specified key
-     * @throws MissingResourceException if no message can be found for the specified key
-     */
+ * 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.
+ *
+ * @param aTextName the message key
+ * @param locale    the locale the message should be for
+ * @param params    an array of objects to be substituted into the message text
+ * @return A formatted message based on the specified key
+ * @throws MissingResourceException if no message can be found for the specified key
+ */
     public static String findDefaultText(String aTextName, Locale locale, Object[] params) throws MissingResourceException {
         MessageFormat mf = buildMessageFormat(findDefaultText(aTextName, locale), locale);
 
     }
 
     /**
-     * Calls {@link #findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args)}
-     * with aTextName as the default message.
-     *
-     * @see #findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args)
-     */
+ * Calls {@link #findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args)}
+ * with aTextName as the default message.
+ *
+ * @see #findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args)
+ */
     public static String findText(Class aClass, String aTextName, Locale locale) {
         return findText(aClass, aTextName, locale, aTextName, new Object[0]);
     }
 
     /**
-     * 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:
-     * <p />
-     * <ol>
-     * <li>Look for message in aClass' class hierarchy.
-     * <ol>
-     * <li>Look for the message in a resource bundle for aClass</li>
-     * <li>If not found, look for the message in a resource bundle for any implemented interface</li>
-     * <li>If not found, traverse up the Class' hierarchy and repeat from the first sub-step</li>
-     * </ol></li>
-     * <li>If not found and aClass is a {@link ModelDriven} Action, then look for message in
-     * the model's class hierarchy (repeat sub-steps listed above).</li>
-     * <li>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
-     * <i>user.address.state</i>, 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.</li>
-     * <li>If not found, look for the message in aClass' package hierarchy.</li>
-     * <li>If still not found, look for the message in the default resource bundles.</li>
-     * <li>Return defaultMessage</li>
-     * </ol>
-     * <p />
-     * 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[*]).
-     * <p />
-     * If a message is found, it will also be interpolated.  Anything within <code>${...}</code>
-     * will be treated as an OGNL expression and evaluated as such.
-     *
-     * @param aClass         the class whose name to use as the start point for the search
-     * @param aTextName      the key to find the text message for
-     * @param locale         the locale the message should be for
-     * @param defaultMessage the message to be returned if no text message can be found in any
-     *                       resource bundle
-     * @return the localized text, or null if none can be found and no defaultMessage is provided
-     */
+ * 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:
+ * <p />
+ * <ol>
+ * <li>Look for message in aClass' class hierarchy.
+ * <ol>
+ * <li>Look for the message in a resource bundle for aClass</li>
+ * <li>If not found, look for the message in a resource bundle for any implemented interface</li>
+ * <li>If not found, traverse up the Class' hierarchy and repeat from the first sub-step</li>
+ * </ol></li>
+ * <li>If not found and aClass is a {@link ModelDriven} Action, then look for message in
+ * the model's class hierarchy (repeat sub-steps listed above).</li>
+ * <li>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
+ * <i>user.address.state</i>, 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.</li>
+ * <li>If not found, look for the message in aClass' package hierarchy.</li>
+ * <li>If still not found, look for the message in the default resource bundles.</li>
+ * <li>Return defaultMessage</li>
+ * </ol>
+ * <p />
+ * 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[*]).
+ * <p />
+ * If a message is found, it will also be interpolated.  Anything within <code>${...}</code>
+ * will be treated as an OGNL expression and evaluated as such.
+ *
+ * @param aClass         the class whose name to use as the start point for the search
+ * @param aTextName      the key to find the text message for
+ * @param locale         the locale the message should be for
+ * @param defaultMessage the message to be returned if no text message can be found in any
+ *                       resource bundle
+ * @return the localized text, or null if none can be found and no defaultMessage is provided
+ */
     public static String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args) {
         ActionContext context = ActionContext.getContext();
         OgnlValueStack valueStack = context.getValueStack();
 
         if (ModelDriven.class.isAssignableFrom(aClass)) {
             // search up model's class hierarchy
-            Action action = context.getActionInvocation().getAction();
-            msg = findMessage(((ModelDriven) action).getModel().getClass(), aTextName, indexedTextName, locale, args, null, valueStack);
+            ActionInvocation actionInvocation = context.getActionInvocation();
 
-            if (msg != null) {
-                return msg;
+            // ActionInvocation may be null if we're being run from a Sitemesh filter, so we won't get model texts if this is null
+            if (actionInvocation != null) {
+                Action action = actionInvocation.getAction();
+                msg = findMessage(((ModelDriven) action).getModel().getClass(), aTextName, indexedTextName, locale, args, null, valueStack);
+
+                if (msg != null) {
+                    return msg;
+                }
             }
         }
 
         // nothing still? alright, search the package hierarchy now
         for (Class clazz = aClass;
-             (clazz != null) && !clazz.equals(Object.class);
-             clazz = clazz.getSuperclass()) {
+                (clazz != null) && !clazz.equals(Object.class);
+                clazz = clazz.getSuperclass()) {
             if (clazz.getPackage() != null) {
                 String packageName = clazz.getPackage().getName() + ".package";
                 msg = getMessage(packageName, locale, aTextName, valueStack, args);
 
         // see if it's a child property
         int idx = aTextName.indexOf(".");
+
         if (idx != -1) {
             String newKey = null;
             String prop = null;
     }
 
     /**
-     * Finds a localized text message for the given key, aTextName, in the specified resource bundle
-     * with aTextName as the default message.
-     * <p />
-     * If a message is found, it will also be interpolated.  Anything within <code>${...}</code>
-     * will be treated as an OGNL expression and evaluated as such.
-     *
-     * @see #findText(java.util.ResourceBundle, java.lang.String, java.util.Locale, java.lang.String, java.lang.Object[])
-     */
+ * Finds a localized text message for the given key, aTextName, in the specified resource bundle
+ * with aTextName as the default message.
+ * <p />
+ * If a message is found, it will also be interpolated.  Anything within <code>${...}</code>
+ * will be treated as an OGNL expression and evaluated as such.
+ *
+ * @see #findText(java.util.ResourceBundle, java.lang.String, java.util.Locale, java.lang.String, java.lang.Object[])
+ */
     public static String findText(ResourceBundle bundle, String aTextName, Locale locale) {
         return findText(bundle, aTextName, locale, aTextName, new Object[0]);
     }
 
     /**
-     * Finds a localized text message for the given key, aTextName, in the specified resource
-     * bundle.
-     * <p />
-     * If a message is found, it will also be interpolated.  Anything within <code>${...}</code>
-     * will be treated as an OGNL expression and evaluated as such.
-     */
+ * Finds a localized text message for the given key, aTextName, in the specified resource
+ * bundle.
+ * <p />
+ * If a message is found, it will also be interpolated.  Anything within <code>${...}</code>
+ * will be treated as an OGNL expression and evaluated as such.
+ */
     public static String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args) {
         OgnlValueStack valueStack = ActionContext.getContext().getValueStack();
 
     }
 
     /**
-     * Gets the default message.
-     */
+ * Gets the default message.
+ */
     private static String getDefaultMessage(String key, Locale locale, OgnlValueStack valueStack, Object[] args, String defaultMessage) {
         if (key != null) {
             String message = null;
     }
 
     /**
-     * Gets the message from the named resource bundle.
-     */
+ * Gets the message from the named resource bundle.
+ */
     private static String getMessage(String bundleName, Locale locale, String key, OgnlValueStack valueStack, Object[] args) {
         try {
             ResourceBundle bundle = findResourceBundle(bundleName, locale);
     }
 
     /**
-     * Traverse up class hierarchy looking for message.  Looks at class, then implemented interface,
-     * before going up hierarchy.
-     */
+ * Traverse up class hierarchy looking for message.  Looks at class, then implemented interface,
+ * before going up hierarchy.
+ */
     private static String findMessage(Class clazz, String key, String indexedKey, Locale locale, Object[] args, Set checked, OgnlValueStack valueStack) {
         if (checked == null) {
             checked = new TreeSet();