001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.tools.ant.taskdefs.optional.depend;
019:
020: import java.io.File;
021: import java.io.FileInputStream;
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.util.Enumeration;
025: import java.util.Hashtable;
026: import java.util.Vector;
027: import java.util.zip.ZipEntry;
028: import java.util.zip.ZipFile;
029: import org.apache.tools.ant.util.depend.AbstractAnalyzer;
030:
031: /**
032: * An analyzer which uses the depend task's bytecode classes to analyze
033: * dependencies
034: *
035: */
036: public class AntAnalyzer extends AbstractAnalyzer {
037: /**
038: * Default constructor
039: */
040: public AntAnalyzer() {
041: }
042:
043: /**
044: * Determine the dependencies of the configured root classes.
045: *
046: * @param files a vector to be populated with the files which contain
047: * the dependency classes
048: * @param classes a vector to be populated with the names of the
049: * dependency classes.
050: */
051: protected void determineDependencies(Vector files, Vector classes) {
052: // we get the root classes and build up a set of
053: // classes upon which they depend
054: Hashtable dependencies = new Hashtable();
055: Hashtable containers = new Hashtable();
056: Hashtable toAnalyze = new Hashtable();
057: for (Enumeration e = getRootClasses(); e.hasMoreElements();) {
058: String classname = (String) e.nextElement();
059: toAnalyze.put(classname, classname);
060: }
061:
062: int count = 0;
063: int maxCount = isClosureRequired() ? MAX_LOOPS : 1;
064: Hashtable analyzedDeps = null;
065: while (toAnalyze.size() != 0 && count++ < maxCount) {
066: analyzedDeps = new Hashtable();
067: for (Enumeration e = toAnalyze.keys(); e.hasMoreElements();) {
068: String classname = (String) e.nextElement();
069: dependencies.put(classname, classname);
070: try {
071: File container = getClassContainer(classname);
072: if (container == null) {
073: continue;
074: }
075: containers.put(container, container);
076:
077: ZipFile zipFile = null;
078: InputStream inStream = null;
079: try {
080: if (container.getName().endsWith(".class")) {
081: inStream = new FileInputStream(container
082: .getPath());
083: } else {
084: zipFile = new ZipFile(container.getPath());
085: String entryName = classname.replace('.',
086: '/')
087: + ".class";
088: ZipEntry entry = new ZipEntry(entryName);
089: inStream = zipFile.getInputStream(entry);
090: }
091: ClassFile classFile = new ClassFile();
092: classFile.read(inStream);
093: Vector dependencyList = classFile
094: .getClassRefs();
095: Enumeration depEnum = dependencyList.elements();
096: while (depEnum.hasMoreElements()) {
097: String dependency = (String) depEnum
098: .nextElement();
099: analyzedDeps.put(dependency, dependency);
100: }
101: } finally {
102: if (inStream != null) {
103: inStream.close();
104: }
105: if (zipFile != null) {
106: zipFile.close();
107: }
108: }
109: } catch (IOException ioe) {
110: // ignore
111: }
112: }
113:
114: toAnalyze.clear();
115:
116: // now recover all the dependencies collected and add to the list.
117: Enumeration depsEnum = analyzedDeps.elements();
118: while (depsEnum.hasMoreElements()) {
119: String className = (String) depsEnum.nextElement();
120: if (!dependencies.containsKey(className)) {
121: toAnalyze.put(className, className);
122: }
123: }
124: }
125:
126: // pick up the last round of dependencies that were determined
127: Enumeration depsEnum = analyzedDeps.elements();
128: while (depsEnum.hasMoreElements()) {
129: String className = (String) depsEnum.nextElement();
130: dependencies.put(className, className);
131: }
132:
133: files.removeAllElements();
134: for (Enumeration e = containers.keys(); e.hasMoreElements();) {
135: files.addElement((File) e.nextElement());
136: }
137:
138: classes.removeAllElements();
139: for (Enumeration e = dependencies.keys(); e.hasMoreElements();) {
140: classes.addElement((String) e.nextElement());
141: }
142: }
143:
144: /**
145: * Indicate if this analyzer can determine dependent files.
146: *
147: * @return true if the analyzer provides dependency file information.
148: */
149: protected boolean supportsFileDependencies() {
150: return true;
151: }
152:
153: }
|