KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > runtime > internal > adaptor > ContextFinder


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.runtime.internal.adaptor;
12
13 import java.io.IOException JavaDoc;
14 import java.net.URL JavaDoc;
15 import java.security.AccessController JavaDoc;
16 import java.security.PrivilegedAction JavaDoc;
17 import java.util.*;
18 import org.eclipse.osgi.framework.adaptor.BundleClassLoader;
19
20 public class ContextFinder extends ClassLoader JavaDoc implements PrivilegedAction JavaDoc {
21     static final class Finder extends SecurityManager JavaDoc {
22         public Class JavaDoc[] getClassContext() {
23             return super.getClassContext();
24         }
25     }
26     //This is used to detect cycle that could be caused while delegating the loading to other classloaders
27
//It keeps track on a thread basis of the set of requested classes and resources
28
private static ThreadLocal JavaDoc cycleDetector = new ThreadLocal JavaDoc();
29     static ClassLoader JavaDoc finderClassLoader;
30     static Finder contextFinder;
31     static {
32         AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
33             public Object JavaDoc run() {
34                 finderClassLoader = ContextFinder.class.getClassLoader();
35                 contextFinder = new Finder();
36                 return null;
37             }
38         });
39     }
40
41     public ContextFinder(ClassLoader JavaDoc contextClassLoader) {
42         super(contextClassLoader);
43     }
44
45     // Return a list of all classloaders on the stack that are neither the
46
// ContextFinder classloader nor the boot classloader. The last classloader
47
// in the list is either a bundle classloader or the framework's classloader
48
// We assume that the bootclassloader never uses the context classloader to find classes in itself.
49
ArrayList basicFindClassLoaders() {
50         Class JavaDoc[] stack = contextFinder.getClassContext();
51         ArrayList result = new ArrayList(1);
52         ClassLoader JavaDoc previousLoader = null;
53         for (int i = 1; i < stack.length; i++) {
54             ClassLoader JavaDoc tmp = stack[i].getClassLoader();
55             if (stack[i] != ContextFinder.class && tmp != null && tmp != this) {
56                 if (checkClassLoader(tmp)) {
57                     if (previousLoader != tmp) {
58                         result.add(tmp);
59                         previousLoader = tmp;
60                     }
61                 }
62                 // stop at the framework classloader or the first bundle classloader
63
if (tmp == finderClassLoader || tmp instanceof BundleClassLoader)
64                     break;
65             }
66         }
67         return result;
68     }
69
70     // ensures that a classloader does not have the ContextFinder as part of the
71
// parent hierachy. A classloader which has the ContextFinder as a parent must
72
// not be used as a delegate, otherwise we endup in endless recursion.
73
private boolean checkClassLoader(ClassLoader JavaDoc classloader) {
74         if (classloader == null || classloader == getParent())
75             return false;
76         for (ClassLoader JavaDoc parent = classloader.getParent(); parent != null; parent = parent.getParent())
77             if (parent == this)
78                 return false;
79         return true;
80     }
81
82     private ArrayList findClassLoaders() {
83         if (System.getSecurityManager() == null)
84             return basicFindClassLoaders();
85         return (ArrayList) AccessController.doPrivileged(this);
86     }
87
88     public Object JavaDoc run() {
89         return basicFindClassLoaders();
90     }
91
92     //Return whether the request for loading "name" should proceed.
93
//False is returned when a cycle is being detected
94
private boolean startLoading(String JavaDoc name) {
95         Set classesAndResources = (Set) cycleDetector.get();
96         if (classesAndResources != null && classesAndResources.contains(name))
97             return false;
98
99         if (classesAndResources == null) {
100             classesAndResources = new HashSet(3);
101             cycleDetector.set(classesAndResources);
102         }
103         classesAndResources.add(name);
104         return true;
105     }
106
107     private void stopLoading(String JavaDoc name) {
108         ((Set) cycleDetector.get()).remove(name);
109     }
110
111     protected Class JavaDoc loadClass(String JavaDoc arg0, boolean arg1) throws ClassNotFoundException JavaDoc {
112         //Shortcut cycle
113
if (startLoading(arg0) == false)
114             throw new ClassNotFoundException JavaDoc(arg0);
115
116         try {
117             ArrayList toConsult = findClassLoaders();
118             for (Iterator loaders = toConsult.iterator(); loaders.hasNext();)
119                 try {
120                     return ((ClassLoader JavaDoc) loaders.next()).loadClass(arg0);
121                 } catch (ClassNotFoundException JavaDoc e) {
122                     // go to the next class loader
123
}
124             return super.loadClass(arg0, arg1);
125         } finally {
126             stopLoading(arg0);
127         }
128     }
129
130     public URL JavaDoc getResource(String JavaDoc arg0) {
131         //Shortcut cycle
132
if (startLoading(arg0) == false)
133             return null;
134         try {
135             ArrayList toConsult = findClassLoaders();
136             for (Iterator loaders = toConsult.iterator(); loaders.hasNext();) {
137                 URL JavaDoc result = ((ClassLoader JavaDoc) loaders.next()).getResource(arg0);
138                 if (result != null)
139                     return result;
140                 // go to the next class loader
141
}
142             return super.getResource(arg0);
143         } finally {
144             stopLoading(arg0);
145         }
146     }
147
148     protected Enumeration findResources(String JavaDoc arg0) throws IOException JavaDoc {
149         //Shortcut cycle
150
if (startLoading(arg0) == false)
151             return null;
152         try {
153             ArrayList toConsult = findClassLoaders();
154             for (Iterator loaders = toConsult.iterator(); loaders.hasNext();) {
155                 Enumeration result = ((ClassLoader JavaDoc) loaders.next()).getResources(arg0);
156                 if (result != null && result.hasMoreElements())
157                     return result;
158                 // go to the next class loader
159
}
160             return super.findResources(arg0);
161         } finally {
162             stopLoading(arg0);
163         }
164     }
165 }
166
Popular Tags