You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by ni...@apache.org on 2006/11/29 13:16:16 UTC
svn commit: r480549 - in /struts/struts1/trunk:
apps/examples/src/main/webapp/WEB-INF/validator/ core/
core/src/main/java/org/apache/struts/util/
core/src/test/java/org/apache/struts/util/ src/site/xdoc/userGuide/
Author: niallp
Date: Wed Nov 29 04:16:15 2006
New Revision: 480549
URL: http://svn.apache.org/viewvc?view=rev&rev=480549
Log:
STR-2925 and STR-2077 - Add configuration option to PropertyMessageResources to operate in one of three modes: 1) default (as its always has) 2) JSTL compatible and 3) PropertyResourceBundle compatible
Added:
struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo.properties (with props)
struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_de.properties (with props)
struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_de_DE.properties (with props)
struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_en.properties (with props)
struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_en_US.properties (with props)
struts/struts1/trunk/core/src/test/java/org/apache/struts/util/TestPropertyMessageResources.java (with props)
Modified:
struts/struts1/trunk/apps/examples/src/main/webapp/WEB-INF/validator/struts-config-i18nVariables.xml
struts/struts1/trunk/apps/examples/src/main/webapp/WEB-INF/validator/struts-config.xml
struts/struts1/trunk/core/pom.xml
struts/struts1/trunk/core/src/main/java/org/apache/struts/util/PropertyMessageResources.java
struts/struts1/trunk/core/src/main/java/org/apache/struts/util/PropertyMessageResourcesFactory.java
struts/struts1/trunk/src/site/xdoc/userGuide/configuration.xml
Modified: struts/struts1/trunk/apps/examples/src/main/webapp/WEB-INF/validator/struts-config-i18nVariables.xml
URL: http://svn.apache.org/viewvc/struts/struts1/trunk/apps/examples/src/main/webapp/WEB-INF/validator/struts-config-i18nVariables.xml?view=diff&rev=480549&r1=480548&r2=480549
==============================================================================
--- struts/struts1/trunk/apps/examples/src/main/webapp/WEB-INF/validator/struts-config-i18nVariables.xml (original)
+++ struts/struts1/trunk/apps/examples/src/main/webapp/WEB-INF/validator/struts-config-i18nVariables.xml Wed Nov 29 04:16:15 2006
@@ -104,9 +104,12 @@
automatically 'escape' single quotes.
-->
- <message-resources key="i18nExample" null="false" parameter="org.apache.struts.webapp.validator.I18nExample" />
+ <message-resources key="i18nExample" null="false" parameter="org.apache.struts.webapp.validator.I18nExample">
+ <set-property key="mode" value="JSTL"/>
+ </message-resources>
<message-resources key="i18nVariables" null="true" parameter="org.apache.struts.webapp.validator.I18nExampleVariables" >
<set-property property="escape" value="false"/>
+ <set-property key="mode" value="JSTL"/>
</message-resources>
</struts-config>
Modified: struts/struts1/trunk/apps/examples/src/main/webapp/WEB-INF/validator/struts-config.xml
URL: http://svn.apache.org/viewvc/struts/struts1/trunk/apps/examples/src/main/webapp/WEB-INF/validator/struts-config.xml?view=diff&rev=480549&r1=480548&r2=480549
==============================================================================
--- struts/struts1/trunk/apps/examples/src/main/webapp/WEB-INF/validator/struts-config.xml (original)
+++ struts/struts1/trunk/apps/examples/src/main/webapp/WEB-INF/validator/struts-config.xml Wed Nov 29 04:16:15 2006
@@ -89,7 +89,9 @@
<!-- ===================================== Message Resources Definitions -->
- <message-resources parameter="org.apache.struts.webapp.validator.MessageResources" />
+ <message-resources parameter="org.apache.struts.webapp.validator.MessageResources">
+ <set-property key="mode" value="JSTL"/>
+ </message-resources>
<!-- ============================================ Plug Ins Configuration -->
Modified: struts/struts1/trunk/core/pom.xml
URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/pom.xml?view=diff&rev=480549&r1=480548&r2=480549
==============================================================================
--- struts/struts1/trunk/core/pom.xml (original)
+++ struts/struts1/trunk/core/pom.xml Wed Nov 29 04:16:15 2006
@@ -67,6 +67,7 @@
<directory>src/test/java</directory>
<includes>
<include>**/*.xml</include>
+ <include>**/*.properties</include>
</includes>
</testResource>
</testResources>
Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/util/PropertyMessageResources.java
URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/util/PropertyMessageResources.java?view=diff&rev=480549&r1=480548&r2=480549
==============================================================================
--- struts/struts1/trunk/core/src/main/java/org/apache/struts/util/PropertyMessageResources.java (original)
+++ struts/struts1/trunk/core/src/main/java/org/apache/struts/util/PropertyMessageResources.java Wed Nov 29 04:16:15 2006
@@ -33,8 +33,8 @@
/**
* Concrete subclass of <code>MessageResources</code> that reads message keys
- * and corresponding strings from named property resources in the same manner
- * that <code>java.util.PropertyResourceBundle</code> does. The
+ * and corresponding strings from named property resources in a <b><i>similar</i></b> manner
+ * (see <i>modes</i> below) that <code>java.util.PropertyResourceBundle</code> does. The
* <code>base</code> property defines the base property resource name, and
* must be specified. <p> <strong>IMPLEMENTATION NOTE</strong> - This class
* trades memory for speed by caching all messages located via generalizing
@@ -43,10 +43,89 @@
* response time on subsequent requests for the same locale + key
* combination.
*
- * @version $Rev$ $Date: 2005-05-07 12:11:38 -0400 (Sat, 07 May 2005)
- * $
+ * <h2>Operating Modes</h2>
+ * This implementation can be configured to operate in one of three modes:
+ * <ul>
+ * <li>1. <b>Default</b> - default, backwardly compatible, Struts behaviour (i.e. the way
+ * its always worked).</li>
+ * <li>2. <b>JSTL</b> - compatible with how JSTL finds messages
+ * (fix for <a href="http://issues.apache.org/struts/browse/STR-2925">STR-2925</a>)</li>
+ * <li>3. <b>Resource</b> - compatible with how Java's <code>PropertyResourceBundle</code>
+ * finds messages (fix for
+ * <a href="http://issues.apache.org/struts/browse/STR-2077">STR-2077</a>)</li>
+ * </ul>
+ *
+ * <h3>1. Default Mode</h3>
+ * <i>Default mode</i> is the way this implementation has always operated. It searches
+ * for a message key for property resources in the following sequence:
+ * <pre>
+ * base + "_" + localeLanguage + "_" + localeCountry + "_" + localeVariant
+ * base + "_" + localeLanguage + "_" + localeCountry
+ * base + "_" + localeLanguage
+ * base + "_" + default locale
+ * base
+ * </pre>
+ * <p>
+ * This mode is the <i>default</i> and requires no additional configuration.
+ *
+ * <h3>2. JSTL Mode</h3>
+ * <i>JSTL mode</i> is compatible with how JSTL operates and the default Locale
+ * is not used when looking for a message key. <i>JSTL mode</i> searches for
+ * a message key for property resources in the following sequence:
+ * <pre>
+ * base + "_" + localeLanguage + "_" + localeCountry + "_" + localeVariant
+ * base + "_" + localeLanguage + "_" + localeCountry
+ * base + "_" + localeLanguage
+ * base
+ * </pre>
+ * <p>
+ * Configure <code>PropertyMessageResources</code> to operate in this mode by
+ * specifying a value of <code>JSTL</code> for the <code>mode</code>
+ * key in your <code>struts-config.xml</code>:
+ * <pre>
+ * <message-resources parameter="mypackage.MyMessageResources">
+ * <set-property key="mode" value="JSTL"/>
+ * </message-resources>
+ * </pre>
+ *
+ * <h3>3. Resource Mode</h3>
+ * <i>Resource mode</i> is compatible with how Java's <code>PropertyResourceBundle</code>
+ * operates. <i>Resource mode</i> searches first through the specified Locale's language,
+ * country and variant, then through the default Locale's language,
+ * country and variant and finally using just the <code>base</code>:
+ * <pre>
+ * base + "_" + localeLanguage + "_" + localeCountry + "_" + localeVariant
+ * base + "_" + localeLanguage + "_" + localeCountry
+ * base + "_" + localeLanguage
+ * base + "_" + defaultLanguage + "_" + defaultCountry + "_" + defaultVariant
+ * base + "_" + defaultLanguage + "_" + defaultCountry
+ * base + "_" + defaultLanguage
+ * base
+ * </pre>
+ * <p>
+ * Configure <code>PropertyMessageResources</code> to operate in this mode by
+ * specifying a value of <code>resource</code> for the <code>mode</code>
+ * key in your <code>struts-config.xml</code>:
+ * <pre>
+ * <message-resources parameter="mypackage.MyMessageResources">
+ * <set-property key="mode" value="resource"/>
+ * </message-resources>
+ * </pre>
+ *
+ * @version $Rev$ $Date$
*/
public class PropertyMessageResources extends MessageResources {
+
+
+ /** Indicates compatibility with how PropertyMessageResources has always looked up messages */
+ private static final int MODE_DEFAULT = 0;
+
+ /** Indicates compatibility with how JSTL looks up messages */
+ private static final int MODE_JSTL = 1;
+
+ /** Indicates compatibility with how java's PropertyResourceBundle looks up messages */
+ private static final int MODE_RESOURCE_BUNDLE = 2;
+
/**
* The <code>Log</code> instance for this class.
*/
@@ -67,6 +146,11 @@
*/
protected HashMap messages = new HashMap();
+ /**
+ * Compatibility mode that PropertyMessageResources is operating in.
+ */
+ private int mode = MODE_DEFAULT;
+
// ----------------------------------------------------------- Constructors
/**
@@ -101,8 +185,35 @@
// --------------------------------------------------------- Public Methods
/**
- * Returns a text message for the specified key, for the default Locale. A
- * null string result will be returned by this method if no relevant
+ * Set the compatibility mode this implementation uses for message lookup.
+ *
+ * @param mode <code>JSTL</code> for JSTL compatibility,
+ * <code>resource</code> for PropertyResourceBundle compatibility or
+ * <code>default</code> for Struts backward compatibility.
+ */
+ public void setMode(String mode) {
+ String value = (mode == null ? null : mode.trim());
+ if ("jstl".equalsIgnoreCase(value)) {
+ this.mode = MODE_JSTL;
+ if (log.isDebugEnabled()) {
+ log.info("Operating in JSTL compatible mode [" + mode + "]");
+ }
+ } else if ("resource".equalsIgnoreCase(value)) {
+ this.mode = MODE_RESOURCE_BUNDLE;
+ if (log.isDebugEnabled()) {
+ log.info("Operating in PropertyResourceBundle compatible mode [" + mode + "]");
+ }
+ } else {
+ this.mode = MODE_DEFAULT;
+ if (log.isDebugEnabled()) {
+ log.info("Operating in Default mode [" + mode + "]");
+ }
+ }
+ }
+
+ /**
+ * Returns a text message for the specified key, for the specified or default
+ * Locale. A null string result will be returned by this method if no relevant
* message resource is found for this key or Locale, if the
* <code>returnNull</code> property is set. Otherwise, an appropriate
* error message will be returned. <p> This method must be implemented by
@@ -121,72 +232,45 @@
// Initialize variables we will require
String localeKey = localeKey(locale);
String originalKey = messageKey(localeKey, key);
- String messageKey = null;
String message = null;
- int underscore = 0;
- boolean addIt = false; // Add if not found under the original key
- // Loop from specific to general Locales looking for this message
- while (true) {
- // Load this Locale's messages if we have not done so yet
- loadLocale(localeKey);
+ // Search the specified Locale
+ message = findMessage(locale, key, originalKey);
+ if (message != null) {
+ return message;
+ }
- // Check if we have this key for the current locale key
- messageKey = messageKey(localeKey, key);
+ // JSTL Compatibility - JSTL doesn't use the default locale
+ if (mode == MODE_JSTL) {
- synchronized (messages) {
- message = (String) messages.get(messageKey);
+ // do nothing (i.e. don't use default Locale)
- if (message != null) {
- if (addIt) {
- messages.put(originalKey, message);
- }
+ // PropertyResourcesBundle - searches through the hierarchy
+ // for the default Locale (e.g. first en_US then en)
+ } else if (mode == MODE_RESOURCE_BUNDLE) {
- return (message);
- }
+ if (!defaultLocale.equals(locale)) {
+ message = findMessage(defaultLocale, key, originalKey);
}
- // Strip trailing modifiers to try a more general locale key
- addIt = true;
- underscore = localeKey.lastIndexOf("_");
+ // Default (backwards) Compatibility - just searches the
+ // specified Locale (e.g. just en_US)
+ } else {
- if (underscore < 0) {
- break;
+ if (!defaultLocale.equals(locale)) {
+ localeKey = localeKey(defaultLocale);
+ message = findMessage(localeKey, key, originalKey);
}
- localeKey = localeKey.substring(0, underscore);
}
-
- // Try the default locale if the current locale is different
- if (!defaultLocale.equals(locale)) {
- localeKey = localeKey(defaultLocale);
- messageKey = messageKey(localeKey, key);
- loadLocale(localeKey);
-
- synchronized (messages) {
- message = (String) messages.get(messageKey);
-
- if (message != null) {
- messages.put(originalKey, message);
-
- return (message);
- }
- }
+ if (message != null) {
+ return message;
}
- // As a last resort, try the default Locale
- localeKey = "";
- messageKey = messageKey(localeKey, key);
- loadLocale(localeKey);
-
- synchronized (messages) {
- message = (String) messages.get(messageKey);
-
- if (message != null) {
- messages.put(originalKey, message);
-
- return (message);
- }
+ // Find the message in the default properties file
+ message = findMessage("", key, originalKey);
+ if (message != null) {
+ return message;
}
// Return an appropriate error indication
@@ -288,6 +372,85 @@
messages.put(messageKey(localeKey, key), props.getProperty(key));
}
+ }
+ }
+
+ // -------------------------------------------------------- Private Methods
+
+ /**
+ * Returns a text message for the specified key, for the specified Locale.
+ * <p>
+ * A null string result will be returned by this method if no relevant
+ * message resource is found. This method searches through the locale
+ * <i>hierarchy</i> (i.e. variant --> languge --> country) for the message.
+ *
+ * @param locale The requested message Locale, or <code>null</code> for
+ * the system default Locale
+ * @param key The message key to look up
+ * @param originalKey The original message key to cache any found message under
+ * @return text message for the specified key and locale
+ */
+ private String findMessage(Locale locale, String key, String originalKey) {
+
+ // Initialize variables we will require
+ String localeKey = localeKey(locale);
+ String messageKey = null;
+ String message = null;
+ int underscore = 0;
+
+ // Loop from specific to general Locales looking for this message
+ while (true) {
+ message = findMessage(localeKey, key, originalKey);
+ if (message != null) {
+ break;
+ }
+
+ // Strip trailing modifiers to try a more general locale key
+ underscore = localeKey.lastIndexOf("_");
+
+ if (underscore < 0) {
+ break;
+ }
+
+ localeKey = localeKey.substring(0, underscore);
+ }
+
+ return message;
+
+ }
+
+ /**
+ * Returns a text message for the specified key, for the specified Locale.
+ * <p>
+ * A null string result will be returned by this method if no relevant
+ * message resource is found.
+ *
+ * @param locale The requested key of the Locale
+ * @param key The message key to look up
+ * @param originalKey The original message key to cache any found message under
+ * @return text message for the specified key and locale
+ */
+ private String findMessage(String localeKey, String key, String originalKey) {
+
+ // Load this Locale's messages if we have not done so yet
+ loadLocale(localeKey);
+
+ // Check if we have this key for the current locale key
+ String messageKey = messageKey(localeKey, key);
+
+ // Add if not found under the original key
+ boolean addIt = !messageKey.equals(originalKey);
+
+ synchronized (messages) {
+ String message = (String) messages.get(messageKey);
+
+ if (message != null) {
+ if (addIt) {
+ messages.put(originalKey, message);
+ }
+
+ }
+ return (message);
}
}
}
Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/util/PropertyMessageResourcesFactory.java
URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/util/PropertyMessageResourcesFactory.java?view=diff&rev=480549&r1=480548&r2=480549
==============================================================================
--- struts/struts1/trunk/core/src/main/java/org/apache/struts/util/PropertyMessageResourcesFactory.java (original)
+++ struts/struts1/trunk/core/src/main/java/org/apache/struts/util/PropertyMessageResourcesFactory.java Wed Nov 29 04:16:15 2006
@@ -26,8 +26,7 @@
* configuration paramter for such instances is the base Java package name of
* the resources entries from which our keys and values will be loaded.
*
- * @version $Rev$ $Date: 2005-05-07 12:11:38 -0400 (Sat, 07 May 2005)
- * $
+ * @version $Rev$ $Date$
*/
public class PropertyMessageResourcesFactory extends MessageResourcesFactory {
// --------------------------------------------------------- Public Methods
@@ -39,6 +38,13 @@
* @param config Configuration parameter(s) for the requested bundle
*/
public MessageResources createResources(String config) {
- return new PropertyMessageResources(this, config, this.returnNull);
+ PropertyMessageResources messageResources =
+ new PropertyMessageResources(this, config, this.returnNull);
+ String mode = null;
+ if (getConfig() != null) {
+ mode = getConfig().getProperty("mode");
+ }
+ messageResources.setMode(mode);
+ return messageResources;
}
}
Added: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo.properties
URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo.properties?view=auto&rev=480549
==============================================================================
--- struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo.properties (added)
+++ struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo.properties Wed Nov 29 04:16:15 2006
@@ -0,0 +1,5 @@
+key.all=ALL default
+key.default=default only
+key.lang=LANG default
+key.country=COUNTRY default
+
Propchange: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo.properties
------------------------------------------------------------------------------
svn:eol-style = native
Added: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_de.properties
URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_de.properties?view=auto&rev=480549
==============================================================================
--- struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_de.properties (added)
+++ struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_de.properties Wed Nov 29 04:16:15 2006
@@ -0,0 +1,3 @@
+key.all=ALL de
+key.de=de only
+key.lang=LANG de
Propchange: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_de.properties
------------------------------------------------------------------------------
svn:eol-style = native
Added: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_de_DE.properties
URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_de_DE.properties?view=auto&rev=480549
==============================================================================
--- struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_de_DE.properties (added)
+++ struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_de_DE.properties Wed Nov 29 04:16:15 2006
@@ -0,0 +1,3 @@
+key.all=ALL de_DE
+key.de_DE=de_DE only
+key.country=COUNTRY de_DE
Propchange: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_de_DE.properties
------------------------------------------------------------------------------
svn:eol-style = native
Added: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_en.properties
URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_en.properties?view=auto&rev=480549
==============================================================================
--- struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_en.properties (added)
+++ struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_en.properties Wed Nov 29 04:16:15 2006
@@ -0,0 +1,3 @@
+key.all=ALL en
+key.en=en only
+key.lang=LANG en
Propchange: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_en.properties
------------------------------------------------------------------------------
svn:eol-style = native
Added: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_en_US.properties
URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_en_US.properties?view=auto&rev=480549
==============================================================================
--- struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_en_US.properties (added)
+++ struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_en_US.properties Wed Nov 29 04:16:15 2006
@@ -0,0 +1,3 @@
+key.all=ALL en_US
+key.en_US=en_US only
+key.country=COUNTRY en_US
Propchange: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/Foo_en_US.properties
------------------------------------------------------------------------------
svn:eol-style = native
Added: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/TestPropertyMessageResources.java
URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/test/java/org/apache/struts/util/TestPropertyMessageResources.java?view=auto&rev=480549
==============================================================================
--- struts/struts1/trunk/core/src/test/java/org/apache/struts/util/TestPropertyMessageResources.java (added)
+++ struts/struts1/trunk/core/src/test/java/org/apache/struts/util/TestPropertyMessageResources.java Wed Nov 29 04:16:15 2006
@@ -0,0 +1,220 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts.util;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.framework.TestCase;
+
+import java.util.Locale;
+import org.apache.struts.config.MessageResourcesConfig;
+
+/**
+ * Unit tests for PropertyMessageResources.
+ *
+ * @version $Revision$
+ */
+public class TestPropertyMessageResources extends TestCase {
+
+
+ private static final String FOO_RESOURCES = "org.apache.struts.util.Foo";
+
+ private Locale defaultLocale;
+
+ // ----------------------------------------------------------------- Basics
+ public TestPropertyMessageResources(String name) {
+ super(name);
+ }
+
+ public static void main(String[] args) {
+ junit.awtui.TestRunner.main(new String[] {
+ TestPropertyMessageResources.class.getName()
+ });
+ }
+
+ public static Test suite() {
+ return (new TestSuite(TestPropertyMessageResources.class));
+ }
+
+ // ----------------------------------------------------- Setup and Teardown
+ public void setUp() {
+ // cache the default locale
+ defaultLocale = Locale.getDefault();
+ }
+
+ public void tearDown() {
+ // restore the default locale
+ Locale.setDefault(defaultLocale);
+ }
+
+ // ------------------------------------------------------- Individual Tests
+
+ /**
+ * Test Struts default PropertyMessageResources behaviour
+ */
+ public void testDefaultMode() {
+
+ Locale.setDefault(Locale.US);
+
+ // Create message resources - default Struts Behaviour
+// MessageResources resources = createMessageResources(FOO_RESOURCES, true, "DEFAULT");
+ MessageResources resources = createMessageResources(FOO_RESOURCES, true, null);
+
+ // Test language (& default) only keys
+ assertEquals("key.lang FRANCE", "LANG default", resources.getMessage(Locale.FRANCE, "key.lang")); // no cached en_US
+ assertEquals("key.lang English", "LANG en", resources.getMessage(Locale.ENGLISH, "key.lang"));
+ assertEquals("key.lang US", "LANG en", resources.getMessage(Locale.US, "key.lang"));
+ assertEquals("key.lang ITALY", "LANG en", resources.getMessage(Locale.ITALY, "key.lang")); // cached en_US
+ assertEquals("key.lang German", "LANG de", resources.getMessage(Locale.GERMAN, "key.lang"));
+ assertEquals("key.lang GERMANY", "LANG de", resources.getMessage(Locale.GERMANY, "key.lang"));
+
+ // Test country (& default) only keys
+ assertEquals("key.country FRANCE", "COUNTRY en_US", resources.getMessage(Locale.FRANCE, "key.country"));
+ assertEquals("key.country English", "COUNTRY en_US", resources.getMessage(Locale.ENGLISH, "key.country"));
+ assertEquals("key.country US", "COUNTRY en_US", resources.getMessage(Locale.US, "key.country"));
+ assertEquals("key.country ITALY", "COUNTRY en_US", resources.getMessage(Locale.ITALY, "key.country"));
+ assertEquals("key.country German", "COUNTRY en_US", resources.getMessage(Locale.GERMAN, "key.country"));
+ assertEquals("key.country GERMANY", "COUNTRY de_DE", resources.getMessage(Locale.GERMANY, "key.country"));
+
+ // Test Unique Keys with wrong Locale
+ assertEquals("Wrong Locale en only", null, resources.getMessage(Locale.GERMAN, "key.en"));
+ assertEquals("Wrong Locale en_US only", "en_US only", resources.getMessage(Locale.GERMANY, "key.en_US"));
+
+ // Run tests with common expected results
+ commonTests(resources);
+ }
+
+ /**
+ * Test JSTL compatible PropertyMessageResources behaviour
+ */
+ public void testJstlMode() {
+
+ Locale.setDefault(Locale.US);
+
+ // Create message resources - default Struts Behaviour
+ MessageResources resources = createMessageResources(FOO_RESOURCES, true, "JSTL");
+
+ // Test language (& default) only keys
+ assertEquals("key.lang FRANCE", "LANG default", resources.getMessage(Locale.FRANCE, "key.lang"));
+ assertEquals("key.lang English", "LANG en", resources.getMessage(Locale.ENGLISH, "key.lang"));
+ assertEquals("key.lang US", "LANG en", resources.getMessage(Locale.US, "key.lang"));
+ assertEquals("key.lang ITALY", "LANG default", resources.getMessage(Locale.ITALY, "key.lang"));
+ assertEquals("key.lang German", "LANG de", resources.getMessage(Locale.GERMAN, "key.lang"));
+ assertEquals("key.lang GERMANY", "LANG de", resources.getMessage(Locale.GERMANY, "key.lang"));
+
+ // Test country (& default) only keys
+ assertEquals("key.country FRANCE", "COUNTRY default", resources.getMessage(Locale.FRANCE, "key.country"));
+ assertEquals("key.country English", "COUNTRY default", resources.getMessage(Locale.ENGLISH, "key.country"));
+ assertEquals("key.country US", "COUNTRY en_US", resources.getMessage(Locale.US, "key.country"));
+ assertEquals("key.country ITALY", "COUNTRY default", resources.getMessage(Locale.ITALY, "key.country"));
+ assertEquals("key.country German", "COUNTRY default", resources.getMessage(Locale.GERMAN, "key.country"));
+ assertEquals("key.country GERMANY", "COUNTRY de_DE", resources.getMessage(Locale.GERMANY, "key.country"));
+
+ // Test Unique Keys with wrong Locale
+ assertEquals("Wrong Locale en only", null, resources.getMessage(Locale.GERMAN, "key.en"));
+ assertEquals("Wrong Locale en_US only", null, resources.getMessage(Locale.GERMANY, "key.en_US"));
+
+ // Run tests with common expected results
+ commonTests(resources);
+
+ }
+
+ /**
+ * Test "PropertyResourceBundle" compatible PropertyMessageResources behaviour
+ */
+ public void testResourceBundleMode() {
+
+ Locale.setDefault(Locale.US);
+
+ // Create message resources - default Struts Behaviour
+ MessageResources resources = createMessageResources(FOO_RESOURCES, true, "RESOURCE");
+
+ // Test language (& default) only keys
+ assertEquals("key.lang FRANCE", "LANG en", resources.getMessage(Locale.FRANCE, "key.lang"));
+ assertEquals("key.lang English", "LANG en", resources.getMessage(Locale.ENGLISH, "key.lang"));
+ assertEquals("key.lang US", "LANG en", resources.getMessage(Locale.US, "key.lang"));
+ assertEquals("key.lang ITALY", "LANG en", resources.getMessage(Locale.ITALY, "key.lang"));
+ assertEquals("key.lang German", "LANG de", resources.getMessage(Locale.GERMAN, "key.lang"));
+ assertEquals("key.lang GERMANY", "LANG de", resources.getMessage(Locale.GERMANY, "key.lang"));
+
+ // Test country (& default) only keys
+ assertEquals("key.country FRANCE", "COUNTRY en_US", resources.getMessage(Locale.FRANCE, "key.country"));
+ assertEquals("key.country English", "COUNTRY en_US", resources.getMessage(Locale.ENGLISH, "key.country"));
+ assertEquals("key.country US", "COUNTRY en_US", resources.getMessage(Locale.US, "key.country"));
+ assertEquals("key.country ITALY", "COUNTRY en_US", resources.getMessage(Locale.ITALY, "key.country"));
+ assertEquals("key.country German", "COUNTRY en_US", resources.getMessage(Locale.GERMAN, "key.country"));
+ assertEquals("key.country GERMANY", "COUNTRY de_DE", resources.getMessage(Locale.GERMANY, "key.country"));
+
+ // Test Unique Keys with wrong Locale
+ assertEquals("Wrong Locale en only", "en only", resources.getMessage(Locale.GERMAN, "key.en"));
+ assertEquals("Wrong Locale en_US only", "en_US only", resources.getMessage(Locale.GERMANY, "key.en_US"));
+
+ // Run tests with common expected results
+ commonTests(resources);
+ }
+
+ /**
+ * Tests with common expected results
+ */
+ public void commonTests(MessageResources resources) {
+
+ // Test "null" Locale
+ assertEquals("null Locale", "ALL default", resources.getMessage((Locale)null, "key.all"));
+
+ // Test Default only key with all Locales
+ assertEquals("Check default en", "default only", resources.getMessage(Locale.ENGLISH, "key.default"));
+ assertEquals("Check default en_US", "default only", resources.getMessage(Locale.US, "key.default"));
+ assertEquals("Check default de", "default only", resources.getMessage(Locale.GERMAN, "key.default"));
+ assertEquals("Check default de_DE", "default only", resources.getMessage(Locale.GERMANY, "key.default"));
+
+ // Test key in all locales
+ assertEquals("Check ALL en", "ALL en", resources.getMessage(Locale.ENGLISH, "key.all"));
+ assertEquals("Check ALL en_US", "ALL en_US", resources.getMessage(Locale.US, "key.all"));
+ assertEquals("Check ALL de", "ALL de", resources.getMessage(Locale.GERMAN, "key.all"));
+ assertEquals("Check ALL de_DE", "ALL de_DE", resources.getMessage(Locale.GERMANY, "key.all"));
+
+ // Test key unique to each locale
+ assertEquals("Check en only", "en only", resources.getMessage(Locale.ENGLISH, "key.en"));
+ assertEquals("Check en_US only", "en_US only", resources.getMessage(Locale.US, "key.en_US"));
+ assertEquals("Check de only", "de only", resources.getMessage(Locale.GERMAN, "key.de"));
+ assertEquals("Check de_DE only", "de_DE only", resources.getMessage(Locale.GERMANY, "key.de_DE"));
+
+ // Test unique keys with incorrect Locale
+ assertEquals("Missing default", null, resources.getMessage(Locale.ENGLISH, "missing"));
+ assertEquals("Missing de only", null, resources.getMessage(Locale.US, "key.de"));
+ assertEquals("Missing de_DE only", null, resources.getMessage(Locale.US, "key.de_DE"));
+ }
+
+ /**
+ * Create the PropertyMessageResources.
+ */
+ private MessageResources createMessageResources(String file, boolean returnNull, String mode) {
+ MessageResourcesConfig config = new MessageResourcesConfig();
+ config.setNull(returnNull);
+ if (mode != null) {
+ config.setProperty("mode", mode);
+ }
+ PropertyMessageResourcesFactory factory = new PropertyMessageResourcesFactory();
+ factory.setConfig(config);
+ factory.setReturnNull(returnNull);
+ return factory.createResources(file);
+ }
+}
Propchange: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/TestPropertyMessageResources.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: struts/struts1/trunk/core/src/test/java/org/apache/struts/util/TestPropertyMessageResources.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Modified: struts/struts1/trunk/src/site/xdoc/userGuide/configuration.xml
URL: http://svn.apache.org/viewvc/struts/struts1/trunk/src/site/xdoc/userGuide/configuration.xml?view=diff&rev=480549&r1=480548&r2=480549
==============================================================================
--- struts/struts1/trunk/src/site/xdoc/userGuide/configuration.xml (original)
+++ struts/struts1/trunk/src/site/xdoc/userGuide/configuration.xml Wed Nov 29 04:16:15 2006
@@ -446,6 +446,34 @@
'.
</p>
+ <p>
+ </p>
+
+ <p>
+ The default <code>PropertyMessageResources</code>
+ implementation can operate in one of three modes:
+ </p>
+
+ <ul>
+ <li><b>Default</b> - default, backwardly compatible,
+ Struts behaviour (i.e. the way its always worked).</li>
+ <li><b>JSTL</b> - compatible with how JSTL finds messages.</li>
+ <li><b>Resource</b> - compatible with how Java's
+ <code>PropertyResourceBundle</code> finds messages.</li>
+ </ul>
+
+ <p>
+ The <i>mode</i> can be configured in the struts-config.xml
+ (for more details see <code>PropertyMessageResources</code>
+ <a href="../struts-core/apidocs/org/apache/struts/util/PropertyMessageResources.html">
+ JavaDoc</a>):.
+ </p>
+ <source><![CDATA[
+<message-resources parameter="MyWebAppResources">
+ <set-property key="mode" value="JSTL"/>
+</message-resources>
+]]></source>
+
</subsection>
<a name="plugin_config"/>