Browse Source

Add capability to classfileset to specify the root classes

using a fileset


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272292 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 23 years ago
parent
commit
2c3767a537
4 changed files with 95 additions and 29 deletions
  1. +17
    -0
      docs/manual/OptionalTypes/classfileset.html
  2. +33
    -23
      src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
  3. +37
    -5
      src/main/org/apache/tools/ant/types/optional/depend/ClassfileSet.java
  4. +8
    -1
      src/main/org/apache/tools/ant/types/optional/depend/DependScanner.java

+ 17
- 0
docs/manual/OptionalTypes/classfileset.html View File

@@ -60,6 +60,14 @@ may be used
</tr> </tr>
</table> </table>


<h4>RootFileSet</h4>
<p>
A root fileset is used to add a set of root classes from a fileset. In this case the entries in
the fileset are expected to be Java class files. The name of the Java class is determined by the
relative location of the classfile in the fileset. So, the file
<code>org/apache/tools/ant/Project.class</code> corresponds to the Java class
<code>org.apache.tools.ant.Project</code>.</p>

<h4>Examples</h4> <h4>Examples</h4>
<blockquote><pre> <blockquote><pre>
&lt;classfileset id=&quot;reqdClasses" dir=&quot;${classes.dir}&quot;&gt; &lt;classfileset id=&quot;reqdClasses" dir=&quot;${classes.dir}&quot;&gt;
@@ -78,6 +86,15 @@ then be used to create a jar.
&lt;/jar&gt; &lt;/jar&gt;
</pre></blockquote> </pre></blockquote>


<blockquote><pre>
&lt;classfileset id=&quot;reqdClasses&quot; dir=&quot;${classes.dir}&quot;&gt;
&lt;rootfileset dir=&quot;${classes.dir}&quot; includes=&quot;org/apache/tools/ant/Project*.class&quot; /&gt;
&lt;/classfileset&gt;
</pre></blockquote>

<p>This example constructs the classfileset using all the class with names starting with Project
in the org.apache.tools.ant package</p>

<hr> <hr>
<p align="center">Copyright &copy; 2002 Apache Software Foundation. All rights <p align="center">Copyright &copy; 2002 Apache Software Foundation. All rights
Reserved.</p> Reserved.</p>


+ 33
- 23
src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java View File

