1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.river.tool.classdepend;
19
20 import java.io.File;
21 import java.io.FileFilter;
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.util.Enumeration;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.Set;
28 import java.util.SortedSet;
29 import java.util.StringTokenizer;
30 import java.util.TreeSet;
31 import java.util.jar.JarEntry;
32 import java.util.jar.JarFile;
33
34
35 public class PackageClasses {
36
37
38 private final Set directories = new HashSet();
39
40
41 private final Set jarContents = new HashSet();
42
43
44
45
46
47
48
49
50
51
52
53 public static void main(String[] args) throws IOException {
54 String classpath;
55 if (args.length == 1) {
56 classpath = System.getProperty("java.class.path");
57 } else if (args.length == 2) {
58 classpath = args[1];
59 } else {
60 throw new IllegalArgumentException(
61 "Usage: java " + PackageClasses.class.getName() +
62 " package [classpath]");
63 }
64 PackageClasses pc = new PackageClasses(classpath);
65 SortedSet classes = new TreeSet(pc.compute(args[0]));
66 Iterator classesIter = classes.iterator();
67 while (classesIter.hasNext()) {
68 System.out.println(classesIter.next());
69 }
70 }
71
72
73
74
75
76
77
78
79
80
81
82
83
84 public PackageClasses(String classpath) throws IOException {
85 if (classpath == null) {
86 throw new NullPointerException("The classpath cannot be null");
87 }
88 StringTokenizer tokens =
89 new StringTokenizer(classpath, File.pathSeparator);
90 while (tokens.hasMoreTokens()) {
91 String token = tokens.nextToken();
92 if (token.equals("")) {
93 token = ".";
94 }
95 File file = new File(token);
96 if (!file.exists()) {
97 throw new FileNotFoundException(
98 "File or directory not found: " + file);
99 } else if (file.isDirectory()) {
100 String path = file.getPath();
101 if (!path.endsWith(File.separator)) {
102 path += File.separator;
103 }
104 directories.add(path);
105 } else {
106 JarFile jarFile;
107 try {
108 jarFile = new JarFile(file);
109 } catch (IOException e) {
110 throw new IOException(
111 "Problem accessing file or directory: " + file, e);
112 }
113 try {
114 for (Enumeration entries = jarFile.entries();
115 entries.hasMoreElements(); )
116 {
117 JarEntry entry = (JarEntry) entries.nextElement();
118 jarContents.add(entry.getName());
119 }
120 } finally {
121 try {
122 jarFile.close();
123 } catch (IOException e) {
124 }
125 }
126 }
127 }
128 }
129
130
131
132
133
134
135
136
137
138
139 public Set compute(String[] packages)
140 throws IOException
141 {
142 return compute(false, packages);
143 }
144
145 public Set compute(String packAge)
146 throws IOException
147 {
148 String [] packages = {packAge};
149 return compute(false, packages);
150 }
151
152
153
154
155
156
157
158
159
160
161
162
163 public Set compute(boolean recurse, String[] packages)
164 throws IOException
165 {
166 if (packages == null) {
167 throw new NullPointerException(
168 "The packages argument cannot be null");
169 }
170 Set classes = new HashSet();
171 int l = packages.length;
172 for (int i = 0 ; i < l ; i++) {
173 String pkg = packages[i];
174 if (pkg == null) {
175 throw new NullPointerException(
176 "Elements of the packages argument cannot be null");
177 }
178 String pkgFileName = pkg.replace('.', File.separatorChar);
179 if (!"".equals(pkgFileName)) {
180 pkgFileName += File.separatorChar;
181 }
182 Iterator dirIter = directories.iterator();
183 while (dirIter.hasNext()) {
184 String dir = (String) dirIter.next();
185 File file = new File(dir, pkgFileName);
186 if (file.exists()) {
187 collectClasses(file, recurse, pkg, classes);
188 }
189 }
190
191 if (File.separatorChar != '/') {
192 pkgFileName = pkgFileName.replace(File.separatorChar, '/');
193 }
194 Iterator jarContentIter = jarContents.iterator();
195 while (jarContentIter.hasNext()) {
196 String file = (String) jarContentIter.next();
197 if (file.startsWith(pkgFileName) && file.endsWith(".class")) {
198 file = removeDotClass(file);
199 if (recurse ||
200 file.indexOf('/', pkgFileName.length() + 1) < 0)
201 {
202
203
204
205
206
207
208 classes.add(file.replace('/', '.'));
209 }
210 }
211 }
212 }
213 return classes;
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227 public Set compute(boolean recurse, String packAge)
228 throws IOException
229 {
230 String [] packages = {packAge};
231 return compute(recurse, packages);
232 }
233
234
235
236
237
238 private static void collectClasses(File directory,
239 final boolean recurse,
240 final String pkg,
241 final Set classes)
242 throws IOException
243 {
244 final IOException[] failed = { null };
245 File[] result = directory.listFiles(new FileFilter() {
246 public boolean accept(File child) {
247 String name = child.getName();
248 if (name != null) {
249 if (name.endsWith(".class") && child.isFile()) {
250 String classname = removeDotClass(name);
251 if (!"".equals(pkg)) {
252 classname = pkg + '.' + classname;
253 }
254 classes.add(classname);
255 } else if (recurse && child.isDirectory()) {
256 String subpackage =
257 "".equals(pkg) ? name : pkg + '.' + name;
258 try {
259 collectClasses(
260 child, recurse, subpackage, classes);
261 } catch (IOException e) {
262 failed[0] = e;
263 }
264 }
265 }
266 return false;
267 }
268 });
269 if (failed[0] != null) {
270 throw failed[0];
271 } else if (result == null) {
272 throw new IOException(
273 "A problem occurred accessing directory: " + directory);
274 }
275 }
276
277
278 private static String removeDotClass(String s) {
279 return s.substring(0, s.length() - 6);
280 }
281 }