KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > theshoemakers > which4j > Which4J


1 /*
2
3 Copyright (c) 2003, theshoemakers.org
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without modification,
7 are permitted provided that the following conditions are met:
8
9     * Redistributions of source code must retain the above copyright notice, this
10       list of conditions and the following disclaimer.
11     * Redistributions in binary form must reproduce the above copyright notice,
12       this list of conditions and the following disclaimer in the documentation
13       and/or other materials provided with the distribution.
14     * Neither the name of the theshoemakers.org nor the names of its contributors
15       may be used to endorse or promote products derived from this software without
16       specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
27 OF SUCH DAMAGE.
28
29 */

30
31 package org.theshoemakers.which4j;
32
33 import java.io.File JavaDoc;
34 import java.net.URL JavaDoc;
35 import java.net.URLClassLoader JavaDoc;
36 import java.util.Properties JavaDoc;
37 import java.util.StringTokenizer JavaDoc;
38
39 /**
40  * Find occurrencens of a particular classname in the system classpath
41  * or the specified ClassLoader.
42  *
43  * This class can be run in command-line mode to search your system
44  * classpath for all occurrences of the specified classname.
45  *
46  * This class can also be used programmatically to search a particular
47  * ClassLoader for the first occurrence of the specified classname.
48  * <p>
49  * Revision: $Revision: 1.3 $
50  *
51  * @author <a HREF="mailto:Ryan.Shoemaker@Sun.COM">Ryan Shoemaker</a>, Sun Microsystems, Inc.
52  * @version 0.1
53  */

