struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From craig...@apache.org
Subject svn commit: r373633 - in /struts/shale/trunk/core-library/src/java/org/apache/shale: faces/ShalePropertyResolver.java util/LoadBundle.java util/Messages.java
Date Mon, 30 Jan 2006 23:50:01 GMT
Author: craigmcc
Date: Mon Jan 30 15:49:55 2006
New Revision: 373633

URL: http://svn.apache.org/viewcvs?rev=373633&view=rev
Log:
Improve usability of the LoadBundle and Messages helper classes, by explicitly
loading the default resource bundle if the requested one is not found.  This
needs to be reviewed to see if we should also do the "strip suffixes" trick
that ResourceBundle itself does (but only after explicitly finding a bundle
with the specified name, which is not particularly friendly).

Also, customize the Shale property resolver so that expressions like:

  #{myLoadBundle['message.key']}

work instead of (actually, for backwards compatibility, in addition to):

  #{myLoadBundle.map['message.key']}

In this way, you can directly substitute use of the LoadBundle helper class,
which makes the resources available to Java event handlers as well, by
simply removing all <f:loadBundle> tags from your JSP pages, and creating
a managed bean (typically in application scope) for the corresponding
"var" name.

Modified:
    struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShalePropertyResolver.java
    struts/shale/trunk/core-library/src/java/org/apache/shale/util/LoadBundle.java
    struts/shale/trunk/core-library/src/java/org/apache/shale/util/Messages.java

Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShalePropertyResolver.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShalePropertyResolver.java?rev=373633&r1=373632&r2=373633&view=diff
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShalePropertyResolver.java
(original)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShalePropertyResolver.java
Mon Jan 30 15:49:55 2006
@@ -16,6 +16,8 @@
 
 package org.apache.shale.faces;
 
+import java.beans.Beans;
+import java.util.Map;
 import javax.faces.el.EvaluationException;
 import javax.faces.el.PropertyNotFoundException;
 import javax.faces.el.PropertyResolver;
@@ -23,6 +25,7 @@
 import javax.naming.Name;
 import javax.naming.NameNotFoundException;
 import javax.naming.NamingException;
+import org.apache.shale.util.LoadBundle;
 
 /**
  * <p>Shale-specific PropertyResolver for evaluating JavaServer Faces
@@ -34,6 +37,18 @@
  *     to the <code>lookup()</code> method of the <code>Context</code>.
  *     The Context has no way to describe whether it is read only or not,
  *     so <code>isReadOnly()</code> returns <code>false</code>.</li>
+ * <li><strong>org.apache.shale.util.LoadBundle</strong> - Special handling
+ *     as follows, based on the requested property name:
+ *     <ul>
+ *     <li><code>map</code> - Delegates to the original resolver's handling
+ *         of the <code>map</code> property.  This is for backwards compatibility
+ *         with applications depending on this behavior from the 1.0.0
+ *         version of the class.</li>
+ *     <li>Any other property is considered to be a resource bundle key, which
+ *         will be used to look up the corresponding value from the underlying
+ *         resource bundle, using the <code>Locale</code> from the current
+ *         view for selecting the appropriate translation.</li>
+ *     </ul></li>
  * </ul>
  * <p>All other evaluations are delegated to the previous implementation
  * that was passed to our constructor.</p>
@@ -63,7 +78,7 @@
 
 
     /**
-     * <p>The original <code>VariableResolver</code> passed to our constructor.</p>
+     * <p>The original <code>PropertyResolver</code> passed to our constructor.</p>
      */
     private PropertyResolver original = null;
 
