KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > Closure


1 /*
2  * Closure.java
3  *
4  * The contents of this file are subject to the terms of the Common Development
5  * and Distribution License (the License). You may not use this file except in
6  * compliance with the License.
7  *
8  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
9  * or http://www.netbeans.org/cddl.txt.
10  *
11  * When distributing Covered Code, include this CDDL Header Notice in each file
12  * and include the License file at http://www.netbeans.org/cddl.txt.
13  * If applicable, add the following below the CDDL Header, with the fields
14  * enclosed by brackets [] replaced by your own identifying information:
15  * "Portions Copyrighted [year] [name of copyright owner]"
16  *
17  * The Original Software is NetBeans. The Initial Developer of the Original
18  * Software is Sun Microsystems, Inc. Portions Copyright 2000-2001 Sun
19  * Microsystems, Inc. All Rights Reserved.
20  *
21  * Contributor(s): Thomas Ball
22  *
23  * Version: $Revision: 1.4 $
24  */

25
26 import org.netbeans.modules.classfile.*;
27 import java.io.*;
28 import java.util.*;
29
30 /**
31  * Closure: report all classes which this file references in one
32  * way or another. Note: this utility won't find classes which are
33  * dynamically loaded.
34  *
35  * @author Thomas Ball
36  */

37 public class Closure {
38     String JavaDoc thisClass;
39     Set closure;
40
41     Closure(String JavaDoc spec) {
42         thisClass = spec;
43     }
44
45     void buildClosure(boolean includeJDK)
46       throws IOException {
47         if (closure != null)
48             return;
49         closure = new HashSet();
50         Set visited = new HashSet();
51         Stack stk = new Stack();
52         ClassName thisCN = ClassName.getClassName(thisClass.replace('.', '/'));
53         stk.push(thisCN);
54         visited.add(thisCN.getExternalName());
55
56         while (!stk.empty()) {
57             // Add class to closure.
58
ClassName cn = (ClassName)stk.pop();
59             InputStream is = findClassStream(cn.getType());
60         if (is == null) {
61         System.err.println("couldn't find class: " +
62                                    cn.getExternalName());
63         continue;
64         }
65             ClassFile cfile = new ClassFile(is);
66             closure.add(cfile.getName().getExternalName());
67             
68             ConstantPool pool = cfile.getConstantPool();
69             Iterator refs = pool.getAllClassNames().iterator();
70             while (refs.hasNext()) {
71                 ClassName cnRef = (ClassName)refs.next();
72                 String JavaDoc cname = cnRef.getExternalName();
73                 if (cname.indexOf('[') != -1) {
74                     // skip arrays
75
} else if (!includeJDK &&
76                            (cname.startsWith("java.") ||
77                             cname.startsWith("javax.") ||
78                             cname.startsWith("sun.") ||
79                             cname.startsWith("com.sun.corba") ||
80                             cname.startsWith("com.sun.image") ||
81                             cname.startsWith("com.sun.java.swing") ||
82                             cname.startsWith("com.sun.naming") ||
83                             cname.startsWith("com.sun.security"))) {
84                     // if directed, skip JDK references
85
} else {
86                     boolean isNew = visited.add(cname);
87                     if (isNew)
88                         stk.push(cnRef);
89                 }
90             }
91         }
92     }
93
94     void dumpClosure(PrintStream out) {
95         Iterator iter = new TreeSet(closure).iterator();
96         while (iter.hasNext())
97             out.println((String JavaDoc)iter.next());
98     }
99
100     Iterator dependencies() {
101         return closure.iterator();
102     }
103
104     private InputStream findClassStream(String JavaDoc className) {
105         InputStream is =
106             ClassLoader.getSystemClassLoader().getResourceAsStream(className + ".class");
107         return is;
108     }
109
110     /**
111      * An error routine which displays the command line usage
112      * before exiting.
113      */

114     public static void usage() {
115         System.err.println(
116             "usage: java Closure [-includejdk] <class> [ <class> ...]");
117         System.exit(1);
118     }
119
120     public static void main(String JavaDoc[] args) {
121         if (args.length == 0)
122             usage();
123
124         boolean includeJDK = false;
125         for (int i = 0; i < args.length; i++) {
126             if (args[i].equals("-includejdk"))
127                 includeJDK = true;
128             else if (args[i].charAt(0) == '-')
129                 usage();
130             else {
131                 try {
132                     Closure c = new Closure(args[i]);
133                     c.buildClosure(includeJDK);
134                     c.dumpClosure(System.out);
135                 } catch (IOException e) {
136                     System.err.println("error accessing \"" + args[i] +
137                                        "\": " + e.toString());
138                 }
139             }
140         }
141     }
142 }
143
Popular Tags