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>