Commits

plightbo  committed bdeceec

XW-200: when searching child properties, don't use a default message.
We do this because we can then tell when no text was found and therefore
we should fall through to the original default message from the first
call to findText()

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

  • Participants
  • Parent commits 2a150ee

Comments (0)

Files changed (2)

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

 import com.opensymphony.xwork.Action;
 import com.opensymphony.xwork.ActionContext;
 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.*;
 
 
      * message is evaluated.
      *
      * @param aTextName the message key
-     * @param locale the locale the message should be for
+     * @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
      */
      * 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
+     * @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
      */
      * 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>
+     * <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
      * 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 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
+     *                       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) {
             }
         }
 
+        // nothing still? alright, search the package hierarchy now
+        for (Class clazz = aClass;
+             (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);
+
+                if (msg != null) {
+                    return msg;
+                }
+
+                if (indexedTextName != null) {
+                    msg = getMessage(packageName, locale, indexedTextName, valueStack, args);
+
+                    if (msg != null) {
+                        return msg;
+                    }
+                }
+            }
+        }
+
         // see if it's a child property
         int idx = aTextName.indexOf(".");
-
         if (idx != -1) {
             String newKey = null;
             String prop = null;
 
                     if (clazz != null) {
                         valueStack.push(obj);
-                        msg = findText(clazz, newKey, locale, defaultMessage, args);
+                        msg = findText(clazz, newKey, locale, null, args);
                         valueStack.pop();
 
                         if (msg != null) {
             }
         }
 
-        // nothing still? alright, search the package hierarchy now
-        for (Class clazz = aClass;
-                (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);
-
-                if (msg != null) {
-                    return msg;
-                }
-
-                if (indexedTextName != null) {
-                    msg = getMessage(packageName, locale, indexedTextName, valueStack, args);
-
-                    if (msg != null) {
-                        return msg;
-                    }
-                }
-            }
-        }
-
         // get default
         if (indexedTextName == null) {
             return getDefaultMessage(aTextName, locale, valueStack, args, defaultMessage);

File src/test/com/opensymphony/xwork/util/LocalizedTextUtilTest.java

 package com.opensymphony.xwork.util;
 
 import com.mockobjects.dynamic.Mock;
-
-import com.opensymphony.xwork.Action;
-import com.opensymphony.xwork.ActionContext;
-import com.opensymphony.xwork.ActionInvocation;
-import com.opensymphony.xwork.ActionProxy;
-import com.opensymphony.xwork.ActionProxyFactory;
-import com.opensymphony.xwork.ModelDriven;
-import com.opensymphony.xwork.XWorkMessages;
+import com.opensymphony.xwork.*;
 import com.opensymphony.xwork.config.ConfigurationManager;
 import com.opensymphony.xwork.test.ModelDrivenAction2;
 import com.opensymphony.xwork.test.TestBean2;
-
 import junit.framework.TestCase;
 
 import java.util.Collections;
 
 /**
  * LocalizedTextUtilTest
+ *
  * @author Jason Carreira
- * Created Apr 20, 2003 12:07:17 AM
+ *         Created Apr 20, 2003 12:07:17 AM
  */
 public class LocalizedTextUtilTest extends TestCase {
     //~ Methods ////////////////////////////////////////////////////////////////
 
+    public void testActionGetTextXXX() {
+        try {
+            LocalizedTextUtil.addDefaultResourceBundle("com/opensymphony/xwork/util/FindMe");
+
+            SimpleAction action = new SimpleAction();
+
+            Mock mockActionInvocation = new Mock(ActionInvocation.class);
+            mockActionInvocation.expectAndReturn("getAction", action);
+            ActionContext.getContext().setActionInvocation((ActionInvocation) mockActionInvocation.proxy());
+            ActionContext.getContext().getValueStack().push(action);
+
+            String message = action.getText("bean.name");
+            String foundBean2 = action.getText("bean2.name");
+
+            assertEquals("Okay! You found Me!", foundBean2);
+            assertEquals("Haha you cant FindMe!", message);
+
+        } catch (MissingResourceException ex) {
+            ex.printStackTrace();
+            fail(ex.getMessage());
+        }
+    }
+
     public void testActionGetText() {
         try {
             ModelDrivenAction2 action = new ModelDrivenAction2();
 
     public void testParameterizedDefaultMessage() {
         try {
-            String message = LocalizedTextUtil.findDefaultText(XWorkMessages.MISSING_ACTION_EXCEPTION, Locale.getDefault(), new String[] {
-                    "AddUser"
-                });
+            String message = LocalizedTextUtil.findDefaultText(XWorkMessages.MISSING_ACTION_EXCEPTION, Locale.getDefault(), new String[]{
+                "AddUser"
+            });
             assertEquals("There is no Action mapped for action name AddUser", message);
         } catch (MissingResourceException e) {
             e.printStackTrace();
 
     public void testParameterizedDefaultMessageWithPackage() {
         try {
-            String message = LocalizedTextUtil.findDefaultText(XWorkMessages.MISSING_PACKAGE_ACTION_EXCEPTION, Locale.getDefault(), new String[] {
-                    "blah", "AddUser"
-                });
+            String message = LocalizedTextUtil.findDefaultText(XWorkMessages.MISSING_PACKAGE_ACTION_EXCEPTION, Locale.getDefault(), new String[]{
+                "blah", "AddUser"
+            });
             assertEquals("There is no Action mapped for namespace blah and action name AddUser", message);
         } catch (MissingResourceException e) {
             e.printStackTrace();