@@ -86,16 +86,16 @@ public class Depend extends MatchingTask {
*/ */
private static class ClassFileInfo { private static class ClassFileInfo {
/** The file where the class file is stored in the file system */ /** The file where the class file is stored in the file system */
public File absoluteFile;
private File absoluteFile;


/** /**
* The location of the file relative to its base directory - the * The location of the file relative to its base directory - the
* root of the package namespace * root of the package namespace
*/ */
public String relativeName;
private String relativeName;


/** The Java class name of this class */ /** The Java class name of this class */
public String className;
private String className;
} }


/** The path where source files exist */ /** The path where source files exist */
@@ -142,9 +142,9 @@ public class Depend extends MatchingTask {
private Path dependClasspath; private Path dependClasspath;


/** constants used with the cache file */ /** constants used with the cache file */
private final static String CACHE_FILE_NAME = "dependencies.txt";
private static final String CACHE_FILE_NAME = "dependencies.txt";
/** String Used to separate classnames in the dependency file */ /** String Used to separate classnames in the dependency file */
private final static String CLASSNAME_PREPEND = "||:";
private static final String CLASSNAME_PREPEND = "||:";


/** /**
* Set the classpath to be used for this dependency check. * Set the classpath to be used for this dependency check.
@@ -292,7 +292,7 @@ public class Depend extends MatchingTask {
depCacheFileExists = depCacheFile.exists(); depCacheFileExists = depCacheFile.exists();
depCacheFileLastModified = depCacheFile.lastModified(); depCacheFileLastModified = depCacheFile.lastModified();
} }
for (Enumeration e = getClassFiles(destPath).elements(); e.hasMoreElements(); ) {
for (Enumeration e = getClassFiles(destPath).elements(); e.hasMoreElements();) {
ClassFileInfo info = (ClassFileInfo)e.nextElement(); ClassFileInfo info = (ClassFileInfo)e.nextElement();
log("Adding class info for " + info.className, Project.MSG_DEBUG); log("Adding class info for " + info.className, Project.MSG_DEBUG);
classFileInfoMap.put(info.className, info); classFileInfoMap.put(info.className, info);
@@ -300,8 +300,10 @@ public class Depend extends MatchingTask {
Vector dependencyList = null; Vector dependencyList = null;


if (cache != null) { if (cache != null) {
// try to read the dependency info from the map if it is not out of date
if (depCacheFileExists && depCacheFileLastModified > info.absoluteFile.lastModified()) {
// try to read the dependency info from the map if it is
// not out of date
if (depCacheFileExists
&& depCacheFileLastModified > info.absoluteFile.lastModified()) {
// depFile exists and is newer than the class file // depFile exists and is newer than the class file
// need to get dependency list from the map. // need to get dependency list from the map.
dependencyList = (Vector)dependencyMap.get(info.className); dependencyList = (Vector)dependencyMap.get(info.className);
@@ -333,7 +335,8 @@ public class Depend extends MatchingTask {
for (Enumeration depEnum = dependencyList.elements(); depEnum.hasMoreElements(); ) { for (Enumeration depEnum = dependencyList.elements(); depEnum.hasMoreElements(); ) {
String dependentClass = (String)depEnum.nextElement(); String dependentClass = (String)depEnum.nextElement();


Hashtable affectedClasses = (Hashtable)affectedClassMap.get(dependentClass);
Hashtable affectedClasses
= (Hashtable)affectedClassMap.get(dependentClass);
if (affectedClasses == null) { if (affectedClasses == null) {
affectedClasses = new Hashtable(); affectedClasses = new Hashtable();
affectedClassMap.put(dependentClass, affectedClasses); affectedClassMap.put(dependentClass, affectedClasses);
@@ -347,22 +350,25 @@ public class Depend extends MatchingTask {
if (dependClasspath != null) { if (dependClasspath != null) {
// now determine which jars each class depends upon // now determine which jars each class depends upon
classpathDependencies = new Hashtable(); classpathDependencies = new Hashtable();
AntClassLoader loader = new AntClassLoader(getProject(), dependClasspath);
AntClassLoader loader
= new AntClassLoader(getProject(), dependClasspath);


Hashtable classpathFileCache = new Hashtable(); Hashtable classpathFileCache = new Hashtable();
Object nullFileMarker = new Object(); Object nullFileMarker = new Object();
for (Enumeration e = dependencyMap.keys(); e.hasMoreElements(); ) {
for (Enumeration e = dependencyMap.keys(); e.hasMoreElements();) {
String className = (String)e.nextElement(); String className = (String)e.nextElement();
Vector dependencyList = (Vector)dependencyMap.get(className); Vector dependencyList = (Vector)dependencyMap.get(className);
Hashtable dependencies = new Hashtable(); Hashtable dependencies = new Hashtable();
classpathDependencies.put(className, dependencies); classpathDependencies.put(className, dependencies);
for (Enumeration e2 = dependencyList.elements(); e2.hasMoreElements(); ) {
for (Enumeration e2 = dependencyList.elements(); e2.hasMoreElements();) {
String dependency = (String)e2.nextElement(); String dependency = (String)e2.nextElement();
Object classpathFileObject = classpathFileCache.get(dependency);
Object classpathFileObject
= classpathFileCache.get(dependency);
if (classpathFileObject == null) { if (classpathFileObject == null) {
classpathFileObject = nullFileMarker; classpathFileObject = nullFileMarker;


if (!dependency.startsWith("java.") && !dependency.startsWith("javax.")) {
if (!dependency.startsWith("java.")
&& !dependency.startsWith("javax.")) {
URL classURL = loader.getResource(dependency.replace('.', '/') + ".class"); URL classURL = loader.getResource(dependency.replace('.', '/') + ".class");
if (classURL != null) { if (classURL != null) {
if (classURL.getProtocol().equals("jar")) { if (classURL.getProtocol().equals("jar")) {
@@ -406,10 +412,11 @@ public class Depend extends MatchingTask {
*/ */
private int deleteAllAffectedFiles() { private int deleteAllAffectedFiles() {
int count = 0; int count = 0;
for (Enumeration e = outOfDateClasses.elements(); e.hasMoreElements(); ) {
for (Enumeration e = outOfDateClasses.elements(); e.hasMoreElements();) {
String className = (String)e.nextElement(); String className = (String)e.nextElement();
count += deleteAffectedFiles(className); count += deleteAffectedFiles(className);
ClassFileInfo classInfo = (ClassFileInfo)classFileInfoMap.get(className);
ClassFileInfo classInfo
= (ClassFileInfo)classFileInfoMap.get(className);
if (classInfo != null && classInfo.absoluteFile.exists()) { if (classInfo != null && classInfo.absoluteFile.exists()) {
classInfo.absoluteFile.delete(); classInfo.absoluteFile.delete();
count++; count++;
@@ -430,7 +437,7 @@ public class Depend extends MatchingTask {


Hashtable affectedClasses = (Hashtable)affectedClassMap.get(className); Hashtable affectedClasses = (Hashtable)affectedClassMap.get(className);
if (affectedClasses != null) { if (affectedClasses != null) {
for (Enumeration e = affectedClasses.keys(); e.hasMoreElements(); ) {
for (Enumeration e = affectedClasses.keys(); e.hasMoreElements();) {
String affectedClassName = (String)e.nextElement(); String affectedClassName = (String)e.nextElement();
ClassFileInfo affectedClassInfo = (ClassFileInfo)affectedClasses.get(affectedClassName); ClassFileInfo affectedClassInfo = (ClassFileInfo)affectedClasses.get(affectedClassName);
if (affectedClassInfo.absoluteFile.exists()) { if (affectedClassInfo.absoluteFile.exists()) {
@@ -479,7 +486,8 @@ public class Depend extends MatchingTask {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
String[] srcPathList = srcPath.list(); String[] srcPathList = srcPath.list();
if (srcPathList.length == 0) { if (srcPathList.length == 0) {
throw new BuildException("srcdir attribute must be set!", location);
throw new BuildException("srcdir attribute must be set!",
location);
} }


if (destPath == null) { if (destPath == null) {
@@ -487,7 +495,8 @@ public class Depend extends MatchingTask {
} }


if (cache != null && cache.exists() && !cache.isDirectory()) { if (cache != null && cache.exists() && !cache.isDirectory()) {
throw new BuildException("The cache, if specified, must point to a directory");
throw new BuildException("The cache, if specified, must "
+ "point to a directory");
} }


if (cache != null && !cache.exists()) { if (cache != null && !cache.exists()) {
@@ -499,11 +508,11 @@ public class Depend extends MatchingTask {
if (dump) { if (dump) {
log("Reverse Dependency Dump for " + affectedClassMap.size() + log("Reverse Dependency Dump for " + affectedClassMap.size() +
" classes:", Project.MSG_DEBUG); " classes:", Project.MSG_DEBUG);
for (Enumeration e = affectedClassMap.keys(); e.hasMoreElements(); ) {
for (Enumeration e = affectedClassMap.keys(); e.hasMoreElements();) {
String className = (String)e.nextElement(); String className = (String)e.nextElement();
log(" Class " + className + " affects:", Project.MSG_DEBUG); log(" Class " + className + " affects:", Project.MSG_DEBUG);
Hashtable affectedClasses = (Hashtable)affectedClassMap.get(className); Hashtable affectedClasses = (Hashtable)affectedClassMap.get(className);
for (Enumeration e2 = affectedClasses.keys(); e2.hasMoreElements(); ) {
for (Enumeration e2 = affectedClasses.keys(); e2.hasMoreElements();) {
String affectedClass = (String)e2.nextElement(); String affectedClass = (String)e2.nextElement();
ClassFileInfo info = (ClassFileInfo)affectedClasses.get(affectedClass); ClassFileInfo info = (ClassFileInfo)affectedClasses.get(affectedClass);
log(" " + affectedClass + " in " + info.absoluteFile.getPath(), Project.MSG_DEBUG); log(" " + affectedClass + " in " + info.absoluteFile.getPath(), Project.MSG_DEBUG);
@@ -525,7 +534,8 @@ public class Depend extends MatchingTask {
} }


// we now need to scan for out of date files. When we have the list // we now need to scan for out of date files. When we have the list
// we go through and delete all class files which are affected by these files.
// we go through and delete all class files which are affected by
// these files.
outOfDateClasses = new Hashtable(); outOfDateClasses = new Hashtable();
for (int i = 0; i < srcPathList.length; i++) { for (int i = 0; i < srcPathList.length; i++) {
File srcDir = (File)project.resolveFile(srcPathList[i]); File srcDir = (File)project.resolveFile(srcPathList[i]);
@@ -538,7 +548,7 @@ public class Depend extends MatchingTask {


// now check classpath file dependencies // now check classpath file dependencies
if (classpathDependencies != null) { if (classpathDependencies != null) {
for (Enumeration e = classpathDependencies.keys(); e.hasMoreElements(); ) {
for (Enumeration e = classpathDependencies.keys(); e.hasMoreElements();) {
String className = (String)e.nextElement(); String className = (String)e.nextElement();
if (!outOfDateClasses.containsKey(className)) { if (!outOfDateClasses.containsKey(className)) {
ClassFileInfo info = (ClassFileInfo)classFileInfoMap.get(className); ClassFileInfo info = (ClassFileInfo)classFileInfoMap.get(className);


+ 37
- 5
src/main/org/apache/tools/ant/types/optional/depend/ClassfileSet.java View File

@@ -53,14 +53,12 @@
*/ */
package org.apache.tools.ant.types.optional.depend; package org.apache.tools.ant.types.optional.depend;




import java.util.Vector; import java.util.Vector;
import java.util.Enumeration;
import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.FileSet;



/** /**
* A ClassfileSet is a FileSet, that enlists all classes that depend on a * A ClassfileSet is a FileSet, that enlists all classes that depend on a
* certain set of root classes. * certain set of root classes.
@@ -79,6 +77,11 @@ public class ClassfileSet extends FileSet {
*/ */
private Vector rootClasses = new Vector(); private Vector rootClasses = new Vector();


/**
* The list of filesets which contain root classes
*/
private Vector rootFileSets = new Vector();
/** /**
* Inner class used to contain info about root classes * Inner class used to contain info about root classes
*/ */
@@ -104,13 +107,24 @@ public class ClassfileSet extends FileSet {
return rootClass; return rootClass;
} }
} }
/** /**
* Default constructor * Default constructor
*/ */
public ClassfileSet() { public ClassfileSet() {
} }
/**
* Add a fileset to which contains a collection of root classes used to
* drive the search from classes
*
* @param rootFileSet a root file set to be used to search for dependent
* classes
*/
public void addRootFileset(FileSet rootFileSet) {
rootFileSets.addElement(rootFileSet);
}
/** /**
* Create a ClassfileSet from another ClassfileSet * Create a ClassfileSet from another ClassfileSet
* *
@@ -142,10 +156,28 @@ public class ClassfileSet extends FileSet {
return getRef(p).getDirectoryScanner(p); return getRef(p).getDirectoryScanner(p);
} }


Vector allRootClasses = (Vector)rootClasses.clone();
for (Enumeration e = rootFileSets.elements(); e.hasMoreElements();) {
FileSet additionalRootSet = (FileSet)e.nextElement();
DirectoryScanner additionalScanner
= additionalRootSet.getDirectoryScanner(p);
String[] files = additionalScanner.getIncludedFiles();
for (int i = 0; i < files.length; ++i) {
if (files[i].endsWith(".class")) {
String classFilePath
= files[i].substring(0, files[i].length() - 6);
String className
= classFilePath.replace('/', '.').replace('\\', '.');
allRootClasses.addElement(className);
}
}
}
DirectoryScanner parentScanner = super.getDirectoryScanner(p); DirectoryScanner parentScanner = super.getDirectoryScanner(p);
DependScanner scanner = new DependScanner(parentScanner); DependScanner scanner = new DependScanner(parentScanner);
scanner.setBasedir(getDir(p)); scanner.setBasedir(getDir(p));
scanner.setRootClasses(rootClasses);
scanner.setRootClasses(allRootClasses);
scanner.scan(); scanner.scan();
return scanner; return scanner;
} }


+ 8
- 1
src/main/org/apache/tools/ant/types/optional/depend/DependScanner.java View File

@@ -99,6 +99,13 @@ public class DependScanner extends DirectoryScanner {
*/ */
private DirectoryScanner parentScanner; private DirectoryScanner parentScanner;
/**
* Create a DependScanner, using the given scanner to provide the basic
* set of files from which class files come.
*
* @param parentScanner the DirectoryScanner which returns the files from
* which class files must come.
*/
public DependScanner(DirectoryScanner parentScanner) { public DependScanner(DirectoryScanner parentScanner) {
this.parentScanner = parentScanner; this.parentScanner = parentScanner;
} }
@@ -161,7 +168,7 @@ public class DependScanner extends DirectoryScanner {
} }
analyzer.addClassPath(new Path(null, basedir.getPath())); analyzer.addClassPath(new Path(null, basedir.getPath()));
for (Enumeration e = rootClasses.elements(); e.hasMoreElements(); ) {
for (Enumeration e = rootClasses.elements(); e.hasMoreElements();) {
String rootClass = (String)e.nextElement(); String rootClass = (String)e.nextElement();
analyzer.addRootClass(rootClass); analyzer.addRootClass(rootClass);
} }


Loading…
Cancel
Save