KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > marshall > SelectedClassnameClassLoader


1 package org.jboss.cache.marshall;
2
3 import org.apache.commons.logging.Log;
4 import org.apache.commons.logging.LogFactory;
5
6 import java.io.ByteArrayOutputStream JavaDoc;
7 import java.io.FileNotFoundException JavaDoc;
8 import java.io.IOException JavaDoc;
9 import java.io.InputStream JavaDoc;
10 import java.util.Map JavaDoc;
11
12 /**
13  * A ClassLoader that loads classes whose classname begins with one of a
14  * given set of strings, without attempting first to delegate to its
15  * parent loader.
16  * <p>
17  * This class is intended to allow emulation of 2 different types of common J2EE
18  * classloading situations.
19  * <ul>
20  * <li>Servlet-style child-first classloading, where this class is the
21  * child loader.</li>
22  * <li>Parent-first classloading where the parent does not have access to
23  * certain classes</li>
24  * </ul>
25  * </p>
26  * <p>
27  * This class can also be configured to raise a ClassNotFoundException if
28  * asked to load certain classes, thus allowing classes on the classpath
29  * to be hidden from a test environment.
30  * </p>
31  *
32  * @author Brian Stansberry
33  *
34  */

35 public class SelectedClassnameClassLoader extends ClassLoader JavaDoc {
36     
37     private String JavaDoc[] includedClasses = null;
38     private String JavaDoc[] excludedClasses = null;
39     private String JavaDoc[] notFoundClasses = null;
40     private Log log = LogFactory.getLog(SelectedClassnameClassLoader.class);
41     
42     private Map JavaDoc classes = new java.util.HashMap JavaDoc();
43
44     /**
45      * Creates a new classloader that loads the given classes.
46      *
47      * @param includedClasses array of class or package names that should be
48      * directly loaded by this loader. Classes
49      * whose name starts with any of the strings
50      * in this array will be loaded by this class,
51      * unless their name appears in
52      * <code>excludedClasses</code>.
53      * Can be <code>null</code>
54      * @param excludedClasses array of class or package names that should NOT
55      * be directly loaded by this loader. Loading of
56      * classes whose name starts with any of the
57      * strings in this array will be delegated to
58      * <code>parent</code>, even if the classes
59      * package or classname appears in
60      * <code>includedClasses</code>. Typically this
61      * parameter is used to exclude loading one or
62      * more classes in a package whose other classes
63      * are loaded by this object.
64      * @param parent ClassLoader to which loading of classes should
65      * be delegated if necessary
66      */

67     public SelectedClassnameClassLoader(String JavaDoc[] includedClasses,
68                                  String JavaDoc[] excludedClasses,
69                                  ClassLoader JavaDoc parent) {
70         super(parent);
71         this.includedClasses = includedClasses;
72         this.excludedClasses = excludedClasses;
73     }
74
75     /**
76      * Creates a new classloader that loads the given classes.
77      *
78      * @param includedClasses array of class or package names that should be
79      * directly loaded by this loader. Classes
80      * whose name starts with any of the strings
81      * in this array will be loaded by this class,
82      * unless their name appears in
83      * <code>excludedClasses</code>.
84      * Can be <code>null</code>
85      * @param excludedClasses array of class or package names that should NOT
86      * be directly loaded by this loader. Loading of
87      * classes whose name starts with any of the
88      * strings in this array will be delegated to
89      * <code>parent</code>, even if the classes
90      * package or classname appears in
91      * <code>includedClasses</code>. Typically this
92      * parameter is used to exclude loading one or
93      * more classes in a package whose other classes
94      * are loaded by this object.
95      * @param notFoundClasses array of class or package names for which this
96      * should raise a ClassNotFoundException
97      * @param parent ClassLoader to which loading of classes should
98      * be delegated if necessary
99      */

100     public SelectedClassnameClassLoader(String JavaDoc[] includedClasses,
101                                  String JavaDoc[] excludedClasses,
102                                  String JavaDoc[] notFoundClasses,
103                                  ClassLoader JavaDoc parent) {
104         super(parent);
105         this.includedClasses = includedClasses;
106         this.excludedClasses = excludedClasses;
107         this.notFoundClasses = notFoundClasses;
108     }
109     
110     protected synchronized Class JavaDoc loadClass(String JavaDoc name, boolean resolve)
111     throws ClassNotFoundException JavaDoc
112     {
113         log.info("In SelectedClassnameClassLoader.loadClass("+name+","+resolve+")");
114         if (isIncluded(name) && (isExcluded(name) == false)) {
115             Class JavaDoc c = findClass(name);
116         
117             if (resolve) {
118                 resolveClass(c);
119             }
120             return c;
121         }
122         else {
123             return super.loadClass(name, resolve);
124         }
125     }
126     
127     protected Class JavaDoc findClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
128
129         log.info("In SelectedClassnameClassLoader.findClass()");
130         Class JavaDoc result = (Class JavaDoc)classes.get(name);
131         if(result != null){
132             return result;
133         }
134         
135         if (isIncluded(name) && (isExcluded(name) == false)) {
136             try {
137                 InputStream JavaDoc is = getResourceAsStream( name.replace('.','/').concat(".class"));
138                 byte[] bytes = new byte[1024];
139                 ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc(1024);
140                 int read;
141                 while ((read = is.read(bytes)) > -1) {
142                     baos.write(bytes, 0, read);
143                 }
144                 bytes = baos.toByteArray();
145                 result = this.defineClass(name, bytes, 0, bytes.length);
146             } catch (FileNotFoundException JavaDoc e) {
147                 throw new ClassNotFoundException JavaDoc("cannot find " + name, e);
148             } catch (IOException JavaDoc e) {
149                 throw new ClassNotFoundException JavaDoc("cannot read " + name, e);
150             }
151         }
152         else if (isNotFound(name)) {
153            throw new ClassNotFoundException JavaDoc(name + " is discarded");
154         }
155         else {
156             result = super.findClass(name);
157         }
158         
159         classes.put(name, result);
160         
161         return result;
162     }
163     
164     private boolean isIncluded(String JavaDoc className) {
165         
166         if (includedClasses != null) {
167             for (int i = 0; i < includedClasses.length; i++) {
168                 if (className.startsWith(includedClasses[i])) {
169                     return true;
170                 }
171             }
172         }
173         
174         return false;
175     }
176     
177     private boolean isExcluded(String JavaDoc className) {
178         
179         if (excludedClasses != null) {
180             for (int i = 0; i < excludedClasses.length; i++) {
181                 if (className.startsWith(excludedClasses[i])) {
182                     return true;
183                 }
184             }
185         }
186         
187         return false;
188     }
189     
190     private boolean isNotFound(String JavaDoc className) {
191         
192         if (notFoundClasses != null) {
193             for (int i = 0; i < notFoundClasses.length; i++) {
194                 if (className.startsWith(notFoundClasses[i])) {
195                     return true;
196                 }
197             }
198         }
199         
200         return false;
201     }
202 }
203
Popular Tags