KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > util > depend > AbstractAnalyzer


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.util.depend;
19 import java.io.File JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.util.Enumeration JavaDoc;
22 import java.util.Vector JavaDoc;
23 import java.util.zip.ZipFile JavaDoc;
24 import org.apache.tools.ant.types.Path;
25
26 /**
27  * An abstract implementation of the analyzer interface providing support
28  * for the bulk of interface methods.
29  *
30  */

31 public abstract class AbstractAnalyzer implements DependencyAnalyzer {
32     /** Maximum number of loops for looking for indirect dependencies. */
33     public static final int MAX_LOOPS = 1000;
34
35     /** The source path for the source files */
36     private Path sourcePath = new Path(null);
37
38     /** The classpath containg dirs and jars of class files */
39     private Path classPath = new Path(null);
40
41     /** The list of root classes */
42     private Vector JavaDoc rootClasses = new Vector JavaDoc();
43
44     /** true if dependencies have been determined */
45     private boolean determined = false;
46
47     /** the list of File objects that the root classes depend upon */
48     private Vector JavaDoc fileDependencies;
49     /** the list of java classes the root classes depend upon */
50     private Vector JavaDoc classDependencies;
51
52     /** true if indirect dependencies should be gathered */
53     private boolean closure = true;
54
55     /** Setup the analyzer */
56     protected AbstractAnalyzer() {
57         reset();
58     }
59
60     /**
61      * Set the closure flag. If this flag is true the analyzer will traverse
62      * all class relationships until it has collected the entire set of
63      * direct and indirect dependencies
64      *
65      * @param closure true if dependencies should be traversed to determine
66      * indirect dependencies.
67      */

68     public void setClosure(boolean closure) {
69         this.closure = closure;
70     }
71
72     /**
73      * Get the list of files in the file system upon which the root classes
74      * depend. The files will be either the classfiles or jar files upon
75      * which the root classes depend.
76      *
77      * @return an enumeration of File instances.
78      */

79     public Enumeration JavaDoc getFileDependencies() {
80         if (!supportsFileDependencies()) {
81             throw new RuntimeException JavaDoc("File dependencies are not supported "
82                 + "by this analyzer");
83         }
84         if (!determined) {
85             determineDependencies(fileDependencies, classDependencies);
86         }
87         return fileDependencies.elements();
88     }
89
90     /**
91      * Get the list of classes upon which root classes depend. This is a
92      * list of Java classnames in dot notation.
93      *
94      * @return an enumeration of Strings, each being the name of a Java
95      * class in dot notation.
96      */

97     public Enumeration JavaDoc getClassDependencies() {
98         if (!determined) {
99             determineDependencies(fileDependencies, classDependencies);
100         }
101         return classDependencies.elements();
102     }
103
104     /**
105      * Get the file that contains the class definition
106      *
107      * @param classname the name of the required class
108      * @return the file instance, zip or class, containing the
109      * class or null if the class could not be found.
110      * @exception IOException if the files in the classpath cannot be read.
111      */

112     public File JavaDoc getClassContainer(String JavaDoc classname) throws IOException JavaDoc {
113         String JavaDoc classLocation = classname.replace('.', '/') + ".class";
114         // we look through the classpath elements. If the element is a dir
115
// we look for the file. IF it is a zip, we look for the zip entry
116
return getResourceContainer(classLocation, classPath.list());
117     }
118
119     /**
120      * Get the file that contains the class source.
121      *
122      * @param classname the name of the required class
123      * @return the file instance, zip or java, containing the
124      * source or null if the source for the class could not be found.
125      * @exception IOException if the files in the sourcepath cannot be read.
126      */

127     public File JavaDoc getSourceContainer(String JavaDoc classname) throws IOException JavaDoc {
128         String JavaDoc sourceLocation = classname.replace('.', '/') + ".java";
129
130         // we look through the source path elements. If the element is a dir
131
// we look for the file. If it is a zip, we look for the zip entry.
132
// This isn't normal for source paths but we get it for free
133
return getResourceContainer(sourceLocation, sourcePath.list());
134     }
135
136     /**
137      * Add a source path to the source path used by this analyzer. The
138      * elements in the given path contain the source files for the classes
139      * being analyzed. Not all analyzers will use this information.
140      *
141      * @param sourcePath The Path instance specifying the source path
142      * elements.
143      */

144     public void addSourcePath(Path sourcePath) {
145         if (sourcePath == null) {
146             return;
147         }
148         this.sourcePath.append(sourcePath);
149         this.sourcePath.setProject(sourcePath.getProject());
150     }
151
152     /**
153      * Add a classpath to the classpath being used by the analyzer. The
154      * classpath contains the binary classfiles for the classes being
155      * analyzed The elements may either be the directories or jar files.Not
156      * all analyzers will use this information.
157      *
158      * @param classPath the Path instance specifying the classpath elements
159      */

160     public void addClassPath(Path classPath) {
161         if (classPath == null) {
162             return;
163         }
164
165         this.classPath.append(classPath);
166         this.classPath.setProject(classPath.getProject());
167     }
168
169     /**
170      * Add a root class. The root classes are used to drive the
171      * determination of dependency information. The analyzer will start at
172      * the root classes and add dependencies from there.
173      *
174      * @param className the name of the class in Java dot notation.
175      */

176     public void addRootClass(String JavaDoc className) {
177         if (className == null) {
178             return;
179         }
180         if (!rootClasses.contains(className)) {
181             rootClasses.addElement(className);
182         }
183     }
184
185     /**
186      * Configure an aspect of the analyzer. The set of aspects that are
187      * supported is specific to each analyzer instance.
188      *
189      * @param name the name of the aspect being configured
190      * @param info the configuration info.
191      */

192     public void config(String JavaDoc name, Object JavaDoc info) {
193         // do nothing by default
194
}
195
196     /**
197      * Reset the dependency list. This will reset the determined
198      * dependencies and the also list of root classes.
199      */

200     public void reset() {
201         rootClasses.removeAllElements();
202         determined = false;
203         fileDependencies = new Vector JavaDoc();
204         classDependencies = new Vector JavaDoc();
205     }
206
207     /**
208      * Get an enumeration of the root classes
209      *
210      * @return an enumeration of Strings, each of which is a class name
211      * for a root class.
212      */

213     protected Enumeration JavaDoc getRootClasses() {
214         return rootClasses.elements();
215     }
216
217     /**
218      * Indicate if the analyzer is required to follow
219      * indirect class relationships.
220      *
221      * @return true if indirect relationships should be followed.
222      */

223     protected boolean isClosureRequired() {
224         return closure;
225     }
226
227     /**
228      * Determine the dependencies of the current set of root classes
229      *
230      * @param files a vector into which Files upon which the root classes
231      * depend should be placed.
232      * @param classes a vector of Strings into which the names of classes
233      * upon which the root classes depend should be placed.
234      */

235     protected abstract void determineDependencies(Vector JavaDoc files, Vector JavaDoc classes);
236
237     /**
238      * Indicate if the particular subclass supports file dependency
239      * information.
240      *
241      * @return true if file dependencies are supported.
242      */

243     protected abstract boolean supportsFileDependencies();
244
245     /**
246      * Get the file that contains the resource
247      *
248      * @param resourceLocation the name of the required resource.
249      * @param paths the paths which will be searched for the resource.
250      * @return the file instance, zip or class, containing the
251      * class or null if the class could not be found.
252      * @exception IOException if the files in the given paths cannot be read.
253      */

254     private File JavaDoc getResourceContainer(String JavaDoc resourceLocation, String JavaDoc[] paths)
255          throws IOException JavaDoc {
256         for (int i = 0; i < paths.length; ++i) {
257             File JavaDoc element = new File JavaDoc(paths[i]);
258             if (!element.exists()) {
259                 continue;
260             }
261             if (element.isDirectory()) {
262                 File JavaDoc resource = new File JavaDoc(element, resourceLocation);
263                 if (resource.exists()) {
264                     return resource;
265                 }
266             } else {
267                 // must be a zip of some sort
268
ZipFile JavaDoc zipFile = null;
269                 try {
270                     zipFile = new ZipFile JavaDoc(element);
271                     if (zipFile.getEntry(resourceLocation) != null) {
272                         return element;
273                     }
274                 } finally {
275                     if (zipFile != null) {
276                         zipFile.close();
277                     }
278                 }
279             }
280         }
281         return null;
282     }
283 }
284
285
Popular Tags