001: /*****************************************************************************
002: * *
003: * This file is part of the BeanShell Java Scripting distribution. *
004: * Documentation and updates may be found at http://www.beanshell.org/ *
005: * *
006: * Sun Public License Notice: *
007: * *
008: * The contents of this file are subject to the Sun Public License Version *
009: * 1.0 (the "License"); you may not use this file except in compliance with *
010: * the License. A copy of the License is available at http://www.sun.com *
011: * *
012: * The Original Code is BeanShell. The Initial Developer of the Original *
013: * Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
014: * (C) 2000. All Rights Reserved. *
015: * *
016: * GNU Public License Notice: *
017: * *
018: * Alternatively, the contents of this file may be used under the terms of *
019: * the GNU Lesser General Public License (the "LGPL"), in which case the *
020: * provisions of LGPL are applicable instead of those above. If you wish to *
021: * allow use of your version of this file only under the terms of the LGPL *
022: * and not to allow others to use your version of this file under the SPL, *
023: * indicate your decision by deleting the provisions above and replace *
024: * them with the notice and other provisions required by the LGPL. If you *
025: * do not delete the provisions above, a recipient may use your version of *
026: * this file under either the SPL or the LGPL. *
027: * *
028: * Patrick Niemeyer (pat@pat.net) *
029: * Author of Learning Java, O'Reilly & Associates *
030: * http://www.pat.net/~pat/ *
031: * *
032: *****************************************************************************/package org.gjt.sp.jedit.bsh.classpath;
033:
034: import java.net.*;
035:
036: import org.gjt.sp.jedit.bsh.BshClassManager;
037:
038: /**
039: One of the things BshClassLoader does is to address a deficiency in
040: URLClassLoader that prevents us from specifying individual classes
041: via URLs.
042: */
043: public class BshClassLoader extends URLClassLoader {
044: BshClassManager classManager;
045:
046: /**
047: @param bases URLs JARClassLoader seems to require absolute paths
048: */
049: public BshClassLoader(BshClassManager classManager, URL[] bases) {
050: super (bases);
051: this .classManager = classManager;
052: }
053:
054: /**
055: @param bases URLs JARClassLoader seems to require absolute paths
056: */
057: public BshClassLoader(BshClassManager classManager, BshClassPath bcp) {
058: this (classManager, bcp.getPathComponents());
059: }
060:
061: /**
062: For use by children
063: @param bases URLs JARClassLoader seems to require absolute paths
064: */
065: protected BshClassLoader(BshClassManager classManager) {
066: this (classManager, new URL[] {});
067: }
068:
069: // public version of addURL
070: public void addURL(URL url) {
071: super .addURL(url);
072: }
073:
074: /**
075: This modification allows us to reload classes which are in the
076: Java VM user classpath. We search first rather than delegate to
077: the parent classloader (or bootstrap path) first.
078:
079: An exception is for BeanShell core classes which are always loaded from
080: the same classloader as the interpreter.
081: */
082: public Class loadClass(String name, boolean resolve)
083: throws ClassNotFoundException {
084: Class c = null;
085:
086: /*
087: Check first for classes loaded through this loader.
088: The VM will not allow a class to be loaded twice.
089: */
090: c = findLoadedClass(name);
091: if (c != null)
092: return c;
093:
094: // This is copied from ClassManagerImpl
095: // We should refactor this somehow if it sticks around
096: if (name.startsWith(ClassManagerImpl.BSH_PACKAGE))
097: try {
098: return org.gjt.sp.jedit.bsh.Interpreter.class
099: .getClassLoader().loadClass(name);
100: } catch (ClassNotFoundException e) {
101: }
102:
103: /*
104: Try to find the class using our classloading mechanism.
105: Note: I wish we didn't have to catch the exception here... slow
106: */
107: try {
108: c = findClass(name);
109: } catch (ClassNotFoundException e) {
110: }
111:
112: if (c == null)
113: throw new ClassNotFoundException("here in loaClass");
114:
115: if (resolve)
116: resolveClass(c);
117:
118: return c;
119: }
120:
121: /**
122: Find the correct source for the class...
123:
124: Try designated loader if any
125: Try our URLClassLoader paths if any
126: Try base loader if any
127: Try system ???
128: */
129: // add some caching for not found classes?
130: protected Class findClass(String name)
131: throws ClassNotFoundException {
132: // Deal with this cast somehow... maybe have this class use
133: // ClassManagerImpl type directly.
134: // Don't add the method to BshClassManager... it's really an impl thing
135: ClassManagerImpl bcm = (ClassManagerImpl) getClassManager();
136:
137: // Should we try to load the class ourselves or delegate?
138: // look for overlay loader
139:
140: // Deal with this cast somehow... maybe have this class use
141: // ClassManagerImpl type directly.
142: // Don't add the method to BshClassManager... it's really an impl thing
143: ClassLoader cl = bcm.getLoaderForClass(name);
144:
145: Class c;
146:
147: // If there is a designated loader and it's not us delegate to it
148: if (cl != null && cl != this )
149: try {
150: return cl.loadClass(name);
151: } catch (ClassNotFoundException e) {
152: throw new ClassNotFoundException(
153: "Designated loader could not find class: " + e);
154: }
155:
156: // Let URLClassLoader try any paths it may have
157: if (getURLs().length > 0)
158: try {
159: return super .findClass(name);
160: } catch (ClassNotFoundException e) {
161: //System.out.println(
162: // "base loader here caught class not found: "+name );
163: }
164:
165: // If there is a baseLoader and it's not us delegate to it
166: cl = bcm.getBaseLoader();
167:
168: if (cl != null && cl != this )
169: try {
170: return cl.loadClass(name);
171: } catch (ClassNotFoundException e) {
172: }
173:
174: // Try system loader
175: return bcm.plainClassForName(name);
176: }
177:
178: /*
179: The superclass does something like this
180:
181: c = findLoadedClass(name);
182: if null
183: try
184: if parent not null
185: c = parent.loadClass(name, false);
186: else
187: c = findBootstrapClass(name);
188: catch ClassNotFoundException
189: c = findClass(name);
190: */
191:
192: BshClassManager getClassManager() {
193: return classManager;
194: }
195:
196: }
|