content: /* ===========================================================
   * JFreeChart : a free chart library for the Java(tm) platform
   * ===========================================================
   *
   * (C) Copyright 2000-2012, by Object Refinery Limited and Contributors.
   *
   * Project Info:  http://www.jfree.org/jfreechart/index.html
   *
   * This library is free software; you can redistribute it and/or modify it
   * under the terms of the GNU Lesser General Public License as published by
   * the Free Software Foundation; either version 2.1 of the License, or
   * (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
   * License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this library; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
   * USA.
   *
   * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   * Other names may be trademarks of their respective owners.]
   *
   * --------------------------
   * ResourceBundleWrapper.java
   * --------------------------
   * (C)opyright 2008, 2009, by Jess Thrysoee and Contributors.
   *
   * Original Author:  Jess Thrysoee;
   * Contributor(s):   David Gilbert (for Object Refinery Limited);
   *
   * Changes
   * -------
   * 18-Dec-2008 : Version 1 (JT);
   *
   */
  
  package org.jfree.chart.util;
  
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Locale;
  import java.util.ResourceBundle;
  
  /**
   * Wrapper of ResourceBundle.getBundle() methods. This wrapper is introduced to
   * avoid a dramatic performance penalty by superfluous resource (and classes
   * loaded by Class.forName) lookups on web server in applets.
   *
   * <pre>
   * public class AppletC extends javax.swing.JApplet {
   *    public void init() {
   *       ResourceBundleWrapper.removeCodeBase(getCodeBase(),
   *               (URLClassLoader) getClass().getClassLoader());
   *    ...
   * </pre>
   *
   * @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4243379">
   *               Bug ID: 4243379</a>
   * @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4668479">
   *               Bug ID: 4668479</a>
   *
   * @since 1.0.12
   */
  public class ResourceBundleWrapper {
  
      /**
       * A special class loader with no code base lookup.  This field may be
       * <code>null</code> (the field is only initialised if removeCodeBase() is
       * called from an applet).
       */
      private static URLClassLoader noCodeBaseClassLoader;
  
      /**
       * Private constructor.
       */
      private ResourceBundleWrapper() {
          // all methods are static, no need to instantiate
      }
  
      /**
       * Instantiate a {@link URLClassLoader} for resource lookups where the
       * codeBase URL is removed.  This method is typically called from an
       * applet's init() method.  If this method is never called, the
       * <code>getBundle()</code> methods map to the standard
       * {@link ResourceBundle} lookup methods.
       *
       * @param codeBase  the codeBase URL.
       * @param urlClassLoader  the class loader.
       */
      public static void removeCodeBase(URL codeBase,
              URLClassLoader urlClassLoader) {
          List<URL> urlsNoBase = new ArrayList<URL>();
  
          URL[] urls = urlClassLoader.getURLs();
          for (URL url : urls) {
              if (!url.sameFile(codeBase)) {
                  urlsNoBase.add(url);
              }
          }
          // substitute the filtered URL list
          URL[] urlsNoBaseArray = urlsNoBase.toArray(new URL[urlsNoBase.size()]);
          noCodeBaseClassLoader = URLClassLoader.newInstance(urlsNoBaseArray);
      }
  
      /**
       * Finds and returns the specified resource bundle.
       *
       * @param baseName  the base name.
       *
       * @return The resource bundle.
       */
      public static ResourceBundle getBundle(String baseName) {
          // the noCodeBaseClassLoader is configured by a call to the
          // removeCodeBase() method, typically in the init() method of an
          // applet...
          if (noCodeBaseClassLoader != null) {
              return ResourceBundle.getBundle(baseName, Locale.getDefault(),
                      noCodeBaseClassLoader);
          }
          else {
              // standard ResourceBundle behaviour
              return ResourceBundle.getBundle(baseName);
          }
      }
  
      /**
       * Finds and returns the specified resource bundle.
       *
       * @param baseName  the base name.
       * @param locale  the locale.
       *
       * @return The resource bundle.
       */
      public static ResourceBundle getBundle(String baseName, Locale locale) {
  
          // the noCodeBaseClassLoader is configured by a call to the
          // removeCodeBase() method, typically in the init() method of an
          // applet...
          if (noCodeBaseClassLoader != null) {
              return ResourceBundle.getBundle(baseName, locale,
                      noCodeBaseClassLoader);
          }
          else {
              // standard ResourceBundle behaviour
              return ResourceBundle.getBundle(baseName, locale);
          }
      }
  
      /**
       * Maps directly to <code>ResourceBundle.getBundle(baseName, locale,
       * loader)</code>.
       *
       * @param baseName  the base name.
       * @param locale  the locale.
       * @param loader  the class loader.
       *
       * @return The resource bundle.
       */
      public static ResourceBundle getBundle(String baseName, Locale locale,
              ClassLoader loader) {
          return ResourceBundle.getBundle(baseName, locale, loader);
      }
  
  }
  