/* =========================================================== * 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); } }