@@ -72,8 +87,19 @@
 
 
     /**
-     * <p>Look up and return the named object corresponding to the
-     * specified property name from this Context.</p>
+     * <p>For a base object of type <code>Context</code>, look up and return
+     * the named object corresponding to the specified property name from
+     * this <code>Context</code>.</p>
+     *
+     * <p>(Since 1.0.1) For a base object of type <code>LoadBundle</code>,
+     * treat the property expression as follows:</p>
+     * <ul>
+     * <li>If the property name is <code>map</code>, call the corresponding
+     *     property getter and return that value.</li>
+     * <li>Otherwise, treat the property name as a message key, and look up
+     *     and return the corresponding value from the <code>Map</code> that
+     *     is returned by the <code>getMap()</code> call.</li>
+     * </ul>
      *
      * @param base Base object from which to return a property
      * @param property Property to be returned
@@ -100,6 +126,13 @@
             } catch (NamingException e) {
                 throw new EvaluationException(e);
             }
+        } else if (base instanceof LoadBundle) {
+            Map map = ((LoadBundle) base).getMap();
+            if ("map".equals(property)) {
+                return map;
+            } else {
+                return map.get(property);
+            }
         } else {
             return original.getValue(base, property);
         }
@@ -108,8 +141,12 @@
 
 
     /**
-     * <p>Replace any previous binding for the named object corresponding
-     * to the specified property name into this Context.</p>
+     * <p>For a base object of type <code>Context</code>, replace any previous
+     * binding for the named object corresponding to the specified property
+     * name into this <code>Context</code>.</p>
+     *
+     * <p>(Since 1.0.1) For a base object of type <code>LoadBundle</code>,
+     * throw an exception since all properties of this object are read only.</p>
      *
      * @param base Base object in which to store a property
      * @param property Property to be stored
@@ -134,6 +171,8 @@
             } catch (NamingException e) {
                 throw new EvaluationException(e);
             }
+        } else if (base instanceof LoadBundle) {
+            throw new PropertyNotFoundException("" + value);
         } else {
             original.setValue(base, property, value);
         }
@@ -142,8 +181,13 @@
 
 
     /**
-     * <p>Arbitrarily return false because we cannot determine if a
-     * Context is read only or not.</p>
+     * <p>For a <code>Context</code> base object, arbitrarily return
+     * <code>false</code> because we cannot determine if a <code>Context</code>
+     * is read only or not.</p>
+     *
+     * <p>(Since 1.0.1) For a <code>LoadBundle</code> base object,
+     * return <code>true</code> because all pseudo-properties of
+     * this bundle are considered to be read only.</p>
      *
      * @param base Base object from which to return read only state
      * @param property Property to be checked
@@ -159,6 +203,9 @@
             // Mimic standard JSF/JSP behavior when base is a Map
             // by returning false if we cannot tell any better
             return false;
+        } else if (base instanceof LoadBundle) {
+            // All properties of this object are considered read only
+            return true;
         } else {
             return original.isReadOnly(base, property);
         }
@@ -167,8 +214,13 @@
 
 
     /**
-     * <p>Look up and return the type of the named object corresponding to the
-     * specified property name from this Context.</p>
+     * <p>For a <code>Context</code>, look up and return the type of the
+     * named object corresponding to the specified property name from this
+     * <code>Context</code>.</p>
+     *
+     * <p>(Since 1.0.1) For a <code>LoadBundle</code>, look up and return
+     * the corresponding object type at runtime, or return <code>Object</code>
+     * for the type to be looked up at design time.</p>
      *
      * @param base Base object from which to return a property type
      * @param property Property whose type is to be returned
@@ -201,6 +253,21 @@
             } else {
                 return value.getClass();
             }
+        } else if (base instanceof LoadBundle) {
+            LoadBundle lb = (LoadBundle) base;
+            if ("map".equals(property)) {
+                return Map.class;
+            } else if (Beans.isDesignTime()) {
+                return Object.class;
+            } else {
+                Object value = lb.getMap().get(property);
+                if (value != null) {
+                    return value.getClass();
+                } else {
+                    return null;
+                }
+            }
+
         } else {
             return original.getType(base, property);
         }
@@ -223,6 +290,8 @@
 
         if (base instanceof Context) {
             return getValue(base, "" + index);
+        } else if (base instanceof LoadBundle) {
+            return getValue(base, "" + index);
         } else {
             return original.getValue(base, index);
         }
@@ -246,6 +315,8 @@
 
         if (base instanceof Context) {
             setValue(base, "" + index, value);
+        } else if (base instanceof LoadBundle) {
+            setValue(base, "" + index, value);
         } else {
             original.setValue(base, index, value);
         }
@@ -268,6 +339,8 @@
 
         if (base instanceof Context) {
             return isReadOnly(base, "" + index);
+        } else if (base instanceof LoadBundle) {
+            return isReadOnly(base, "" + index);
         } else {
             return original.isReadOnly(base, index);
         }
@@ -289,6 +362,8 @@
       throws EvaluationException, PropertyNotFoundException {
 
         if (base instanceof Context) {
+            return getType(base, "" + index);
+        } else if (base instanceof LoadBundle) {
             return getType(base, "" + index);
         } else {
             return original.getType(base, index);

Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/util/LoadBundle.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/util/LoadBundle.java?rev=373633&r1=373632&r2=373633&view=diff
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/util/LoadBundle.java (original)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/util/LoadBundle.java Mon Jan
30 15:49:55 2006
@@ -57,8 +57,19 @@
  * property will return a <code>Map</code> representing the localized messages
for
  * the <code>com.mycompany.mypackage.Bundle</code> resource bundle.  You can
look
  * up localized messages in this <code>Map</code> by evaluating a value binding
- * expression like <code>#{messages.map['message.key']}</code>, where
- * <code>message.key</code> is the key for which to retrieve a localized message.</p>
+ * expression like this:</p>
+ * <blockquote>
+ *   <code>#{messages.['message.key']}</code>
+ * </blockquote>
+ * <p>where <code>message.key</code> is the key for which to retrieve a
+ * localized message.</p>
+ *
+ * <p>(Since 1.0.1) <strong>IMPLEMENTATION NOTE</strong> - For backwards
+ * compatibility in applications that utilized the 1.0.0 version of this
+ * class, the following sort of expression resolves to the same value:</p>
+ * <blockquote>
+ *   <code>#{messages.map['message.key']}</code>
+ * </blockquote>
  */
 public class LoadBundle {
 
@@ -80,6 +91,15 @@
    }
 
 
