1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52:
53:
58: public class RMIClassLoaderImpl extends RMIClassLoaderSpi
59: {
60: private static class MyClassLoader extends URLClassLoader
61: {
62:
63: MyClassLoader (URL[] urls, ClassLoader parent, String annotation)
64: {
65: super (urls, parent);
66: this.annotation = annotation;
67: }
68:
69: public static String urlToAnnotation (URL[] urls)
70: {
71: if (urls.length == 0)
72: return null;
73:
74: CPStringBuilder annotation = new CPStringBuilder (64 * urls.length);
75:
76: for (int i = 0; i < urls.length; i++)
77: {
78: annotation.append (urls [i].toExternalForm());
79: annotation.append (' ');
80: }
81:
82: return annotation.toString();
83: }
84:
85: public final String getClassAnnotation()
86: {
87: return annotation;
88: }
89:
90: private final String annotation;
91: }
92:
93:
97: private static class CacheKey
98: {
99: private String mCodeBase;
100: private ClassLoader mContextClassLoader;
101:
102: public CacheKey (String theCodebase, ClassLoader theContextClassLoader)
103: {
104: mCodeBase = theCodebase;
105: mContextClassLoader = theContextClassLoader;
106: }
107:
108:
111: public boolean equals (Object theOther)
112: {
113: if (theOther instanceof CacheKey)
114: {
115: CacheKey key = (CacheKey) theOther;
116:
117: return (equals (this.mCodeBase,key.mCodeBase)
118: && equals (this.mContextClassLoader, key.mContextClassLoader));
119: }
120: return false;
121: }
122:
123:
129: private boolean equals (Object theOne, Object theOther)
130: {
131: return theOne != null ? theOne.equals (theOther) : theOther == null;
132: }
133:
134:
137: public int hashCode()
138: {
139: return ((mCodeBase != null ? mCodeBase.hashCode() : 0)
140: ^(mContextClassLoader != null ? mContextClassLoader.hashCode() : -1));
141: }
142:
143: public String toString()
144: {
145: return "[" + mCodeBase + "," + mContextClassLoader + "]";
146: }
147:
148: }
149:
150: private static RMIClassLoaderImpl instance = null;
151:
152: private static Map cacheLoaders;
153: private static Map cacheAnnotations;
154:
155: private static MyClassLoader defaultClassLoader;
156:
157:
158:
159: private static String defaultAnnotation;
160:
161:
162: private static URL defaultCodebase;
163:
164: static
165: {
166:
167: cacheLoaders = new Hashtable (89);
168: cacheAnnotations = new Hashtable (89);
169:
170: defaultAnnotation = System.getProperty ("java.rmi.server.defaultAnnotation");
171:
172: try
173: {
174: if (defaultAnnotation != null)
175: defaultCodebase = new URL (defaultAnnotation);
176: }
177: catch (Exception _)
178: {
179: defaultCodebase = null;
180: }
181:
182: if (defaultCodebase != null)
183: {
184: defaultClassLoader = new MyClassLoader (new URL[] { defaultCodebase }, null,
185: defaultAnnotation);
186:
187: cacheLoaders.put (new CacheKey (defaultAnnotation,
188: Thread.currentThread().getContextClassLoader()),
189: defaultClassLoader);
190: }
191: }
192:
193:
197: private RMIClassLoaderImpl()
198: {
199: }
200:
201:
206: public static RMIClassLoaderSpi getInstance()
207: {
208: if (instance == null)
209: instance = new RMIClassLoaderImpl();
210: return instance;
211: }
212:
213: public Class loadClass(String codeBase, String name,
214: ClassLoader defaultLoader)
215: throws MalformedURLException, ClassNotFoundException
216: {
217: try
218: {
219: if (defaultLoader != null)
220: return Class.forName(name, false, defaultLoader);
221: }
222: catch (ClassNotFoundException e)
223: {
224: }
225:
226: return Class.forName(name, false, getClassLoader(codeBase));
227: }
228:
229: public Class loadProxyClass(String codeBase, String[] interfaces,
230: ClassLoader defaultLoader)
231: throws MalformedURLException, ClassNotFoundException
232: {
233: Class clss[] = new Class[interfaces.length];
234:
235: for (int i = 0; i < interfaces.length; i++)
236: {
237: clss[i] = loadClass(codeBase, interfaces[i], defaultLoader);
238: }
239:
240:
241: ArrayList loaders = new ArrayList(clss.length);
242: ClassLoader loader = null;
243: for (int i = 0; i < clss.length; i++)
244: {
245: loader = clss[i].getClassLoader();
246: if (! loaders.contains(loader))
247: {
248: loaders.add(0, loader);
249: }
250: }
251: if (loaders.size() > 1)
252: {
253: loader = new CombinedClassLoader(loaders);
254: }
255:
256: try
257: {
258: return Proxy.getProxyClass(loader, clss);
259: }
260: catch (IllegalArgumentException e)
261: {
262: throw new ClassNotFoundException(null, e);
263: }
264: }
265:
266:
276: public ClassLoader getClassLoader(String codebase)
277: throws MalformedURLException
278: {
279: if (codebase == null || codebase.length() == 0)
280: return Thread.currentThread().getContextClassLoader();
281:
282: ClassLoader loader;
283: CacheKey loaderKey = new CacheKey
284: (codebase, Thread.currentThread().getContextClassLoader());
285: loader = (ClassLoader) cacheLoaders.get (loaderKey);
286:
287: if (loader == null)
288: {
289:
290:
291: StringTokenizer tok = new StringTokenizer (codebase, " ");
292: ArrayList urls = new ArrayList();
293:
294: while (tok.hasMoreTokens())
295: urls.add (new URL(tok.nextToken()));
296:
297: loader = new MyClassLoader((URL[]) urls.toArray(new URL [urls.size()]),
298: Thread.currentThread().getContextClassLoader(),
299: codebase);
300: cacheLoaders.put (loaderKey, loader);
301: }
302:
303: return loader;
304: }
305:
306:
315: public String getClassAnnotation(Class cl)
316: {
317: ClassLoader loader = cl.getClassLoader();
318:
319: if (loader == null
320: || loader == ClassLoader.getSystemClassLoader())
321: {
322: return System.getProperty ("java.rmi.server.codebase");
323: }
324:
325: if (loader instanceof MyClassLoader)
326: {
327: return ((MyClassLoader) loader).getClassAnnotation();
328: }
329:
330: String s = (String) cacheAnnotations.get (loader);
331:
332: if (s != null)
333: return s;
334:
335: if (loader instanceof URLClassLoader)
336: {
337: URL[] urls = ((URLClassLoader) loader).getURLs();
338:
339: if (urls.length == 0)
340: return null;
341:
342: CPStringBuilder annotation = new CPStringBuilder (64 * urls.length);
343:
344: for (int i = 0; i < urls.length; i++)
345: {
346: annotation.append (urls [i].toExternalForm());
347: annotation.append (' ');
348: }
349:
350: s = annotation.toString();
351: cacheAnnotations.put (loader, s);
352: return s;
353: }
354:
355: return System.getProperty ("java.rmi.server.codebase");
356: }
357: }