aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java286
1 files changed, 286 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java
new file mode 100644
index 00000000..5c95d75b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.depend;
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.zip.ZipFile;
+
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.VectorSet;
+
+/**
+ * An abstract implementation of the analyzer interface providing support
+ * for the bulk of interface methods.
+ *
+ */
+public abstract class AbstractAnalyzer implements DependencyAnalyzer {
+ /** Maximum number of loops for looking for indirect dependencies. */
+ public static final int MAX_LOOPS = 1000;
+
+ /** The source path for the source files */
+ private Path sourcePath = new Path(null);
+
+ /** The classpath containg dirs and jars of class files */
+ private Path classPath = new Path(null);
+
+ /** The list of root classes */
+ private final Vector<String> rootClasses = new VectorSet<String>();
+
+ /** true if dependencies have been determined */
+ private boolean determined = false;
+
+ /** the list of File objects that the root classes depend upon */
+ private Vector<File> fileDependencies;
+ /** the list of java classes the root classes depend upon */
+ private Vector<String> classDependencies;
+
+ /** true if indirect dependencies should be gathered */
+ private boolean closure = true;
+
+ /** Setup the analyzer */
+ protected AbstractAnalyzer() {
+ reset();
+ }
+
+ /**
+ * Set the closure flag. If this flag is true the analyzer will traverse
+ * all class relationships until it has collected the entire set of
+ * direct and indirect dependencies
+ *
+ * @param closure true if dependencies should be traversed to determine
+ * indirect dependencies.
+ */
+ public void setClosure(boolean closure) {
+ this.closure = closure;
+ }
+
+ /**
+ * Get the list of files in the file system upon which the root classes
+ * depend. The files will be either the classfiles or jar files upon
+ * which the root classes depend.
+ *
+ * @return an enumeration of File instances.
+ */
+ public Enumeration<File> getFileDependencies() {
+ if (!supportsFileDependencies()) {
+ throw new RuntimeException("File dependencies are not supported "
+ + "by this analyzer");
+ }
+ if (!determined) {
+ determineDependencies(fileDependencies, classDependencies);
+ }
+ return fileDependencies.elements();
+ }
+
+ /**
+ * Get the list of classes upon which root classes depend. This is a
+ * list of Java classnames in dot notation.
+ *
+ * @return an enumeration of Strings, each being the name of a Java
+ * class in dot notation.
+ */
+ public Enumeration<String> getClassDependencies() {
+ if (!determined) {
+ determineDependencies(fileDependencies, classDependencies);
+ }
+ return classDependencies.elements();
+ }
+
+ /**
+ * Get the file that contains the class definition
+ *
+ * @param classname the name of the required class
+ * @return the file instance, zip or class, containing the
+ * class or null if the class could not be found.
+ * @exception IOException if the files in the classpath cannot be read.
+ */
+ public File getClassContainer(String classname) throws IOException {
+ String classLocation = classname.replace('.', '/') + ".class";
+ // we look through the classpath elements. If the element is a dir
+ // we look for the file. IF it is a zip, we look for the zip entry
+ return getResourceContainer(classLocation, classPath.list());
+ }
+
+ /**
+ * Get the file that contains the class source.
+ *
+ * @param classname the name of the required class
+ * @return the file instance, zip or java, containing the
+ * source or null if the source for the class could not be found.
+ * @exception IOException if the files in the sourcepath cannot be read.
+ */
+ public File getSourceContainer(String classname) throws IOException {
+ String sourceLocation = classname.replace('.', '/') + ".java";
+
+ // we look through the source path elements. If the element is a dir
+ // we look for the file. If it is a zip, we look for the zip entry.
+ // This isn't normal for source paths but we get it for free
+ return getResourceContainer(sourceLocation, sourcePath.list());
+ }
+
+ /**
+ * Add a source path to the source path used by this analyzer. The
+ * elements in the given path contain the source files for the classes
+ * being analyzed. Not all analyzers will use this information.
+ *
+ * @param sourcePath The Path instance specifying the source path
+ * elements.
+ */
+ public void addSourcePath(Path sourcePath) {
+ if (sourcePath == null) {
+ return;
+ }
+ this.sourcePath.append(sourcePath);
+ this.sourcePath.setProject(sourcePath.getProject());
+ }
+
+ /**
+ * Add a classpath to the classpath being used by the analyzer. The
+ * classpath contains the binary classfiles for the classes being
+ * analyzed The elements may either be the directories or jar files.Not
+ * all analyzers will use this information.
+ *
+ * @param classPath the Path instance specifying the classpath elements
+ */
+ public void addClassPath(Path classPath) {
+ if (classPath == null) {
+ return;
+ }
+
+ this.classPath.append(classPath);
+ this.classPath.setProject(classPath.getProject());
+ }
+
+ /**
+ * Add a root class. The root classes are used to drive the
+ * determination of dependency information. The analyzer will start at
+ * the root classes and add dependencies from there.
+ *
+ * @param className the name of the class in Java dot notation.
+ */
+ public void addRootClass(String className) {
+ if (className == null) {
+ return;
+ }
+ if (!rootClasses.contains(className)) {
+ rootClasses.addElement(className);
+ }
+ }
+
+ /**
+ * Configure an aspect of the analyzer. The set of aspects that are
+ * supported is specific to each analyzer instance.
+ *
+ * @param name the name of the aspect being configured
+ * @param info the configuration info.
+ */
+ public void config(String name, Object info) {
+ // do nothing by default
+ }
+
+ /**
+ * Reset the dependency list. This will reset the determined
+ * dependencies and the also list of root classes.
+ */
+ public void reset() {
+ rootClasses.removeAllElements();
+ determined = false;
+ fileDependencies = new Vector<File>();
+ classDependencies = new Vector<String>();
+ }
+
+ /**
+ * Get an enumeration of the root classes
+ *
+ * @return an enumeration of Strings, each of which is a class name
+ * for a root class.
+ */
+ protected Enumeration<String> getRootClasses() {
+ return rootClasses.elements();
+ }
+
+ /**
+ * Indicate if the analyzer is required to follow
+ * indirect class relationships.
+ *
+ * @return true if indirect relationships should be followed.
+ */
+ protected boolean isClosureRequired() {
+ return closure;
+ }
+
+ /**
+ * Determine the dependencies of the current set of root classes
+ *
+ * @param files a vector into which Files upon which the root classes
+ * depend should be placed.
+ * @param classes a vector of Strings into which the names of classes
+ * upon which the root classes depend should be placed.
+ */
+ protected abstract void determineDependencies(Vector<File> files, Vector<String> classes);
+
+ /**
+ * Indicate if the particular subclass supports file dependency
+ * information.
+ *
+ * @return true if file dependencies are supported.
+ */
+ protected abstract boolean supportsFileDependencies();
+
+ /**
+ * Get the file that contains the resource
+ *
+ * @param resourceLocation the name of the required resource.
+ * @param paths the paths which will be searched for the resource.
+ * @return the file instance, zip or class, containing the
+ * class or null if the class could not be found.
+ * @exception IOException if the files in the given paths cannot be read.
+ */
+ private File getResourceContainer(String resourceLocation, String[] paths)
+ throws IOException {
+ for (int i = 0; i < paths.length; ++i) {
+ File element = new File(paths[i]);
+ if (!element.exists()) {
+ continue;
+ }
+ if (element.isDirectory()) {
+ File resource = new File(element, resourceLocation);
+ if (resource.exists()) {
+ return resource;
+ }
+ } else {
+ // must be a zip of some sort
+ ZipFile zipFile = null;
+ try {
+ zipFile = new ZipFile(element);
+ if (zipFile.getEntry(resourceLocation) != null) {
+ return element;
+ }
+ } finally {
+ if (zipFile != null) {
+ zipFile.close();
+ }
+ }
+ }
+ }
+ return null;
+ }
+}
+