001 /* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
006 *
007 * Project Info: http://www.jfree.org/jfreechart/index.html
008 *
009 * This library is free software; you can redistribute it and/or modify it
010 * under the terms of the GNU Lesser General Public License as published by
011 * the Free Software Foundation; either version 2.1 of the License, or
012 * (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but
015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017 * License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this library; if not, write to the Free Software
021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
022 * USA.
023 *
024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025 * in the United States and other countries.]
026 *
027 * --------------------------
028 * ResourceBundleWrapper.java
029 * --------------------------
030 * (C)opyright 2008, by Jess Thrysoee and Contributors.
031 *
032 * Original Author: Jess Thrysoee;
033 * Contributor(s): David Gilbert (for Object Refinery Limited);
034 *
035 * Changes
036 * -------
037 * 18-Dec-2008 : Version 1 (JT);
038 *
039 */
040
041 package org.jfree.chart.util;
042
043 import java.net.URL;
044 import java.net.URLClassLoader;
045 import java.util.ArrayList;
046 import java.util.List;
047 import java.util.Locale;
048 import java.util.ResourceBundle;
049
050 /**
051 * Wrapper of ResourceBundle.getBundle() methods. This wrapper is introduced to
052 * avoid a dramatic performance penalty by superfluous resource (and classes
053 * loaded by Class.forName) lookups on web server in applets.
054 *
055 * <pre>
056 * public class AppletC extends javax.swing.JApplet {
057 * public void init() {
058 * ResourceBundleWrapper.removeCodeBase(getCodeBase(),
059 * (URLClassLoader) getClass().getClassLoader());
060 * ...
061 * </pre>
062 *
063 * @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4243379">
064 * Bug ID: 4243379</a>
065 * @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4668479">
066 * Bug ID: 4668479</a>
067 *
068 * @since 1.0.12
069 */
070 public class ResourceBundleWrapper {
071
072 /**
073 * A special class loader with no code base lookup. This field may be
074 * <code>null</code> (the field is only initialised if removeCodeBase() is
075 * called from an applet.
076 */
077 private static URLClassLoader noCodeBaseClassLoader;
078
079 /**
080 * Private constructor.
081 */
082 private ResourceBundleWrapper() {
083 // all methods are static, no need to instantiate
084 }
085
086 /**
087 * Instantiate a {@link URLClassLoader} for resource lookups where the
088 * codeBase URL is removed. This method is typically called from an
089 * applet's init() method. If this method is never called, the
090 * <code>getBundle()</code> methods map to the standard
091 * {@link ResourceBundle} lookup methods.
092 *
093 * @param codeBase the codeBase URL.
094 * @param urlClassLoader the class loader.
095 */
096 public static void removeCodeBase(URL codeBase,
097 URLClassLoader urlClassLoader) {
098 List urlsNoBase = new ArrayList();
099
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 }