| /* |
| * 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.axis2.i18n; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.text.MessageFormat; |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| import java.util.Locale; |
| import java.util.MissingResourceException; |
| import java.util.Properties; |
| |
| /** |
| * CURRENTLY NOT USED |
| * KEEPING FOR REFERENCE 9/19/2002 |
| * <p/> |
| * <p>Wrapper class for resource bundles. Property files are used to store |
| * resource strings, which are the only types of resources available. |
| * Property files can inherit properties from other files so that |
| * a base property file can be used and a small number of properties |
| * can be over-ridden by another property file. For example you may |
| * create an english version of a resource file named "resource.properties". |
| * You then decide that the British English version of all of the properties |
| * except one are the same, so there is no need to redefine all of the |
| * properties in "resource_en_GB", just the one that is different.</p> |
| * <p>The property file lookup searches for classes with various suffixes |
| * on the basis if the desired local and the current default local |
| * (as returned by Local.getDefault()). As property files are found the |
| * property values are merged so that inheritance is preserved.</p> |
| * <p>The order of searching is:</p> |
| * <dir> |
| * basename + "_" + langage + "_" + country + "_" + variant |
| * basename + "_" + langage + "_" + country |
| * basename + "_" + langage |
| * basename + "_" + defaultLanguage + "_" + defaultCountry + "_" + defaultVariant |
| * basename + "_" + defaultLanguage + "_" + defaultCountry |
| * basename + "_" + defaultLanguage |
| * basename |
| * </dir> |
| * <p>The basename is the name of the property file without the ".properties" |
| * extension.</p> |
| * <p>Properties will be cached for performance.<p> |
| * <p>Property values stored in the property files can also contain dynamic |
| * variables. Any dynamic variable defined in PropertiesUtil.getVariableValue() |
| * can be used (such as {date}), as well as arguments in the form {0}, {1}, etc. |
| * Argument values are specified in the various overloaded getString() methods.</p> |
| */ |
| public class RB { |
| // The static cache of properties. The key is the basename + the local + |
| // the default local and the element is the Properties object containing |
| // the resources |
| static Hashtable propertyCache = new Hashtable(); |
| |
| // The default base name |
| public static final String BASE_NAME = "resource"; |
| |
| // The property file extension |
| public static final String PROPERTY_EXT = ".properties"; |
| |
| // The name of the current base property file (with extension) |
| protected String basePropertyFileName; |
| |
| // The properties for the current resource bundle |
| protected Properties resourceProperties; |
| |
| /** |
| * Construct a new RB |
| * |
| * @param name The name of the property file without the ".properties" extension |
| */ |
| public RB(String name) throws MissingResourceException { |
| this(null, name, null); |
| } |
| |
| /** |
| * Construct a new RB |
| * |
| * @param caller The calling object. This is used to get the package name |
| * to further construct the basename as well as to get the proper ClassLoader |
| * @param name The name of the property file without the ".properties" extension |
| */ |
| public RB(Object caller, String name) throws MissingResourceException { |
| this(caller, name, null); |
| } |
| |
| /** |
| * Construct a new RB |
| * |
| * @param caller The calling object. This is used to get the package name |
| * to further construct the basename as well as to get the proper ClassLoader |
| * @param name The name of the property file without the ".properties" extension |
| * @param locale The locale |
| */ |
| public RB(Object caller, String name, Locale locale) throws MissingResourceException { |
| ClassLoader cl = null; |
| |
| if (caller != null) { |
| |
| Class c; |
| if (caller instanceof Class) { |
| c = (Class) caller; |
| } else { |
| c = caller.getClass(); |
| } |
| |
| // Get the appropriate class loader |
| cl = c.getClassLoader(); |
| |
| if (name.indexOf("/") == -1) { |
| |
| // Create the full basename only if not given |
| String fullName = c.getName(); |
| |
| int pos = fullName.lastIndexOf("."); |
| if (pos > 0) { |
| name = fullName.substring(0, pos + 1).replace('.', '/') + name; |
| } |
| } |
| } else { |
| // Try the shared default properties file... |
| if (name.indexOf("/") == -1) { |
| name = "org/apache/axis2/default-resource"; |
| } |
| } |
| |
| Locale defaultLocale = Locale.getDefault(); |
| |
| // If the locale given is the same as the default locale, ignore it |
| if (locale != null) { |
| if (locale.equals(defaultLocale)) { |
| locale = null; |
| } |
| } |
| |
| // Load the properties. If no property files exist then a |
| // MissingResourceException will be thrown |
| loadProperties(name, cl, locale, defaultLocale); |
| } |
| |
| /** |
| * Gets a string message from the resource bundle for the given key |
| * |
| * @param key The resource key |
| * @return The message |
| */ |
| public String getString(String key) throws MissingResourceException { |
| return getString(key, (Object[]) null); |
| } |
| |
| /** |
| * <p>Gets a string message from the resource bundle for the given key. The |
| * message may contain variables that will be substituted with the given |
| * arguments. Variables have the format:</p> |
| * <dir> |
| * This message has two variables: {0} and {1} |
| * </dir> |
| * |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @return The message |
| */ |
| public String getString(String key, Object arg0) throws MissingResourceException { |
| Object[] o = new Object[1]; |
| o[0] = arg0; |
| return getString(key, o); |
| } |
| |
| /** |
| * <p>Gets a string message from the resource bundle for the given key. The |
| * message may contain variables that will be substituted with the given |
| * arguments. Variables have the format:</p> |
| * <dir> |
| * This message has two variables: {0} and {1} |
| * </dir> |
| * |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @param arg1 The argument to place in variable {1} |
| * @return The message |
| */ |
| public String getString(String key, Object arg0, Object arg1) throws MissingResourceException { |
| Object[] o = new Object[2]; |
| o[0] = arg0; |
| o[1] = arg1; |
| return getString(key, o); |
| } |
| |
| /** |
| * <p>Gets a string message from the resource bundle for the given key. The |
| * message may contain variables that will be substituted with the given |
| * arguments. Variables have the format:</p> |
| * <dir> |
| * This message has two variables: {0} and {1} |
| * </dir> |
| * |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @param arg1 The argument to place in variable {1} |
| * @param arg2 The argument to place in variable {1} |
| * @return The message |
| */ |
| public String getString(String key, Object arg0, Object arg1, Object arg2) |
| throws MissingResourceException { |
| Object[] o = new Object[3]; |
| o[0] = arg0; |
| o[1] = arg1; |
| o[2] = arg2; |
| return getString(key, o); |
| } |
| |
| /** |
| * <p>Gets a string message from the resource bundle for the given key. The |
| * message may contain variables that will be substituted with the given |
| * arguments. Variables have the format:</p> |
| * <dir> |
| * This message has two variables: {0} and {1} |
| * </dir> |
| * |
| * @param key The resource key |
| * @param array An array of objects to place in corresponding variables |
| * @return The message |
| */ |
| public String getString(String key, Object[] array) throws MissingResourceException { |
| String msg = null; |
| if (resourceProperties != null) { |
| msg = resourceProperties.getProperty(key); |
| } |
| |
| if (msg == null) { |
| throw new MissingResourceException("Cannot find resource key \"" + key + |
| "\" in base name " + basePropertyFileName, |
| basePropertyFileName, key); |
| } |
| |
| msg = MessageFormat.format(msg, array); |
| return msg; |
| } |
| |
| protected void loadProperties(String basename, ClassLoader loader, Locale locale, |
| Locale defaultLocale) |
| throws MissingResourceException { |
| // Check the cache first |
| String loaderName = ""; |
| if (loader != null) { |
| loaderName = ":" + loader.hashCode(); |
| } |
| String cacheKey = basename + ":" + locale + ":" + defaultLocale + loaderName; |
| Properties p = (Properties) propertyCache.get(cacheKey); |
| basePropertyFileName = basename + PROPERTY_EXT; |
| |
| if (p == null) { |
| // The properties were not found in the cache. Search the given locale |
| // first |
| if (locale != null) { |
| p = loadProperties(basename, loader, locale, p); |
| } |
| |
| // Search the default locale |
| if (defaultLocale != null) { |
| p = loadProperties(basename, loader, defaultLocale, p); |
| } |
| |
| // Search for the basename |
| p = merge(p, loadProperties(basePropertyFileName, loader)); |
| |
| if (p == null) { |
| throw new MissingResourceException("Cannot find resource for base name " + |
| basePropertyFileName, basePropertyFileName, ""); |
| } |
| |
| // Cache the properties |
| propertyCache.put(cacheKey, p); |
| |
| } |
| |
| resourceProperties = p; |
| } |
| |
| protected Properties loadProperties(String basename, ClassLoader loader, Locale locale, |
| Properties props) { |
| |
| String language = locale.getLanguage(); |
| String country = locale.getCountry(); |
| String variant = locale.getVariant(); |
| if (variant != null) { |
| if (variant.trim().length() == 0) { |
| variant = null; |
| } |
| } |
| |
| if (language != null) { |
| |
| if (country != null) { |
| |
| if (variant != null) { |
| props = merge(props, loadProperties( |
| basename + "_" + language + "_" + country + "_" + variant + |
| PROPERTY_EXT, loader)); |
| } |
| props = merge(props, loadProperties(basename + "_" + language + "_" + country + |
| PROPERTY_EXT, loader)); |
| } |
| props = merge(props, loadProperties(basename + "_" + language + PROPERTY_EXT, loader)); |
| } |
| return props; |
| } |
| |
| protected Properties loadProperties(String resname, ClassLoader loader) { |
| Properties props = null; |
| |
| // Attempt to open and load the properties |
| InputStream in = null; |
| try { |
| if (loader != null) { |
| in = loader.getResourceAsStream(resname); |
| } |
| |
| // Either we're using the system class loader or we didn't find the |
| // resource using the given class loader |
| if (in == null) { |
| in = ClassLoader.getSystemResourceAsStream(resname); |
| } |
| if (in != null) { |
| props = new Properties(); |
| try { |
| props.load(in); |
| } catch (IOException ex) { |
| // On error, clear the props |
| props = null; |
| } |
| } |
| } finally { |
| if (in != null) { |
| try { |
| in.close(); |
| } catch (Exception ex) { |
| // Ignore error on close |
| } |
| } |
| } |
| return props; |
| } |
| |
| /** |
| * Merge two Properties objects |
| */ |
| protected Properties merge(Properties p1, Properties p2) { |
| if ((p1 == null) && |
| (p2 == null)) { |
| return null; |
| } else if (p1 == null) { |
| return p2; |
| } else if (p2 == null) { |
| return p1; |
| } |
| |
| // Now merge. p1 takes precedence |
| Enumeration enumeration = p2.keys(); |
| while (enumeration.hasMoreElements()) { |
| String key = (String) enumeration.nextElement(); |
| if (p1.getProperty(key) == null) { |
| p1.put(key, p2.getProperty(key)); |
| } |
| } |
| |
| return p1; |
| } |
| |
| /** |
| * Get the underlying properties |
| */ |
| public Properties getProperties() { |
| return resourceProperties; |
| } |
| |
| // STATIC ACCESSORS |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param key The resource key |
| * @return The formatted message |
| */ |
| public static String getString(Object caller, String key) |
| throws MissingResourceException { |
| return getMessage(caller, BASE_NAME, null, key, null); |
| } |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @return The formatted message |
| */ |
| public static String getString(Object caller, String key, Object arg0) |
| throws MissingResourceException { |
| Object[] o = new Object[1]; |
| o[0] = arg0; |
| return getMessage(caller, BASE_NAME, null, key, o); |
| } |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @param arg1 The argument to place in variable {1} |
| * @return The formatted message |
| */ |
| public static String getString(Object caller, String key, Object arg0, Object arg1) |
| throws MissingResourceException { |
| Object[] o = new Object[2]; |
| o[0] = arg0; |
| o[1] = arg1; |
| return getMessage(caller, BASE_NAME, null, key, o); |
| } |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @param arg1 The argument to place in variable {1} |
| * @param arg2 The argument to place in variable {2} |
| * @return The formatted message |
| */ |
| public static String getString(Object caller, String key, Object arg0, Object arg1, Object arg2) |
| throws MissingResourceException { |
| Object[] o = new Object[3]; |
| o[0] = arg0; |
| o[1] = arg1; |
| o[2] = arg2; |
| return getMessage(caller, BASE_NAME, null, key, o); |
| } |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @param arg1 The argument to place in variable {1} |
| * @param arg2 The argument to place in variable {2} |
| * @param arg3 The argument to place in variable {3} |
| * @return The formatted message |
| */ |
| public static String getString(Object caller, String key, Object arg0, Object arg1, Object arg2, |
| Object arg3) |
| throws MissingResourceException { |
| Object[] o = new Object[4]; |
| o[0] = arg0; |
| o[1] = arg1; |
| o[2] = arg2; |
| o[3] = arg3; |
| return getMessage(caller, BASE_NAME, null, key, o); |
| } |
| |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @param arg1 The argument to place in variable {1} |
| * @param arg2 The argument to place in variable {2} |
| * @param arg3 The argument to place in variable {3} |
| * @param arg4 The argument to place in variable {4} |
| * @return Returns the formatted message. |
| */ |
| public static String getString(Object caller, String key, Object arg0, Object arg1, Object arg2, |
| Object arg3, Object arg4) |
| throws MissingResourceException { |
| Object[] o = new Object[5]; |
| o[0] = arg0; |
| o[1] = arg1; |
| o[2] = arg2; |
| o[3] = arg3; |
| o[4] = arg4; |
| return getMessage(caller, BASE_NAME, null, key, o); |
| } |
| |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param key The resource key |
| * @param args An array of objects to place in corresponding variables |
| * @return Returns the formatted message. |
| */ |
| public static String getString(Object caller, String key, Object[] args) |
| throws MissingResourceException { |
| return getMessage(caller, BASE_NAME, null, key, args); |
| } |
| |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param locale The locale |
| * @param key The resource key |
| * @return The formatted message |
| */ |
| public static String getString(Object caller, Locale locale, String key) |
| throws MissingResourceException { |
| return getMessage(caller, BASE_NAME, locale, key, null); |
| } |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param locale The locale |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @return The formatted message |
| */ |
| public static String getString(Object caller, Locale locale, String key, Object arg0) |
| throws MissingResourceException { |
| Object[] o = new Object[1]; |
| o[0] = arg0; |
| return getMessage(caller, BASE_NAME, locale, key, o); |
| } |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param locale The locale |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @param arg1 The argument to place in variable {1} |
| * @return The formatted message |
| */ |
| public static String getString(Object caller, Locale locale, String key, Object arg0, |
| Object arg1) |
| throws MissingResourceException { |
| Object[] o = new Object[2]; |
| o[0] = arg0; |
| o[1] = arg1; |
| return getMessage(caller, BASE_NAME, locale, key, o); |
| } |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param locale The locale |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @param arg1 The argument to place in variable {1} |
| * @param arg2 The argument to place in variable {2} |
| * @return The formatted message |
| */ |
| public static String getString(Object caller, Locale locale, String key, Object arg0, |
| Object arg1, Object arg2) |
| throws MissingResourceException { |
| Object[] o = new Object[3]; |
| o[0] = arg0; |
| o[1] = arg1; |
| o[2] = arg2; |
| return getMessage(caller, BASE_NAME, locale, key, o); |
| } |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param locale The locale |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @param arg1 The argument to place in variable {1} |
| * @param arg2 The argument to place in variable {2} |
| * @param arg3 The argument to place in variable {3} |
| * @return The formatted message |
| */ |
| public static String getString(Object caller, Locale locale, String key, Object arg0, |
| Object arg1, Object arg2, Object arg3) |
| throws MissingResourceException { |
| Object[] o = new Object[4]; |
| o[0] = arg0; |
| o[1] = arg1; |
| o[2] = arg2; |
| o[3] = arg3; |
| return getMessage(caller, BASE_NAME, locale, key, o); |
| } |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param locale The locale |
| * @param key The resource key |
| * @param arg0 The argument to place in variable {0} |
| * @param arg1 The argument to place in variable {1} |
| * @param arg2 The argument to place in variable {2} |
| * @param arg3 The argument to place in variable {3} |
| * @return Returns the formatted message. |
| */ |
| public static String getString(Object caller, Locale locale, String key, Object arg0, |
| Object arg1, Object arg2, Object arg3, Object arg4) |
| throws MissingResourceException { |
| Object[] o = new Object[5]; |
| o[0] = arg0; |
| o[1] = arg1; |
| o[2] = arg2; |
| o[3] = arg3; |
| o[4] = arg4; |
| return getMessage(caller, BASE_NAME, locale, key, o); |
| } |
| |
| /** |
| * Get a message from resource.properties from the package of the given object. |
| * |
| * @param caller The calling object, used to get the package name and class loader |
| * @param locale The locale |
| * @param key The resource key |
| * @param args An array of objects to place in corresponding variables |
| * @return Returns the formatted message. |
| */ |
| public static String getString(Object caller, Locale locale, String key, Object[] args) |
| throws MissingResourceException { |
| return getMessage(caller, BASE_NAME, locale, key, args); |
| } |
| |
| // Workhorse that does the resource loading and key lookup |
| public static String getMessage(Object caller, String basename, Locale locale, String key, |
| Object[] args) |
| throws MissingResourceException { |
| String msg = null; |
| MissingResourceException firstEx = null; |
| String fullName = null; |
| Class curClass = null; |
| boolean didNull = false; |
| |
| if (caller != null) { |
| if (caller instanceof Class) { |
| curClass = (Class) caller; |
| } else { |
| curClass = caller.getClass(); |
| } |
| } |
| |
| while (msg == null) { |
| |
| // Get the full name of the resource |
| if (curClass != null) { |
| |
| // Create the full basename |
| String pkgName = curClass.getName(); |
| |
| int pos = pkgName.lastIndexOf("."); |
| if (pos > 0) { |
| fullName = pkgName.substring(0, pos + 1).replace('.', '/') + basename; |
| } else { |
| fullName = basename; |
| } |
| } else { |
| fullName = basename; |
| } |
| |
| try { |
| RB rb = new RB(caller, fullName, locale); |
| msg = rb.getString(key, args); |
| } catch (MissingResourceException ex) { |
| if (curClass == null) { |
| throw ex; |
| } |
| |
| // Save the first exception |
| if (firstEx == null) { |
| firstEx = ex; |
| } |
| |
| // Get the superclass |
| curClass = curClass.getSuperclass(); |
| if (curClass == null) { |
| if (didNull) { |
| throw firstEx; |
| } |
| didNull = true; |
| caller = null; |
| } else { |
| String cname = curClass.getName(); |
| if (cname.startsWith("java.") || |
| cname.startsWith("javax.")) { |
| if (didNull) { |
| throw firstEx; |
| } |
| didNull = true; |
| caller = null; |
| curClass = null; |
| } |
| } |
| } |
| |
| } |
| return msg; |
| } |
| |
| /** |
| * Clears the internal cache. |
| */ |
| public static void clearCache() { |
| propertyCache.clear(); |
| } |
| } |