+   // --------------------------------------------------------- Static Variables
+
+
+   /**
+    * <p>The default <code>Locale</code> for this application.</p>
+    */
+   private static final Locale defaultLocale = Locale.getDefault();
+
+
    // --------------------------------------------------------------- Properties
 
 
@@ -128,9 +148,7 @@
        assert locale != null;
 
        // Look up the requested resource bundle
-       final ResourceBundle bundle =
-         ResourceBundle.getBundle(basename, locale,
-                                  Thread.currentThread().getContextClassLoader());
+       final ResourceBundle bundle = getBundle(basename, locale);
        if (bundle == null) {
            throw new IllegalArgumentException
              ("No resource bundle found for base name '" + basename + "' and locale '" +
locale + "'"); // FIXME - i18n
@@ -249,6 +267,33 @@
        return map;
 
    }
+
+
+    // --------------------------------------------------------- Private Methods
+
+
+    /**
+     * <p>Return the localized <code>ResourceBundle</code> for the specified
+     * <code>Locale</code>.</p>
+     *
+     * @param basename Base name of the resource bundle to return
+     * @param locale Locale used to select the appropriate resource bundle
+     */
+    private ResourceBundle getBundle(String basename, Locale locale) {
+
+        assert basename != null;
+        assert locale != null;
+        ClassLoader rbcl = Thread.currentThread().getContextClassLoader();
+        if (rbcl == null) {
+            rbcl = this.getClass().getClassLoader();
+        }
+        try {
+            return ResourceBundle.getBundle(basename, locale, rbcl);
+        } catch (MissingResourceException e) {
+            return ResourceBundle.getBundle(basename, defaultLocale, rbcl);
+        }
+
+    }
 
 
 }

Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/util/Messages.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/util/Messages.java?rev=373633&r1=373632&r2=373633&view=diff
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/util/Messages.java (original)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/util/Messages.java Mon Jan 30
15:49:55 2006
@@ -277,7 +277,11 @@
         synchronized (bundles) {
             rb = (ResourceBundle) bundles.get(locale);
             if (rb == null) {
-                rb = ResourceBundle.getBundle(name, locale, cl);
+                try {
+                    rb = ResourceBundle.getBundle(name, locale, cl);
+                } catch (MissingResourceException e) {
+                    rb = ResourceBundle.getBundle(name, defaultLocale, cl);
+                }
                 bundles.put(locale, rb);
             }
             return rb;



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Mime
View raw message