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>