KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > equinox > internal > jsp > jasper > JSPContextFinder


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