KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ca > commons > cbutil > CBClassLoader


1 package com.ca.commons.cbutil;
2
3 import java.io.InputStream JavaDoc;
4 import java.net.MalformedURLException JavaDoc;
5 import java.net.URL JavaDoc;
6 import java.util.Hashtable JavaDoc;
7 import java.util.logging.Logger JavaDoc;
8 import java.util.zip.ZipException JavaDoc;
9
10 /**
11  * Title: test
12  * Description: See if we can get this crappy IDE to work properly just once.
13  * Copyright: Copyright (c) 2001
14  * Company:
15  *
16  * @author Chris Betts
17  * @version 1.0
18  */

19
20 public class CBClassLoader extends ClassLoader JavaDoc
21 {
22
23     /**
24      * a cached list of classes to speed the return of twice loaded classes.
25      */

26
27     protected Hashtable JavaDoc classes = new Hashtable JavaDoc();
28     protected Hashtable JavaDoc lowerCaseClasses = new Hashtable JavaDoc();
29
30     /**
31      * The resource loader provides the interface to a group of zip files.
32      */

33
34     protected CBResourceLoader resourceLoader;
35
36
37     private static Logger JavaDoc log = Logger.getLogger(CBClassLoader.class.getName());
38
39     /**
40      * Constructor - note that that the class is useless until at least one resource file has been
41      * registered with it using the addResource() method.
42      */

43
44     public CBClassLoader(CBResourceLoader loader)
45     {
46         log.fine("Started CBClassLoader");
47
48         resourceLoader = loader;
49     }
50
51     /**
52      * Translates the '.' seperators of Class package names into the \ seperators needed for
53      * the internal directory structure of the zip file.
54      */

55
56     protected String JavaDoc translateClassName(String JavaDoc name)
57     {
58         if (name.endsWith(".class"))
59             name = name.replace('.', '/');
60         else
61             name = name.replace('.', '/') + ".class";
62
63         log.finer("looking for class: " + name);
64
65         return name;
66     }
67
68     /**
69      * This sample function for reading class implementations reads
70      * them from the local file system
71      */

72
73     private byte[] getClassFromResourceFiles(String JavaDoc className)
74             throws ZipException JavaDoc
75     {
76         className = translateClassName(className);
77         return resourceLoader.getResource(className);
78     }
79
80     /**
81      * This is a simple version for external clients since they
82      * will always want the class resolved before it is returned
83      * to them.
84      */

85     public Class JavaDoc findClass(String JavaDoc className) throws ClassNotFoundException JavaDoc
86     {
87         return (findClass(className, true));
88     }
89
90     void addClass(Class JavaDoc c)
91     {
92         log.finer("adding class " + c.toString());
93         // super.addClass(c);
94
}
95
96     /**
97      * This is the required version of findClass which is called
98      * both from findClass above and from the internal function
99      * loadClass of the parent.
100      */

101
102     public synchronized Class JavaDoc findClass(String JavaDoc className, boolean resolveIt)
103             throws ClassNotFoundException JavaDoc
104     {
105         Class JavaDoc result;
106         byte classData[];
107
108         log.finer(" >>>>>> Load class : " + className);
109
110         /* Check our local cache of classes */
111         Object JavaDoc local = classes.get(className);
112         if (local != null)
113         {
114             if (local instanceof String JavaDoc && "".equals((String JavaDoc) local))
115             {
116                 log.finer(" >>>>>> ignoring '" + className + "' (failed to load previously).");
117                 throw new ClassNotFoundException JavaDoc("ignoring class '" + className + "' (failed to load previously).");
118             }
119             log.finer(" >>>>>> returning cached result.");
120             return (Class JavaDoc) local;
121         }
122
123         /* Check with the primordial class loader */
124         try
125         {
126             result = super.findSystemClass(className);
127             log.finer(" >>>>>> returning system class (in CLASSPATH).");
128             return result;
129         }
130         catch (ClassNotFoundException JavaDoc e)
131         {
132             log.finer(" >>>>>> Not a system class - looking in zip files.");
133         }
134
135         /* Try to load it from our repository */
136         try
137         {
138             classData = getClassFromResourceFiles(className);
139         }
140         catch (ZipException JavaDoc e)
141         {
142             classes.put(className, ""); // stick a dummy entry in as a warning to others...
143
lowerCaseClasses.put(className.toLowerCase(), "");
144             throw new ClassNotFoundException JavaDoc("Error getting className: '" + className + "' : " + e);
145         }
146
147         if (classData == null)
148         {
149             classes.put(className, ""); // stick a dummy entry in as a warning to others...
150
lowerCaseClasses.put(className.toLowerCase(), "");
151             throw new ClassNotFoundException JavaDoc();
152         }
153
154         /* Define it (parse the class file) */
155         result = defineClass(className, classData, 0, classData.length);
156         if (result == null)
157         {
158             classes.put(className, ""); // stick a dummy entry in as a warning to others...
159
lowerCaseClasses.put(className.toLowerCase(), "");
160             throw new ClassFormatError JavaDoc();
161         }
162
163         if (resolveIt)
164         {
165             resolveClass(result);
166         }
167
168         classes.put(className, result);
169         lowerCaseClasses.put(className.toLowerCase(), result);
170         log.finer(" >>>>>> Returning newly loaded zipped class. " + className);
171         return result;
172     }
173
174     public URL JavaDoc getResource(String JavaDoc name)
175     {
176         URL JavaDoc bloop = super.getResource(name);
177         return bloop;
178     }
179
180     /**
181      * Returns a 'jar url' to the specified resource.
182      *
183      * @param name the name of the resource to look for (e.g. 'HelpSet.hs')
184      * @return the url of the resource, (e.g. 'jar:file:myjarfile.jar!/HelpSet.hs'.
185      * - this will be null if the resource cannot be found in the known
186      * jar file.
187      */

188
189     protected URL JavaDoc findResource(String JavaDoc name)
190     {
191         log.finer("CLASSLOADER MAGIC: looking for: " + name);
192         CBJarResource container = resourceLoader.getJarContainingResource(name);
193         log.finer("CLASSLOADER MAGIC: found container: " + ((container == null) ? "null" : container.getZipFileName()));
194         if (container == null)
195             return null;
196
197         String JavaDoc zipFile = container.getZipFileName();
198         String JavaDoc url = "jar:file:" + zipFile + "!/" + name;
199         log.finer("CLASSLOADER MAGIC: constructed url: " + url);
200
201         try
202         {
203             return new URL JavaDoc(url);
204         }
205         catch (MalformedURLException JavaDoc e)
206         {
207             log.warning("Unable to construct url: " + url + "\n -> due to " + e);
208             return null;
209         }
210     }
211
212     public String JavaDoc toString()
213     {
214         return "CBClassLoader";
215     }
216
217     public InputStream JavaDoc getResourceAsStream(String JavaDoc name)
218     {
219         return super.getResourceAsStream(name);
220     }
221
222 }
Popular Tags