Commits

jcarreira  committed 458be4b

TextProviders can now have a value stack passed in to be used when evaluating localized texts, instead of using ActionContext.getContext().getValueStack(). This allows localized texts to be used in Sitemesh decorators.

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

  • Participants
  • Parent commits a9dbd45

Comments (0)

Files changed (5)

File src/java/com/opensymphony/xwork/ActionSupport.java

  */
 package com.opensymphony.xwork;
 
+import com.opensymphony.xwork.util.OgnlValueStack;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import java.io.Serializable;
-
 import java.util.*;
 
 
         return textProvider.getTexts(aBundleName);
     }
 
+    public String getText(String key, String defaultValue, List args, OgnlValueStack stack) {
+        return textProvider.getText(key,defaultValue,args,stack);
+    }
+
     public ResourceBundle getTexts() {
         return textProvider.getTexts();
     }

File src/java/com/opensymphony/xwork/TextProvider.java

  */
 package com.opensymphony.xwork;
 
+import com.opensymphony.xwork.util.OgnlValueStack;
+
 import java.util.List;
-import java.util.Locale;
 import java.util.ResourceBundle;
 
 
      */
     String getText(String key, String defaultValue, List args);
 
+     /**
+     * Gets a message based on a key using the supplied args, as defined in
+     * {@link java.text.MessageFormat}, or, if the message is not found, a supplied
+     * default value is returned. Instead of using the value stack in the ActionContext
+     * this version of the getText() method uses the provided value stack.
+     *
+     * @param key the resource bundle key that is to be searched for
+     * @param defaultValue the default value which will be returned if no message is found
+     * @param args a list args to be used in a {@link java.text.MessageFormat} message
+     * @param stack the value stack to use for finding the text
+     * @return the message as found in the resource bundle, or defaultValue if none is found
+     */
+    String getText(String key, String defaultValue, List args, OgnlValueStack stack);
+
     /**
     * Get the named bundle, such as "com/acme/Foo".
     *

File src/java/com/opensymphony/xwork/TextProviderSupport.java

 package com.opensymphony.xwork;
 
 import com.opensymphony.xwork.util.LocalizedTextUtil;
-
-import java.io.Serializable;
+import com.opensymphony.xwork.util.OgnlValueStack;
 
 import java.util.List;
 import java.util.Locale;
     }
 
     /**
+     * Gets a message based on a key using the supplied args, as defined in
+     * {@link java.text.MessageFormat}, or, if the message is not found, a supplied
+     * default value is returned. Instead of using the value stack in the ActionContext
+     * this version of the getText() method uses the provided value stack.
+     *
+     * @param aTextName   the resource bundle key that is to be searched for
+     * @param defaultValue the default value which will be returned if no message is found
+     * @param args         a list args to be used in a {@link java.text.MessageFormat} message
+     * @param stack        the value stack to use for finding the text
+     * @return the message as found in the resource bundle, or defaultValue if none is found
+     */
+    public String getText(String aTextName, String defaultValue, List args, OgnlValueStack stack) {
+        Object[] argsArray = ((args != null) ? args.toArray() : null);
+
+        if (clazz != null) {
+            return LocalizedTextUtil.findText(clazz, aTextName, getLocale(), defaultValue, argsArray, stack);
+        } else {
+            return LocalizedTextUtil.findText(bundle, aTextName, getLocale(), defaultValue, argsArray, stack);
+        }
+    }
+
+    /**
     * Get the named bundle.
     *
     * You can override the getLocale() methodName to change the behaviour of how

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

      * @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();
+        OgnlValueStack valueStack = ActionContext.getContext().getValueStack();
+        return findText(aClass, aTextName, locale, defaultMessage, args, 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:
+     * <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
+     * @param valueStack the value stack to use to evaluate expressions instead of the
+     * one in the ActionContext ThreadLocal
+     * @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, OgnlValueStack valueStack) {
         String indexedTextName = null;
         if (aTextName == null) {
             LOG.warn("Trying to find text with null key!");
         }
 
         if (ModelDriven.class.isAssignableFrom(aClass)) {
+            ActionContext context = ActionContext.getContext();
             // search up model's class hierarchy
             ActionInvocation actionInvocation = context.getActionInvocation();
 
     public static String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args) {
         OgnlValueStack valueStack = ActionContext.getContext().getValueStack();
 
+        return findText(bundle, aTextName, locale, defaultMessage, args, valueStack);
+
+    }
+
+    public static String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args, OgnlValueStack valueStack) {
         try {
             reloadBundles(bundle);
 

File src/java/com/opensymphony/xwork/validator/DelegatingValidatorContext.java

 package com.opensymphony.xwork.validator;
 
 import com.opensymphony.xwork.*;
+import com.opensymphony.xwork.util.OgnlValueStack;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
         return textProvider.getTexts(aBundleName);
     }
 
+    public String getText(String key, String defaultValue, List args, OgnlValueStack stack) {
+        return textProvider.getText(key,defaultValue,args,stack);
+    }
+
     public ResourceBundle getTexts() {
         return textProvider.getTexts();
     }