001: /*
002: * $Id: CachedClassLoader.java,v 1.4 2003/11/11 18:19:35 ajzeneski Exp $
003: *
004: * Copyright (c) 2003 The Open For Business Project - www.ofbiz.org
005: *
006: * Permission is hereby granted, free of charge, to any person obtaining a
007: * copy of this software and associated documentation files (the "Software"),
008: * to deal in the Software without restriction, including without limitation
009: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
010: * and/or sell copies of the Software, and to permit persons to whom the
011: * Software is furnished to do so, subject to the following conditions:
012: *
013: * The above copyright notice and this permission notice shall be included
014: * in all copies or substantial portions of the Software.
015: *
016: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
017: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
018: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
019: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
020: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
021: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
022: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023: */
024: package org.ofbiz.base.util;
025:
026: import java.net.URL;
027: import java.net.URLClassLoader;
028: import java.util.HashMap;
029: import java.util.HashSet;
030: import java.util.Map;
031:
032: /**
033: * Caching Class Loader
034: *
035: * @author <a href="mailto:jonesde@ofbiz.org">David E. Jones</a>
036: * @version $Revision: 1.4 $
037: * @since 2.1
038: */
039: public class CachedClassLoader extends URLClassLoader {
040:
041: public static final String module = CachedClassLoader.class
042: .getName();
043:
044: private String contextName;
045:
046: public static Map globalClassNameClassMap = new HashMap();
047: public static HashSet globalBadClassNameSet = new HashSet();
048:
049: public Map localClassNameClassMap = new HashMap();
050: public HashSet localBadClassNameSet = new HashSet();
051:
052: public static Map globalResourceMap = new HashMap();
053: public static HashSet globalBadResourceNameSet = new HashSet();
054:
055: public Map localResourceMap = new HashMap();
056: public HashSet localBadResourceNameSet = new HashSet();
057:
058: static {
059: // setup some commonly used classes...
060: globalClassNameClassMap.put("Object", java.lang.Object.class);
061: globalClassNameClassMap.put("java.lang.Object",
062: java.lang.Object.class);
063:
064: globalClassNameClassMap.put("String", java.lang.String.class);
065: globalClassNameClassMap.put("java.lang.String",
066: java.lang.String.class);
067:
068: globalClassNameClassMap.put("Boolean", java.lang.Boolean.class);
069: globalClassNameClassMap.put("java.lang.Boolean",
070: java.lang.Boolean.class);
071:
072: globalClassNameClassMap.put("Double", java.lang.Double.class);
073: globalClassNameClassMap.put("java.lang.Double",
074: java.lang.Double.class);
075: globalClassNameClassMap.put("Float", java.lang.Float.class);
076: globalClassNameClassMap.put("java.lang.Float",
077: java.lang.Float.class);
078: globalClassNameClassMap.put("Long", java.lang.Long.class);
079: globalClassNameClassMap.put("java.lang.Long",
080: java.lang.Long.class);
081: globalClassNameClassMap.put("Integer", java.lang.Integer.class);
082: globalClassNameClassMap.put("java.lang.Integer",
083: java.lang.Integer.class);
084:
085: globalClassNameClassMap.put("Timestamp",
086: java.sql.Timestamp.class);
087: globalClassNameClassMap.put("java.sql.Timestamp",
088: java.sql.Timestamp.class);
089: globalClassNameClassMap.put("Time", java.sql.Time.class);
090: globalClassNameClassMap.put("java.sql.Time",
091: java.sql.Time.class);
092: globalClassNameClassMap.put("Date", java.sql.Date.class);
093: globalClassNameClassMap.put("java.sql.Date",
094: java.sql.Date.class);
095:
096: globalClassNameClassMap.put("Locale", java.util.Locale.class);
097: globalClassNameClassMap.put("java.util.Locale",
098: java.util.Locale.class);
099:
100: globalClassNameClassMap.put("java.util.Date",
101: java.util.Date.class);
102: globalClassNameClassMap.put("Collection",
103: java.util.Collection.class);
104: globalClassNameClassMap.put("java.util.Collection",
105: java.util.Collection.class);
106: globalClassNameClassMap.put("List", java.util.List.class);
107: globalClassNameClassMap.put("java.util.List",
108: java.util.List.class);
109: globalClassNameClassMap.put("Set", java.util.Set.class);
110: globalClassNameClassMap.put("java.util.Set",
111: java.util.Set.class);
112: globalClassNameClassMap.put("Map", java.util.Map.class);
113: globalClassNameClassMap.put("java.util.Map",
114: java.util.Map.class);
115: globalClassNameClassMap.put("HashMap", java.util.HashMap.class);
116: globalClassNameClassMap.put("java.util.HashMap",
117: java.util.HashMap.class);
118:
119: try {
120: ClassLoader loader = Thread.currentThread()
121: .getContextClassLoader();
122:
123: // note: loadClass is necessary for these since this class doesn't know anything about the Entity Engine at compile time
124: globalClassNameClassMap.put("GenericValue", loader
125: .loadClass("org.ofbiz.entity.GenericValue"));
126: globalClassNameClassMap
127: .put("org.ofbiz.entity.GenericValue", loader
128: .loadClass("org.ofbiz.entity.GenericValue"));
129: globalClassNameClassMap.put("GenericPK", loader
130: .loadClass("org.ofbiz.entity.GenericPK"));
131: globalClassNameClassMap.put("org.ofbiz.entity.GenericPK",
132: loader.loadClass("org.ofbiz.entity.GenericPK"));
133: globalClassNameClassMap.put("GenericEntity", loader
134: .loadClass("org.ofbiz.entity.GenericEntity"));
135: globalClassNameClassMap.put(
136: "org.ofbiz.entity.GenericEntity",
137: loader.loadClass("org.ofbiz.entity.GenericEntity"));
138: } catch (ClassNotFoundException e) {
139: Debug
140: .logError(
141: e,
142: "Could not pre-initialize dynamically loaded class: ",
143: module);
144: }
145: }
146:
147: public CachedClassLoader(URL[] url, ClassLoader parent,
148: String contextName) {
149: super (url, parent);
150: this .contextName = contextName;
151: if (Debug.verboseOn()) {
152: Package[] paks = this .getPackages();
153: StringBuffer pakList = new StringBuffer();
154: for (int i = 0; i < paks.length; i++) {
155: pakList.append(paks[i].getName());
156: if (i < (paks.length - 1)) {
157: pakList.append(":");
158: }
159: }
160: Debug.logVerbose("Cached ClassLoader Packages : "
161: + pakList.toString(), module);
162: }
163: }
164:
165: public CachedClassLoader(ClassLoader parent, String contextName) {
166: this (new URL[0], parent, contextName);
167: }
168:
169: public CachedClassLoader(URL[] url, ClassLoader parent) {
170: this (url, parent, "__globalContext");
171: }
172:
173: public String toString() {
174: return "org.ofbiz.base.util.CachedClassLoader(" + contextName
175: + ") / " + getParent().toString();
176: }
177:
178: public Class loadClass(String name) throws ClassNotFoundException {
179: return loadClass(name, false);
180: }
181:
182: protected Class loadClass(String name, boolean resolve)
183: throws ClassNotFoundException {
184: //check glocal common classes, ie for all instances
185: Class theClass = (Class) globalClassNameClassMap.get(name);
186:
187: //check local classes, ie for this instance
188: if (theClass == null)
189: theClass = (Class) localClassNameClassMap.get(name);
190:
191: //make sure it is not a known bad class name
192: if (theClass == null) {
193: if (localBadClassNameSet.contains(name)
194: || globalBadClassNameSet.contains(name)) {
195: if (Debug.verboseOn())
196: Debug.logVerbose(
197: "Cached loader got a known bad class name: ["
198: + name + "]", module);
199: throw new ClassNotFoundException(
200: "Cached loader got a known bad class name: "
201: + name);
202: }
203: }
204:
205: if (theClass == null) {
206: if (Debug.verboseOn())
207: Debug.logVerbose(
208: "Cached loader cache miss for class name: ["
209: + name + "]", module);
210:
211: synchronized (this ) {
212: theClass = (Class) localClassNameClassMap.get(name);
213: if (theClass == null) {
214: try {
215: theClass = super .loadClass(name, resolve);
216: if (isGlobalPath(name)) {
217: globalClassNameClassMap.put(name, theClass);
218: } else {
219: localClassNameClassMap.put(name, theClass);
220: }
221: } catch (ClassNotFoundException e) {
222: //Debug.logInfo(e, module);
223: if (Debug.verboseOn())
224: Debug.logVerbose(
225: "Remembering invalid class name: ["
226: + name + "]", module);
227: if (isGlobalPath(name)) {
228: globalBadClassNameSet.add(name);
229: } else {
230: localBadClassNameSet.add(name);
231: }
232: throw e;
233: }
234: }
235: }
236: }
237: return theClass;
238: }
239:
240: public URL getResource(String name) {
241: //check glocal common resources, ie for all instances
242: URL theResource = (URL) globalResourceMap.get(name);
243:
244: //check local resources, ie for this instance
245: if (theResource == null)
246: theResource = (URL) localResourceMap.get(name);
247:
248: //make sure it is not a known bad resource name
249: if (theResource == null) {
250: if (localBadResourceNameSet.contains(name)
251: || globalBadResourceNameSet.contains(name)) {
252: if (Debug.verboseOn())
253: Debug.logVerbose(
254: "Cached loader got a known bad resource name: ["
255: + name + "]", module);
256: return null;
257: }
258: }
259:
260: if (theResource == null) {
261: if (Debug.verboseOn())
262: Debug.logVerbose(
263: "Cached loader cache miss for resource name: ["
264: + name + "]", module);
265: //Debug.logInfo("Cached loader cache miss for resource name: [" + name + "]", module);
266:
267: synchronized (this ) {
268: theResource = (URL) localResourceMap.get(name);
269: if (theResource == null) {
270: theResource = super .getResource(name);
271: if (theResource == null) {
272: if (Debug.verboseOn())
273: Debug.logVerbose(
274: "Remembering invalid resource name: ["
275: + name + "]", module);
276: //Debug.logInfo("Remembering invalid resource name: [" + name + "]", module);
277: if (isGlobalPath(name)) {
278: globalBadResourceNameSet.add(name);
279: } else {
280: localBadResourceNameSet.add(name);
281: }
282: } else {
283: if (isGlobalPath(name)) {
284: globalResourceMap.put(name, theResource);
285: } else {
286: localResourceMap.put(name, theResource);
287: }
288: }
289: }
290: }
291: }
292: return theResource;
293: }
294:
295: protected boolean isGlobalPath(String name) {
296: if (name.startsWith("java.") || name.startsWith("java/")
297: || name.startsWith("/java/"))
298: return true;
299: if (name.startsWith("javax.") || name.startsWith("javax/")
300: || name.startsWith("/javax/"))
301: return true;
302: if (name.startsWith("sun.") || name.startsWith("sun/")
303: || name.startsWith("/sun/"))
304: return true;
305: if (name.startsWith("org.ofbiz."))
306: return true;
307: return false;
308: }
309: }
|