54 public class Which4J {
55
56     private static boolean debug = false;
57
58     /**
59      * Main method used in command-line mode for searching the system
60      * classpath for <em>all</em> occurrences of the specified classname.
61      *
62      * @param args command-line arguments (run "<code>java org.theshoemakers.tools.which4j.Which4J
63      * -help</code>" for a detailed description).
64      */

65     public static void main(String JavaDoc[] args) {
66         String JavaDoc s = System.getProperty("line.separator");
67         if (args.length == 2) {
68             if (args[0].equals("-debug")) {
69                 debug = true;
70                 findIt(args[1]);
71             } else {
72                 System.err.println(
73                     "error: unrecognized \"" + args[0] + "\" option ");
74                 System.exit(-1);
75             }
76         } else if (args.length == 1 && args[0].equals("-help")) {
77             usage();
78         } else if (args.length == 1) {
79             findIt(args[0]);
80         } else {
81             usage();
82         }
83
84         System.exit(0);
85     }
86
87     private static void usage() {
88         System.err.println(
89             "usage: java Which4J [-debug] <classname>"
90                 + "\n\tThe commandline version of Which4J will search the system"
91                 + "\n\tclasspath defined in your environment for all occurences"
92                 + "\n\tof the class. Alternatively, you can use this class"
93                 + "\n\tprogrammatically to search the current (or any) ClassLoader."
94                 + "\n\tSee the javadoc for more detail."
95                 + "\n\t"
96                 + "\n\tNote: if the name of the jar file listed after \"found in:\""
97                 + "\n\tdoesn't match the name of the jar listed next to \"url:\", then "
98                 + "\n\tthere is likely a \"Class-Path\" entry in the jar manifest "
99                 + "\n\tthat is causing the classloader to indirectly find the class.");
100         System.exit(-1);
101     }
102
103     /**
104      * Iterate over the system classpath defined by "java.class.path" searching
105      * for all occurrances of the given class name.
106      *
107      * @param classname the fully qualified class name to search for
108      */

109     private static void findIt(String JavaDoc classname) {
110
111         try {
112             // get the system classpath
113
String JavaDoc classpath = System.getProperty("java.class.path", "");
114
115             if (classpath.equals("")) {
116                 System.err.println("error: classpath is not set");
117             }
118
119             if (debug) {
120                 System.out.println("classname: " + classname);
121                 System.out.println("system classpath = " + classpath);
122             }
123
124             if (isPrimitiveOrVoid(classname)) {
125                 System.out.println("'" + classname + "' primitive");
126                 return;
127             }
128
129             StringTokenizer JavaDoc st =
130                 new StringTokenizer JavaDoc(classpath, File.pathSeparator);
131
132             String JavaDoc classnameAsResource = classname.replace('.', '/') + ".class";
133             boolean checkSystemClassLoader = true;
134             
135             while (st.hasMoreTokens()) {
136                 String JavaDoc token = st.nextToken();
137                 File JavaDoc classpathElement = new File JavaDoc(token);
138
139                 if (debug)
140                     System.out.println(
141                         classpathElement.isDirectory()
142                             ? "dir: " + token
143                             : "jar: " + token);
144
145                 URL JavaDoc[] url = { classpathElement.toURL()};
146
147                 URLClassLoader JavaDoc cl = URLClassLoader.newInstance(url, null);
148
149                 URL JavaDoc it = cl.findResource(classnameAsResource);
150                 if (it != null) {
151                     checkSystemClassLoader = false;
152                     System.out.println("found in: " + token);
153                     System.out.println(" url: " + it.toString());
154                     System.out.println("");
155                 }
156             }
157             
158             if (checkSystemClassLoader) {
159                 URL JavaDoc it = ClassLoader.getSystemResource(classnameAsResource);
160                 if (it != null) {
161                     checkSystemClassLoader = false;
162                     System.out.println("found in url: " + it.toString());
163                     System.out.println("");
164                 }
165             }
166         } catch (Exception JavaDoc e) {
167             e.printStackTrace();
168         }
169     }
170
171     /**
172      * Search the current classloader for the given classname.
173      *
174      * Equivalent to calling which( String classname, Which4J.class.getClassLoader ).
175      *
176      * @param classname the fully qualified name of the class to search for
177      * @return the source location of the resource, or null if it wasn't found
178      */

179     public static String JavaDoc which(String JavaDoc classname) {
180         return which(classname, Which4J.class.getClassLoader());
181     }
182
183     /**
184      * Search the specified classloader for the given classname.
185      *
186      * @param classname the fully qualified name of the class to search for
187      * @param loader the classloader to search
188      * @return the source location of the resource, or null if it wasn't found
189      */

190     public static String JavaDoc which(String JavaDoc classname, ClassLoader JavaDoc loader) {
191
192         if (isArrayType(classname)) {
193             classname = getElementType(classname);
194         }
195
196         if (isPrimitiveOrVoid(classname)) {
197             return "'" + classname + "' primitive";
198         }
199
200         String JavaDoc classnameAsResource = classname.replace('.', '/') + ".class";
201
202         if (loader == null) {
203             // some VM's return null from getClassLoader to indicate that
204
// the class was loaded by the bootstrap class loader
205
loader = ClassLoader.getSystemClassLoader();
206         }
207         URL JavaDoc it = loader.getResource(classnameAsResource);
208         if (it != null) {
209             return it.toString();
210         } else {
211             return null;
212         }
213     }
214
215     /**
216      * Search the current classloader for the given classname.
217      *
218      * Equivalent to calling which( Class clazz, Which4J.class.getClassLoader ).
219      *
220      * @param clazz the class object to search for
221      * @return the source location of the resource, or null if it wasn't found
222      */

223     public static String JavaDoc which(Class JavaDoc clazz) {
224         return which(clazz, clazz.getClassLoader());
225     }
226
227     /**
228      * Search the specified classloader for the given class object.
229      *
230      * @param clazz the class object to search for
231      * @param loader the classloader to search
232      * @return the source location of the resource, or null if it wasn't found
233      */

234     public static String JavaDoc which(Class JavaDoc clazz, ClassLoader JavaDoc loader) {
235         return which(clazz.getName(), loader);
236     }
237
238     /**
239      * Determine if the class name corresponds to a primitive Java datatype or
240      * the void datatype.
241      *
242      * @param classname the name of the class
243      * @return true iff the classname corresponds to a primitive Java datatype
244      * or the void datatype, false otherwise.
245      */

246     private static boolean isPrimitiveOrVoid(String JavaDoc classname) {
247         return (
248             classname.equals("boolean")
249                 || classname.equals("byte")
250                 || classname.equals("char")
251                 || classname.equals("double")
252                 || classname.equals("float")
253                 || classname.equals("int")
254                 || classname.equals("long")
255                 || classname.equals("short")
256                 || classname.equals("void"));
257     }
258
259     /**
260      * Determine if the classname corresponds to an array type as defined by
261      * the Java Language Specification.
262      *
263      * @param classname the name of the class
264      * @return true iff the classname corresponds to an array type, false
265      * otherwise.
266      */

267     private static boolean isArrayType(String JavaDoc classname) {
268         return classname.startsWith("[");
269     }
270
271     /**
272      * Determine the element type of the array type. This can be the name
273      * of a primitive type or the fully qualified class name of a non primitive
274      * type.
275      *
276      * @param classname the array type
277      * @return the name of the base element type.
278      */

279     private static String JavaDoc getElementType(String JavaDoc classname) {
280         // remove leading '['
281
String JavaDoc elementType = classname.split("^\\[+")[1];
282         char encoding = elementType.charAt(0);
283
284         if (encoding == 'L') {
285             // don't include the first char 'L' or last char ';'
286
return elementType.substring(1, elementType.length() - 1);
287         } else if (encoding == 'Z') {
288             return "boolean";
289         } else if (encoding == 'B') {
290             return "byte";
291         } else if (encoding == 'C') {
292             return "char";
293         } else if (encoding == 'D') {
294             return "double";
295         } else if (encoding == 'F') {
296             return "float";
297         } else if (encoding == 'I') {
298             return "int";
299         } else if (encoding == 'J') {
300             return "long";
301         } else if (encoding == 'S') {
302             return "short";
303         } else {
304             throw new InternalError JavaDoc(
305                 "unknown array type: '"
306                     + encoding
307                     + "'.\nplease file a bug report at http://which4j.dev.java.net");
308         }
309     }
310
311 }
312
Popular Tags