Save This Page
Home » jdo2-util-2.3-ea-src » org.apache.jdo.util » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software 
   12    * distributed under the License is distributed on an "AS IS" BASIS, 
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
   14    * See the License for the specific language governing permissions and 
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.jdo.util;
   19   
   20   import java.util;
   21   import java.text.MessageFormat;
   22   import java.security.AccessController;
   23   import java.security.PrivilegedAction;
   24   
   25   /** Helper class for constructing messages from bundles.  The intended usage
   26    * of this class is to construct a new instance bound to a bundle, as in
   27    * <P>
   28    * <code>I18NHelper msg = I18NHelper.getInstance("org.apache.jdo.util.jdo.Bundle");</code>
   29    * <P>
   30    * This call uses the class loader that loaded the I18NHelper class to find
   31    * the specified Bundle. The class provides two overloaded getInstance
   32    * methods allowing to specify a different class loader: 
   33    * {@link #getInstance(Class cls)} looks for a bundle
   34    * called "Bundle.properties" located in the package of the specified class 
   35    * object and {@link #getInstance(String bundleName,ClassLoader loader)} 
   36    * uses the specified class loader to find the bundle.
   37    * <P>
   38    * Subsequently, instance methods can be used to format message strings 
   39    * using the text from the bundle, as in 
   40    * <P>
   41    * <code>throw new JDOFatalInternalException (msg.msg("ERR_NoMetadata", cls.getName()));</code>
   42    * @since 1.0.1
   43    * @version 1.1
   44    */        
   45   public class I18NHelper {
   46   
   47       /** Bundles that have already been loaded 
   48        */
   49       private static Hashtable    bundles = new Hashtable();
   50       
   51       /** Helper instances that have already been created 
   52        */
   53       private static Hashtable    helpers = new Hashtable();
   54       
   55       /** The default locale for this VM.
   56        */
   57       private static Locale       locale = Locale.getDefault();
   58   
   59       /** The name of the bundle used by this instance of the helper.
   60        */
   61       private final String        bundleName;
   62   
   63       /** The bundle used by this instance of the helper.
   64        */
   65       private ResourceBundle      bundle = null;
   66   
   67       /** Throwable if ResourceBundle couldn't be loaded
   68        */
   69       private Throwable           failure = null;
   70   
   71       /** The unqualified standard name of a bundle. */
   72       private static final String bundleSuffix = ".Bundle";    // NOI18N
   73   
   74       /** Constructor */
   75       private I18NHelper() {
   76           this.bundleName = null;
   77       }
   78   
   79       /** Constructor for an instance bound to a bundle.
   80        * @param bundleName the name of the resource bundle
   81        * @param loader the class loader from which to load the resource
   82        * bundle
   83        */
   84       private I18NHelper (String bundleName, ClassLoader loader) {
   85           this.bundleName = bundleName;
   86           try {
   87               bundle = loadBundle (bundleName, loader);
   88           }
   89           catch (Throwable e) {
   90               failure = e;
   91           }
   92       }
   93       
   94       /** An instance bound to a bundle. This method uses the current class 
   95        * loader to find the bundle.
   96        * @param bundleName the name of the bundle
   97        * @return the helper instance bound to the bundle
   98        */
   99       public static I18NHelper getInstance (String bundleName) {
  100           return getInstance (bundleName, I18NHelper.class.getClassLoader());
  101       }
  102   
  103       /** An instance bound to a bundle. This method figures out the bundle name
  104        * for the class object's package and uses the class' class loader to
  105        * find the bundle. Note, the specified class object must not be
  106        * <code>null</code>.
  107        * @param cls the class object from which to load the resource bundle
  108        * @return the helper instance bound to the bundle
  109        */
  110       public static I18NHelper getInstance (final Class cls) {
  111           ClassLoader classLoader = (ClassLoader) AccessController.doPrivileged (
  112               new PrivilegedAction () {
  113                   public Object run () {
  114                       return cls.getClassLoader();
  115                   }
  116               }
  117               );
  118           String bundle = getPackageName (cls.getName()) + bundleSuffix;
  119           return getInstance (bundle, classLoader);
  120       }
  121   
  122       /** An instance bound to a bundle. This method uses the specified class
  123        * loader to find the bundle. Note, the specified class loader must not
  124        * be <code>null</code>.
  125        * @param bundleName the name of the bundle
  126        * @param loader the class loader from which to load the resource
  127        * bundle
  128        * @return the helper instance bound to the bundle
  129        */
  130       public static I18NHelper getInstance (String bundleName, 
  131                                             ClassLoader loader) {
  132           I18NHelper helper = (I18NHelper) helpers.get (bundleName);
  133           if (helper != null) {
  134               return helper;
  135           }
  136           helper = new I18NHelper(bundleName, loader);
  137           helpers.put (bundleName, helper);
  138           // if two threads simultaneously create the same helper, return the first
  139           // one to be put into the Hashtable.  The other will be garbage collected.
  140           return (I18NHelper) helpers.get (bundleName);
  141       }
  142   
  143       /** Message formatter
  144        * @param messageKey the message key
  145        * @return the resolved message text
  146        */
  147       public String msg (String messageKey) {
  148           assertBundle (messageKey);
  149           return getMessage (bundle, messageKey);
  150       }
  151   
  152       /** Message formatter
  153        * @param messageKey the message key
  154        * @param arg1 the first argument
  155        * @return the resolved message text
  156        */
  157       public String msg (String messageKey, Object arg1) {
  158           assertBundle (messageKey);
  159           return getMessage (bundle, messageKey, arg1);
  160       }
  161   
  162       /** Message formatter
  163        * @param messageKey the message key
  164        * @param arg1 the first argument
  165        * @param arg2 the second argument
  166        * @return the resolved message text
  167        */
  168       public String msg (String messageKey, Object arg1, Object arg2) {
  169           assertBundle (messageKey);
  170           return getMessage (bundle, messageKey, arg1, arg2);
  171       }
  172   
  173       /** Message formatter
  174        * @param messageKey the message key
  175        * @param arg1 the first argument
  176        * @param arg2 the second argument
  177        * @param arg3 the third argument
  178        * @return the resolved message text
  179        */
  180       public String msg (String messageKey, Object arg1, Object arg2, Object arg3) {
  181           assertBundle (messageKey);
  182           return getMessage (bundle, messageKey, arg1, arg2, arg3);
  183       }
  184   
  185       /** Message formatter
  186        * @param messageKey the message key
  187        * @param args the array of arguments
  188        * @return the resolved message text
  189        */
  190       public String msg (String messageKey, Object[] args) {
  191           assertBundle (messageKey);
  192           return getMessage (bundle, messageKey, args);
  193       }
  194   
  195       /** Message formatter
  196        * @param messageKey the message key
  197        * @param arg the argument
  198        * @return the resolved message text
  199        */
  200       public String msg (String messageKey, int arg) {
  201           assertBundle (messageKey);
  202           return getMessage(bundle, messageKey, arg);
  203       }
  204       
  205       /** Message formatter
  206        * @param messageKey the message key
  207        * @param arg the argument
  208        * @return the resolved message text
  209        */
  210       public String msg (String messageKey, boolean arg) {
  211           assertBundle (messageKey);
  212           return getMessage(bundle, messageKey, arg);
  213       }
  214       
  215       /** Returns the resource bundle used by this I18NHelper.
  216        * @return the associated resource bundle
  217        * @since 1.1
  218        */
  219       public ResourceBundle getResourceBundle () {
  220           assertBundle ();
  221           return bundle;
  222       }
  223       
  224       //========= Internal helper methods ==========
  225   
  226       /**
  227        * Load ResourceBundle by bundle name
  228        * @param bundleName the name of the bundle
  229        * @param loader the class loader from which to load the resource bundle
  230        * @return  the ResourceBundle
  231        */
  232       final private static ResourceBundle loadBundle(
  233           String bundleName, ClassLoader loader) {
  234           ResourceBundle messages = (ResourceBundle)bundles.get(bundleName);
  235   
  236           if (messages == null) //not found as loaded - add
  237           {
  238               messages = ResourceBundle.getBundle(bundleName, locale, loader);
  239               bundles.put(bundleName, messages);
  240           }
  241           return messages;
  242       }
  243   
  244       /** Assert resources available
  245        * @since 1.1
  246        * @throws RuntimeException if the resource bundle could not
  247        * be loaded during construction.
  248        */
  249       private void assertBundle () {
  250           if (failure != null)
  251               throw new RuntimeException (
  252                   "No resources could be found for bundle:\"" + //NOI18N
  253                   bundle + "\" " + failure); //NOI18N
  254       }
  255       
  256       /** Assert resources available
  257        * @param key the message key 
  258        * @since 1.0.2
  259        * @throws RuntimeException if the resource bundle could not
  260        * be loaded during construction.
  261        */
  262       private void assertBundle (String key) {
  263           if (failure != null)
  264               throw new RuntimeException (
  265                   "No resources could be found to annotate error message key:\"" + //NOI18N
  266                   key + "\" " + failure); //NOI18N
  267       }
  268   
  269       /**
  270        * Returns message as <code>String</code>
  271        * @param messages the resource bundle
  272        * @param messageKey the message key
  273        * @return the resolved message text
  274        */
  275       final private static String getMessage(ResourceBundle messages, String messageKey) 
  276       {
  277           return messages.getString(messageKey);
  278       }
  279   
  280       /**
  281        * Formats message by adding array of arguments
  282        * @param messages the resource bundle
  283        * @param messageKey the message key
  284        * @param msgArgs an array of arguments to substitute into the message
  285        * @return the resolved message text
  286        */
  287       final private static String getMessage(ResourceBundle messages, String messageKey, Object msgArgs[]) 
  288       {
  289           for (int i=0; i<msgArgs.length; i++) {
  290               if (msgArgs[i] == null) msgArgs[i] = ""; // NOI18N
  291           }
  292           MessageFormat formatter = new MessageFormat(messages.getString(messageKey));
  293           return formatter.format(msgArgs);
  294       }
  295       
  296       /**
  297        * Formats message by adding an <code>Object</code> argument.
  298        * @param messages the resource bundle
  299        * @param messageKey the message key
  300        * @param arg the argument
  301        * @return the resolved message text
  302        */
  303       final private static String getMessage(ResourceBundle messages, String messageKey, Object arg) 
  304       {
  305           Object []args = {arg};
  306           return getMessage(messages, messageKey, args);
  307       }
  308       
  309       /**
  310        * Formats message by adding two <code>Object</code> arguments.
  311        * @param messages the resource bundle
  312        * @param messageKey the message key
  313        * @param arg1 the first argument
  314        * @param arg2 the second argument
  315        * @return the resolved message text
  316        */
  317       final private static String getMessage(ResourceBundle messages, String messageKey, Object arg1,
  318                                      Object arg2) 
  319       {
  320           Object []args = {arg1, arg2};
  321           return getMessage(messages, messageKey, args);
  322       }
  323       
  324       /**
  325        * Formats message by adding three <code>Object</code> arguments.
  326        * @param messages the resource bundle
  327        * @param messageKey the message key
  328        * @param arg1 the first argument
  329        * @param arg2 the second argument
  330        * @param arg3 the third argument
  331        * @return the resolved message text
  332        */
  333       final private static String getMessage(ResourceBundle messages, String messageKey, Object arg1,
  334                                      Object arg2, Object arg3) 
  335       {
  336           Object []args = {arg1, arg2, arg3};
  337           return getMessage(messages, messageKey, args);
  338       }
  339   
  340       /**
  341        * Formats message by adding an <code>int</code> as an argument.
  342        * @param messages the resource bundle
  343        * @param messageKey the message key
  344        * @param arg the argument
  345        * @return the resolved message text
  346        */
  347       final private static String getMessage(ResourceBundle messages, String messageKey, int arg) 
  348       {
  349           Object []args = {new Integer(arg)};
  350           return getMessage(messages, messageKey, args);
  351       }
  352       
  353       /**
  354        * Formats message by adding a <code>boolean</code> as an argument.
  355        * @param messages the resource bundle
  356        * @param messageKey the message key
  357        * @param arg the argument
  358        * @return the resolved message text
  359        */
  360       final private static String getMessage(ResourceBundle messages, String messageKey, boolean arg) 
  361       {
  362           Object []args = {String.valueOf(arg)};
  363           return getMessage(messages, messageKey, args);
  364       }
  365   
  366       /**  
  367        * Returns the package portion of the specified class.
  368        * @param className the name of the class from which to extract the 
  369        * package 
  370        * @return package portion of the specified class
  371        */   
  372       final private static String getPackageName(final String className)
  373       { 
  374           final int index = className.lastIndexOf('.');
  375           return ((index != -1) ? className.substring(0, index) : ""); // NOI18N
  376       }
  377   }

Save This Page
Home » jdo2-util-2.3-ea-src » org.apache.jdo.util » [javadoc | source]