A problem with the current <bean:message> tag is that the only way to
specify the message resource key dynamically is by using a JSP expression.
This leads to the use of the following pattern:

    <bean:define id="myKey" name="myForm" property="myKeyProperty"
type="java.lang.String"/>
    <bean:message key="<%= myKey %>"/>

An alternative is to have the Action look up the key and set the resulting
string value in the property for use on the JSP page via <bean:write>. This
doesn't feel right, because the responsibility for looking up the
appropriately localized text is then divided between the Action and the JSP
page.

By enhancing the <bean:message> tag to allow it to obtain the message
resource key from a bean property, we can simplify the above example to:

    <bean:message name="myForm" property="myKeyProperty"/>

Here, the 'name' and 'property' attributes are used to obtain the message
resource key from a bean. That key is then used as if it had been specified
using the 'key' attribute.

The attached patch adds the 'name', 'property' and 'scope' attributes to the
<bean:message> tag to support this usage.

--
Martin Cooper

Index: MessageTag.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-struts/src/share/org/apache/struts/taglib/bean/MessageTag.java,v
retrieving revision 1.4
diff -u -r1.4 MessageTag.java
--- MessageTag.java     2001/02/20 01:48:45     1.4
+++ MessageTag.java     2001/05/28 04:24:55
@@ -196,6 +196,48 @@
 
 
     /**
+     * Name of the bean that contains the message key.
+     */
+    protected String name = null;
+
+    public String getName() {
+        return (this.name);
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+
+    /**
+     * Name of the property to be accessed on the specified bean.
+     */
+    protected String property = null;
+
+    public String getProperty() {
+        return (this.property);
+    }
+
+    public void setProperty(String property) {
+        this.property = property;
+    }
+
+
+    /**
+     * The scope to be searched to retrieve the specified bean.
+     */
+    protected String scope = null;
+
+    public String getScope() {
+        return (this.scope);
+    }
+
+    public void setScope(String scope) {
+        this.scope = scope;
+    }
+
+
+    /**
      * The session scope key under which our Locale is stored.
      */
     protected String localeKey = Action.LOCALE_KEY;
@@ -227,6 +269,20 @@
      */
     public int doStartTag() throws JspException {
 
+        String key = this.key;
+        if (key == null) {
+            // Look up the requested property value
+            Object value =
+                RequestUtils.lookup(pageContext, name, property, scope);
+            if (value != null && !(value instanceof String)) {
+                JspException e = new JspException
+                    (messages.getMessage("message.property", key));
+                RequestUtils.saveException(pageContext, e);
+                throw e;
+            }
+            key = (String)value;
+        }
+
        // Construct the optional arguments array we will be using
        Object args[] = new Object[5];
        args[0] = arg0;
@@ -237,7 +293,7 @@
 
        // Retrieve the message string we are looking for
        String message = RequestUtils.message(pageContext, this.bundle,
-                                              this.localeKey, this.key, args);
+                                              this.localeKey, key, args);
        if (message == null) {
            JspException e = new JspException
                (messages.getMessage("message.message", key));
@@ -267,6 +323,9 @@
        arg4 = null;
        bundle = Action.MESSAGES_KEY;
        key = null;
+       name = null;
+       property = null;
+       scope = null;
        localeKey = Action.LOCALE_KEY;
 
     }
Index: LocalStrings.properties
===================================================================
RCS file: 
/home/cvspublic/jakarta-struts/src/share/org/apache/struts/taglib/bean/LocalStrings.properties,v
retrieving revision 1.12
diff -u -r1.12 LocalStrings.properties
--- LocalStrings.properties     2001/05/09 19:31:11     1.12
+++ LocalStrings.properties     2001/05/28 04:25:24
@@ -8,6 +8,7 @@
 include.read=Exception reading resource {0}: {1}
 include.url=Cannot create include URL: {0}
 message.message=Missing message for key {0}
+message.property=Property for message key must be a String
 message.resources=Missing resources attribute {0}
 page.selector=Invalid page context selector {0}
 parameter.get=No parameter {0} was included in this request
Index: struts-bean.xml
===================================================================
RCS file: /home/cvspublic/jakarta-struts/doc/struts-bean.xml,v
retrieving revision 1.4
diff -u -r1.4 struts-bean.xml
--- struts-bean.xml     2001/05/09 19:31:00     1.4
+++ struts-bean.xml     2001/05/28 04:26:11
@@ -444,6 +444,10 @@
     <p>Retrieves an internationalized message for the specified locale,
     using the specified message key, and write it to the output stream.
     Up to five parametric replacements (such as "{0}") may be specified.</p>
+
+    <p>The message key may be specified directly, using the <code>key</code>
+    attribute, or indirectly, using the <code>name</code> and
+    <code>property</code> attributes to obtain it from a bean.</p>
     </info>
 
     <attribute>
@@ -505,11 +509,13 @@
 
     <attribute>
       <name>key</name>
-      <required>true</required>
+      <required>false</required>
       <rtexprvalue>true</rtexprvalue>
       <info>
       <p>The message key of the requested message, which must have
-      a corresponding value in the message resources.</p>
+      a corresponding value in the message resources. If not specified,
+      the key is obtained from the <code>name</code> and
+      <code>property</code> attributes.</p>
       </info>
     </attribute>
 
@@ -522,6 +528,42 @@
       selected <code>Locale</code> object is stored.  If not specified,
       the default name (the value of the <code>Action.LOCALE_KEY</code>
       constant string) is used.</p>
+      </info>
+    </attribute>
+
+    <attribute>
+      <name>name</name>
+      <required>false</required>
+      <rtexprvalue>true</rtexprvalue>
+      <info>
+      <p>Specifies the attribute name of the bean whose property is accessed
+      to retrieve the value specified by <code>property</code> (if
+      specified).  If <code>property</code> is not specified, the value of
+      this bean itself will be used as the message resource key.</p>
+      </info>
+    </attribute>
+
+    <attribute>
+      <name>property</name>
+      <required>false</required>
+      <rtexprvalue>true</rtexprvalue>
+      <info>
+      <p>Specifies the name of the property to be accessed on the bean
+      specified by <code>name</code>.  This value may be a simple, indexed,
+      or nested property reference expression.  If not specified, the value
+      of the bean identified by <code>name</code> will itself be used as the
+      message resource key.</p>
+      </info>
+    </attribute>
+
+    <attribute>
+      <name>scope</name>
+      <required>false</required>
+      <rtexprvalue>true</rtexprvalue>
+      <info>
+      <p>Specifies the variable scope searched to retrieve the bean specified
+      by <code>name</code>.  If not specified, the default rules applied by
+      <code>PageContext.findAttribute()</code> are applied.</p>
       </info>
     </attribute>
 

Reply via email to