You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by kf...@apache.org on 2015/05/21 11:46:45 UTC

svn commit: r1680783 - /tomcat/trunk/java/org/apache/catalina/tribes/util/StringManager.java

Author: kfujino
Date: Thu May 21 09:46:45 2015
New Revision: 1680783

URL: http://svn.apache.org/r1680783
Log:
Align tribes.util.StringManager implementation with tomcat.util.StringManager implementation.

Modified:
    tomcat/trunk/java/org/apache/catalina/tribes/util/StringManager.java

Modified: tomcat/trunk/java/org/apache/catalina/tribes/util/StringManager.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/tribes/util/StringManager.java?rev=1680783&r1=1680782&r2=1680783&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/tribes/util/StringManager.java (original)
+++ tomcat/trunk/java/org/apache/catalina/tribes/util/StringManager.java Thu May 21 09:46:45 2015
@@ -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,12 +53,15 @@ import java.util.ResourceBundle;
  */
 public class StringManager {
 
+    private static int LOCALE_CACHE_SIZE = 10;
+
     /**
      * The ResourceBundle for this StringManager.
      */
     private final ResourceBundle bundle;
     private final Locale locale;
 
+
     /**
      * Creates a new StringManager for a given package. This is a
      * private method and all access to it is arbitrated by the
@@ -63,58 +70,67 @@ public class StringManager {
      *
      * @param packageName Name of package to create StringManager for.
      */
-    private StringManager(String packageName) {
-        ResourceBundle b = null;
-
+    private StringManager(String packageName, Locale locale) {
         String bundleName = packageName + ".LocalStrings";
+        ResourceBundle bnd = null;
         try {
-            b = 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 {
-                    b = 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
-        this.bundle = b;
         if (bundle != null) {
-            locale = bundle.getLocale();
+            Locale bundleLocale = bundle.getLocale();
+            if (bundleLocale.equals(Locale.ROOT)) {
+                this.locale = Locale.ENGLISH;
+            } else {
+                this.locale = bundleLocale;
+            }
         } else {
-            locale = null;
+            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)
@@ -129,12 +145,13 @@ 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
      */
     public String getString(final String key, final Object... args) {
         String value = getString(key);
@@ -147,12 +164,35 @@ public class StringManager {
         return mf.format(args, new StringBuffer(), null).toString();
     }
 
+
+    /**
+     * Identify the Locale this StringManager is associated with
+     */
+    public Locale getLocale() {
+        return locale;
+    }
+
+
     // --------------------------------------------------------------
     // STATIC SUPPORT METHODS
     // --------------------------------------------------------------
 
-    private static final Hashtable<String, StringManager> managers =
-        new Hashtable<>();
+    private static final Map<String, Map<Locale,StringManager>> managers =
+            new Hashtable<>();
+
+
+    /**
+     * Get the StringManager for a given class. 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
+     */
+    public static final StringManager getManager(Class<?> clazz) {
+        return getManager(clazz.getPackage().getName());
+    }
+
 
     /**
      * Get the StringManager for a particular package. If a manager for
@@ -161,13 +201,73 @@ public class StringManager {
      *
      * @param packageName The package name
      */
-    public static final synchronized StringManager getManager(String packageName) {
-        StringManager mgr = managers.get(packageName);
+    public static final StringManager getManager(String packageName) {
+        return getManager(packageName, Locale.getDefault());
+    }
+
+
+    /**
+     * Get the StringManager for a particular package and Locale. 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
+     */
+    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 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