KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jodd > io > findfile > FindClass


1 // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
2

3 package jodd.io.findfile;
4
5 import jodd.util.StringUtil;
6 import jodd.util.Wildcard;
7
8 import java.net.URL JavaDoc;
9 import java.net.URI JavaDoc;
10 import java.net.URISyntaxException JavaDoc;
11 import java.util.zip.ZipFile JavaDoc;
12 import java.util.zip.ZipEntry JavaDoc;
13 import java.util.Enumeration JavaDoc;
14 import java.io.*;
15
16 /**
17  * Simple utility that scans <code>URL</code>s for classes.
18  * Its purpose is to help scanning class paths for some classes.
19  * Jar files are also examined.
20  */

21 public abstract class FindClass {
22
23     private static final String JavaDoc CLASS_FILE_EXT = ".class";
24
25     private static final String JavaDoc JAR_FILE_EXT = ".jar";
26
27     // ---------------------------------------------------------------- excluded jars
28

29     /**
30      * Array of jar file name patterns that are excluded from the search.
31      * By default java runtime libraries are excluded.
32      */

33     protected String JavaDoc[] excludedJars = new String JavaDoc[] {
34             "*/jre/lib/*.jar",
35             "*/jre/lib/ext/*.jar",
36             "*/tools.jar",
37             "*/j2ee.jar"
38     };
39
40
41     public String JavaDoc[] getExcludedJars() {
42         return excludedJars;
43     }
44
45     public void setExcludedJars(String JavaDoc[] excludedJars) {
46         this.excludedJars = excludedJars;
47     }
48
49     /**
50      * Array of jar file name patterns that are included in the search.
51      * This rule is applied after the excluded rule.
52      */

53     protected String JavaDoc[] includedJars = null;
54
55     public String JavaDoc[] getIncludedJars() {
56         return includedJars;
57     }
58
59     public void setIncludedJars(String JavaDoc[] includedJars) {
60         this.includedJars = includedJars;
61     }
62
63     // ---------------------------------------------------------------- included packages
64

65     /**
66      * Array of included package name patterns.
67      */

68     protected String JavaDoc[] includedPackages;
69
70     public String JavaDoc[] getIncludedPackages() {
71         return includedPackages;
72     }
73
74     public void setIncludedPackages(String JavaDoc[] includedPackages) {
75         this.includedPackages = includedPackages;
76     }
77
78     // ---------------------------------------------------------------- implementation
79

80     /**
81      * If set to <code>true</code>, input stream will be opened for each file.
82      */

83     protected boolean createInputStream = false;
84
85     public FindClass() {
86     }
87     
88     /**
89      * Scans single URL for classes and jar files.
90      * Callback {@link #onClassName(String, java.io.InputStream)} is called on
91      * each class name.
92      */

93     protected void scanUrl(URL JavaDoc url) throws IOException {
94         File JavaDoc file;
95         try {
96             file = new File JavaDoc(new URI JavaDoc(url.toString()));
97         } catch (URISyntaxException JavaDoc usex) {
98             throw new IOException(usex.toString());
99         }
100         String JavaDoc pathString = url.toString();
101         if (StringUtil.endsWithIgnoreCase(pathString, JAR_FILE_EXT) == true) {
102             if (excludedJars != null) {
103                 if (Wildcard.matchOne(pathString, excludedJars) != -1) {
104                     return;
105                 }
106             }
107             if (includedJars != null) {
108                 if (Wildcard.matchOne(pathString, includedJars) == -1) {
109                     return;
110                 }
111             }
112             scanJarFile(new ZipFile JavaDoc(file));
113         } else if (file.isDirectory() == true) {
114             scanClassPath(file);
115         }
116     }
117
118     /**
119      * Scans classes inside single JAR archive.
120      * Archive is scanned as a zip file.
121      * @see #onClassName(String, java.io.InputStream)
122      */

123     protected void scanJarFile(ZipFile JavaDoc zipFile) throws IOException {
124         Enumeration JavaDoc entries = zipFile.entries();
125         while (entries.hasMoreElements()) {
126             ZipEntry JavaDoc zipEntry = (ZipEntry JavaDoc) entries.nextElement();
127             String JavaDoc zipEntryName = zipEntry.getName();
128             if (StringUtil.endsWithIgnoreCase(zipEntryName, CLASS_FILE_EXT)) {
129                 scanClassName(zipEntryName, createInputStream == true ? zipFile.getInputStream(zipEntry) : null);
130             }
131         }
132     }
133
134     /**
135      * Scans single classpath directory.
136      * @see #onClassName(String, java.io.InputStream)
137      */

138     protected void scanClassPath(File JavaDoc root) throws FileNotFoundException {
139         //noinspection NonConstantStringShouldBeStringBuffer
140
String JavaDoc rootPath = root.getAbsolutePath();
141         if (rootPath.endsWith(File.separator) == false) {
142             rootPath += File.separatorChar;
143         }
144
145         FindFile ff = new FindFile().excludeDirs().recursive().searchPath(rootPath);
146         File JavaDoc file;
147         while ((file = ff.nextFile()) != null) {
148             String JavaDoc filePath = file.getAbsolutePath();
149             if (StringUtil.endsWithIgnoreCase(filePath, CLASS_FILE_EXT)) {
150                 if (StringUtil.startsWithIgnoreCase(filePath, rootPath) == true) {
151                     scanClassName(filePath.substring(rootPath.length()), createInputStream == true ? new FileInputStream(file) : null);
152                 }
153             }
154         }
155     }
156
157
158     /**
159      * Scans class name and calls {@link #onClassName(String, java.io.InputStream)} callback.
160      * Strips '.class' from the end and converts all slashes to dots.
161      */

162     protected void scanClassName(String JavaDoc name, InputStream inputStream) {
163         name = name.substring(0, name.length() - 6);
164         name = StringUtil.replace(name, '/', '.');
165         name = StringUtil.replace(name, '\\', '.');
166
167         if (includedPackages != null) {
168             if (Wildcard.matchOne(name, includedPackages) == -1) {
169                 return;
170             }
171         }
172         onClassName(name, inputStream);
173     }
174
175
176     // ---------------------------------------------------------------- callback
177

178     /**
179      * Called during scanning when class has been found.
180      * Provided class name is java-alike class name that may be
181      * immediatly used for dynamic loading.
182      * <code>InputStream</code> is availiable only when {@link #createInputStream} is set
183      * to <code>true</code> and may be used for reading class content for any reason.
184      */

185     protected abstract void onClassName(String JavaDoc className, InputStream inputStream);
186 }
187
Popular Tags