You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2019/11/08 22:14:15 UTC
[tomcat] 01/02: Align with 8.5.x/9.0.x
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 661f583a14dd509e39d084dc50c7c94ffc7993fd
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Nov 8 22:10:46 2019 +0000
Align with 8.5.x/9.0.x
---
.../apache/catalina/tribes/util/StringManager.java | 177 +++++++++++++++++----
1 file changed, 145 insertions(+), 32 deletions(-)
diff --git a/java/org/apache/catalina/tribes/util/StringManager.java b/java/org/apache/catalina/tribes/util/StringManager.java
index 2204245..53caf03 100644
--- a/java/org/apache/catalina/tribes/util/StringManager.java
+++ b/java/org/apache/catalina/tribes/util/StringManager.java
@@ -18,11 +18,15 @@
package org.apache.catalina.tribes.util;
import java.text.MessageFormat;
+import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.LinkedHashMap;
import java.util.Locale;
+import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
+
/**
* An internationalization / localization helper class which reduces
* the bother of handling ResourceBundles and takes care of the
@@ -49,11 +53,14 @@ import java.util.ResourceBundle;
*/
public class StringManager {
+ private static int LOCALE_CACHE_SIZE = 10;
+
/**
* The ResourceBundle for this StringManager.
*/
- private ResourceBundle bundle;
- private Locale locale;
+ private final ResourceBundle bundle;
+ private final Locale locale;
+
/**
* Creates a new StringManager for a given package. This is a
@@ -63,53 +70,67 @@ public class StringManager {
*
* @param packageName Name of package to create StringManager for.
*/
- private StringManager(String packageName) {
+ private StringManager(String packageName, Locale locale) {
String bundleName = packageName + ".LocalStrings";
+ ResourceBundle bnd = null;
try {
- bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());
- } catch( MissingResourceException ex ) {
+ bnd = ResourceBundle.getBundle(bundleName, locale);
+ } catch (MissingResourceException ex) {
// Try from the current loader (that's the case for trusted apps)
// Should only be required if using a TC5 style classloader structure
// where common != shared != server
ClassLoader cl = Thread.currentThread().getContextClassLoader();
- if( cl != null ) {
+ if (cl != null) {
try {
- bundle = ResourceBundle.getBundle(
- bundleName, Locale.getDefault(), cl);
- } catch(MissingResourceException ex2) {
+ bnd = ResourceBundle.getBundle(bundleName, locale, cl);
+ } catch (MissingResourceException ex2) {
// Ignore
}
}
}
+ bundle = bnd;
// Get the actual locale, which may be different from the requested one
if (bundle != null) {
- locale = bundle.getLocale();
+ Locale bundleLocale = bundle.getLocale();
+ if (bundleLocale.equals(Locale.ROOT)) {
+ this.locale = Locale.ENGLISH;
+ } else {
+ this.locale = bundleLocale;
+ }
+ } else {
+ this.locale = null;
}
}
- /**
- Get a string from the underlying resource bundle or return
- null if the String is not found.
- @param key to desired resource String
- @return resource String matching <i>key</i> from underlying
- bundle or null if not found.
- @throws IllegalArgumentException if <i>key</i> is null.
+ /**
+ * Get a string from the underlying resource bundle or return null if the
+ * String is not found.
+ *
+ * @param key to desired resource String
+ *
+ * @return resource String matching <i>key</i> from underlying bundle or
+ * null if not found.
+ *
+ * @throws IllegalArgumentException if <i>key</i> is null
*/
public String getString(String key) {
- if(key == null){
+ if (key == null){
String msg = "key may not have a null value";
-
throw new IllegalArgumentException(msg);
}
String str = null;
try {
- str = bundle.getString(key);
- } catch(MissingResourceException mre) {
+ // Avoid NPE if bundle is null and treat it like an MRE
+ if (bundle != null) {
+ str = bundle.getString(key);
+ }
+ } catch (MissingResourceException mre) {
//bad: shouldn't mask an exception the following way:
- // str = "[cannot find message associated with key '" + key + "' due to " + mre + "]";
+ // str = "[cannot find message associated with key '" + key +
+ // "' due to " + mre + "]";
// because it hides the fact that the String was missing
// from the calling code.
//good: could just throw the exception (or wrap it in another)
@@ -124,12 +145,15 @@ public class StringManager {
return str;
}
+
/**
* Get a string from the underlying resource bundle and format
* it with the given set of arguments.
*
- * @param key
- * @param args
+ * @param key The key for the required message
+ * @param args The values to insert into the message
+ *
+ * @return The requested string formatted with the provided arguments
*/
public String getString(final String key, final Object... args) {
String value = getString(key);
@@ -142,27 +166,116 @@ public class StringManager {
return mf.format(args, new StringBuffer(), null).toString();
}
+
+ /**
+ * Identify the Locale this StringManager is associated with
+ *
+ * @return The Locale associated with this instance
+ */
+ public Locale getLocale() {
+ return locale;
+ }
+
+
// --------------------------------------------------------------
// STATIC SUPPORT METHODS
// --------------------------------------------------------------
- private static Hashtable<String, StringManager> managers =
- new Hashtable<String, StringManager>();
+ private static final Map<String, Map<Locale,StringManager>> managers =
+ new Hashtable<String, Map<Locale, StringManager>>();
+
/**
- * Get the StringManager for a particular package. If a manager for
- * a package already exists, it will be reused, else a new
+ * The StringManager will be returned for the package in which the class is
+ * located. If a manager for that package already exists, it will be reused,
+ * else a new StringManager will be created and returned.
+ *
+ * @param clazz The class for which to retrieve the StringManager
+ *
+ * @return The StringManager for the given class.
+ */
+ public static final StringManager getManager(Class<?> clazz) {
+ return getManager(clazz.getPackage().getName());
+ }
+
+
+ /**
+ * If a manager for a package already exists, it will be reused, else a new
* StringManager will be created and returned.
*
* @param packageName The package name
+ *
+ * @return The StringManager for the given package.
+ */
+ public static final StringManager getManager(String packageName) {
+ return getManager(packageName, Locale.getDefault());
+ }
+
+
+ /**
+ * If a manager for a package/Locale combination already exists, it will be
+ * reused, else a new StringManager will be created and returned.
+ *
+ * @param packageName The package name
+ * @param locale The Locale
+ *
+ * @return The StringManager for a particular package and Locale
*/
- public static final synchronized StringManager getManager(String packageName) {
- StringManager mgr = managers.get(packageName);
+ public static final synchronized StringManager getManager(
+ String packageName, Locale locale) {
+
+ Map<Locale,StringManager> map = managers.get(packageName);
+ if (map == null) {
+ /*
+ * Don't want the HashMap to be expanded beyond LOCALE_CACHE_SIZE.
+ * Expansion occurs when size() exceeds capacity. Therefore keep
+ * size at or below capacity.
+ * removeEldestEntry() executes after insertion therefore the test
+ * for removal needs to use one less than the maximum desired size
+ *
+ */
+ map = new LinkedHashMap<Locale,StringManager>(LOCALE_CACHE_SIZE, 1, true) {
+ private static final long serialVersionUID = 1L;
+ @Override
+ protected boolean removeEldestEntry(
+ Map.Entry<Locale,StringManager> eldest) {
+ if (size() > (LOCALE_CACHE_SIZE - 1)) {
+ return true;
+ }
+ return false;
+ }
+ };
+ managers.put(packageName, map);
+ }
+
+ StringManager mgr = map.get(locale);
if (mgr == null) {
- mgr = new StringManager(packageName);
- managers.put(packageName, mgr);
+ mgr = new StringManager(packageName, locale);
+ map.put(locale, mgr);
}
return mgr;
}
+
+ /**
+ * Retrieve the StringManager for a list of Locales. The first StringManager
+ * found will be returned.
+ *
+ * @param packageName The package for which the StringManager is required
+ * @param requestedLocales the list of Locales
+ *
+ * @return the found StringManager or the default StringManager
+ */
+ public static StringManager getManager(String packageName,
+ Enumeration<Locale> requestedLocales) {
+ while (requestedLocales.hasMoreElements()) {
+ Locale locale = requestedLocales.nextElement();
+ StringManager result = getManager(packageName, locale);
+ if (result.getLocale().equals(locale)) {
+ return result;
+ }
+ }
+ // Return the default
+ return getManager(packageName);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org