Source for org.jfree.util.ResourceBundleWrapper

   1: /* ========================================================================
   2:  * JCommon : a free general purpose class library for the Java(tm) platform
   3:  * ========================================================================
   4:  *
   5:  * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
   6:  *
   7:  * Project Info:  http://www.jfree.org/jcommon/index.html
   8:  *
   9:  * This library is free software; you can redistribute it and/or modify it
  10:  * under the terms of the GNU Lesser General Public License as published by
  11:  * the Free Software Foundation; either version 2.1 of the License, or
  12:  * (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but
  15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  16:  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  17:  * License for more details.
  18:  *
  19:  * You should have received a copy of the GNU Lesser General Public
  20:  * License along with this library; if not, write to the Free Software
  21:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
  22:  * USA.
  23:  *
  24:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  25:  * in the United States and other countries.]
  26:  *
  27:  * --------------------------
  28:  * ResourceBundleWrapper.java
  29:  * --------------------------
  30:  * (C)opyright 2008, by Jess Thrysoee and Contributors.
  31:  *
  32:  * Original Author:  Jess Thrysoee;
  33:  * Contributor(s):   David Gilbert (for Object Refinery Limited);
  34:  *
  35:  * Changes
  36:  * -------
  37:  * 18-Dec-2008 : Version 1 (JT);
  38:  *
  39:  */
  40: 
  41: package org.jfree.util;
  42: 
  43: import java.net.URL;
  44: import java.net.URLClassLoader;
  45: import java.util.ArrayList;
  46: import java.util.List;
  47: import java.util.Locale;
  48: import java.util.ResourceBundle;
  49: 
  50: /**
  51:  * Wrapper of ResourceBundle.getBundle() methods. This wrapper is introduced to
  52:  * avoid a dramatic performance penalty by superfluous resource (and classes
  53:  * loaded by Class.forName) lookups on web server in applets.
  54:  *
  55:  * <pre>
  56:  * public class AppletC extends javax.swing.JApplet {
  57:  *    public void init() {
  58:  *       ResourceBundleWrapper.removeCodeBase(getCodeBase(),
  59:  *               (URLClassLoader) getClass().getClassLoader());
  60:  *    ...
  61:  * </pre>
  62:  *
  63:  * @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4243379">
  64:  *               Bug ID: 4243379</a>
  65:  * @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4668479">
  66:  *               Bug ID: 4668479</a>
  67:  *
  68:  * @since 1.0.15
  69:  */
  70: public class ResourceBundleWrapper {
  71: 
  72:     /**
  73:      * A special class loader with no code base lookup.  This field may be
  74:      * <code>null</code> (the field is only initialised if removeCodeBase() is
  75:      * called from an applet.
  76:      */
  77:     private static URLClassLoader noCodeBaseClassLoader;
  78: 
  79:     /**
  80:      * Private constructor.
  81:      */
  82:     private ResourceBundleWrapper() {
  83:         // all methods are static, no need to instantiate
  84:     }
  85: 
  86:     /**
  87:      * Instantiate a {@link URLClassLoader} for resource lookups where the
  88:      * codeBase URL is removed.  This method is typically called from an
  89:      * applet's init() method.  If this method is never called, the
  90:      * <code>getBundle()</code> methods map to the standard
  91:      * {@link ResourceBundle} lookup methods.
  92:      *
  93:      * @param codeBase  the codeBase URL.
  94:      * @param urlClassLoader  the class loader.
  95:      */
  96:     public static void removeCodeBase(URL codeBase,
  97:             URLClassLoader urlClassLoader) {
  98:         List urlsNoBase = new ArrayList();
  99: 
 100:         URL[] urls = urlClassLoader.getURLs();
 101:         for (int i = 0; i < urls.length; i++) {
 102:             if (! urls[i].sameFile(codeBase)) {
 103:                 urlsNoBase.add(urls[i]);
 104:             }
 105:         }
 106:         // substitute the filtered URL list
 107:         URL[] urlsNoBaseArray = (URL[]) urlsNoBase.toArray(new URL[0]);
 108:         noCodeBaseClassLoader = URLClassLoader.newInstance(urlsNoBaseArray);
 109:     }
 110: 
 111:     /**
 112:      * Finds and returns the specified resource bundle.
 113:      *
 114:      * @param baseName  the base name.
 115:      *
 116:      * @return The resource bundle.
 117:      */
 118:     public static final ResourceBundle getBundle(String baseName) {
 119:         // the noCodeBaseClassLoader is configured by a call to the
 120:         // removeCodeBase() method, typically in the init() method of an
 121:         // applet...
 122:         if (noCodeBaseClassLoader != null) {
 123:             return ResourceBundle.getBundle(baseName, Locale.getDefault(),
 124:                     noCodeBaseClassLoader);
 125:         }
 126:         else {
 127:             // standard ResourceBundle behaviour
 128:             return ResourceBundle.getBundle(baseName);
 129:         }
 130:     }
 131: 
 132:     /**
 133:      * Finds and returns the specified resource bundle.
 134:      *
 135:      * @param baseName  the base name.
 136:      * @param locale  the locale.
 137:      *
 138:      * @return The resource bundle.
 139:      */
 140:     public static final ResourceBundle getBundle(String baseName,
 141:             Locale locale) {
 142: 
 143:         // the noCodeBaseClassLoader is configured by a call to the
 144:         // removeCodeBase() method, typically in the init() method of an
 145:         // applet...
 146:         if (noCodeBaseClassLoader != null) {
 147:             return ResourceBundle.getBundle(baseName, locale,
 148:                     noCodeBaseClassLoader);
 149:         }
 150:         else {
 151:             // standard ResourceBundle behaviour
 152:             return ResourceBundle.getBundle(baseName, locale);
 153:         }
 154:     }
 155: 
 156:     /**
 157:      * Maps directly to <code>ResourceBundle.getBundle(baseName, locale,
 158:      * loader)</code>.
 159:      *
 160:      * @param baseName  the base name.
 161:      * @param locale  the locale.
 162:      * @param loader  the class loader.
 163:      *
 164:      * @return The resource bundle.
 165:      */
 166:     public static ResourceBundle getBundle(String baseName, Locale locale,
 167:             ClassLoader loader) {
 168:         return ResourceBundle.getBundle(baseName, locale, loader);
 169:     }
 170: 
 171: }