conor 02/04/09 06:20:09
Modified: src/etc/testcases/taskdefs/optional/depend depend.xml
src/main/org/apache/tools/ant/taskdefs/optional/depend
Depend.java
src/testcases/org/apache/tools/ant/taskdefs/optional/depend
DependTest.java
Added: src/etc/testcases/taskdefs/optional/depend/src5 A.java
B.java
Log:
Add a check in depend so that if a class file is out of date and the
source file cannot be determined, the class is not deleted and a warning
is given.
PR: 7312
Revision Changes Path
1.8 +15 -0
jakarta-ant/src/etc/testcases/taskdefs/optional/depend/depend.xml
Index: depend.xml
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/etc/testcases/taskdefs/optional/depend/depend.xml,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -w -u -r1.7 -r1.8
--- depend.xml 9 Apr 2002 03:51:19 -0000 1.7
+++ depend.xml 9 Apr 2002 13:20:08 -0000 1.8
@@ -5,6 +5,7 @@
<property name="src2.dir" value="src2"/>
<property name="src3.dir" value="src3"/>
<property name="src4.dir" value="src4"/>
+ <property name="src5.dir" value="src5"/>
<property name="tempsrc.dir" value="working"/>
<property name="cache.dir" value="working"/>
@@ -41,6 +42,12 @@
</copy>
</target>
+ <target name="src5setup" depends="basesetup">
+ <copy todir="${tempsrc.dir}">
+ <fileset dir="${src5.dir}"/>
+ </copy>
+ </target>
+
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${tempsrc.dir}" destdir="${classes.dir}"/>
@@ -136,5 +143,13 @@
destdir="${classes.dir}" closure="yes"/>
<depend cache="${cache.dir}" srcdir="${tempsrc.dir}"
destdir="${classes.dir}" closure="yes"/>
+ </target>
+
+ <target name="testnonpublic" depends="src5setup, compile">
+ <sleep seconds="3"/>
+ <delete file="${tempsrc.dir}/B.java"/>
+ <copy file="${src2.dir}/B.java" tofile="${tempsrc.dir}/B.java"/>
+ <depend srcdir="${tempsrc.dir}" destdir="${classes.dir}" closure="yes"/>
+ <fileset id="result" dir="${classes.dir}"/>
</target>
</project>
1.1
jakarta-ant/src/etc/testcases/taskdefs/optional/depend/src5/A.java
Index: A.java
===================================================================
public class A {
APrivate dependency = new APrivate();
}
class APrivate extends B {
}
1.1
jakarta-ant/src/etc/testcases/taskdefs/optional/depend/src5/B.java
Index: B.java
===================================================================
public class B {
}
1.23 +149 -93
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
Index: Depend.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -w -u -r1.22 -r1.23
--- Depend.java 9 Apr 2002 11:20:51 -0000 1.22
+++ Depend.java 9 Apr 2002 13:20:08 -0000 1.23
@@ -95,14 +95,14 @@
/** The file where the class file is stored in the file system */
private File absoluteFile;
- /**
- * The location of the file relative to its base directory - the
- * root of the package namespace
- */
- private String relativeName;
-
/** The Java class name of this class */
private String className;
+
+ /** The source File containing this class */
+ private File sourceFile;
+
+ /** if user has been warned about this file not having a source file
*/
+ private boolean isUserWarned = false;
}
/** The path where source files exist */
@@ -114,8 +114,11 @@
/** The directory which contains the dependency cache. */
private File cache;
+ /** The list of source paths derived from the srcPath field. */
+ private String[] srcPathList;
+
/**
- * A map which gives for every class a list of te class which it
+ * A map which gives for every class a list of the class which it
* affects.
*/
private Hashtable affectedClassMap;
@@ -204,13 +207,10 @@
* @return a collection of class dependencies
* @exception IOException if the dependnecy file cannot be read
*/
- private Hashtable readCachedDependencies() throws IOException {
+ private Hashtable readCachedDependencies(File depFile) throws
IOException {
Hashtable dependencyMap = new Hashtable();
- if (cache != null) {
- File depFile = new File(cache, CACHE_FILE_NAME);
BufferedReader in = null;
- if (depFile.exists()) {
try {
in = new BufferedReader(new FileReader(depFile));
String line = null;
@@ -231,8 +231,6 @@
in.close();
}
}
- }
- }
return dependencyMap;
}
@@ -277,9 +275,19 @@
/**
* Determine the dependencies between classes. Class dependencies are
* determined by examining the class references in a class file to other
- * classes
+ * classes.
+ *
+ * This method sets up the following fields
+ * <ul>
+ * <li>affectedClassMap - the list of classes each class affects</li>
+ * <li>classFileInfoMap - information about each class</li>
+ * <li>classpathDependencies - the list of jars and classes from the
+ * classpath that each class depends
upon.</li>
+ * </ul>
+ *
+ * If required, the dependencies are written to the cache.
*
- * @exception IOException if either the dependnecies cache or the class
+ * @exception IOException if either the dependencies cache or the class
* files cannot be read or written
*/
private void determineDependencies() throws IOException {
@@ -288,16 +296,18 @@
boolean cacheDirty = false;
Hashtable dependencyMap = new Hashtable();
- File depCacheFile = null;
- boolean depCacheFileExists = true;
- long depCacheFileLastModified = Long.MAX_VALUE;
+ File cacheFile = null;
+ boolean cacheFileExists = true;
+ long cacheLastModified = Long.MAX_VALUE;
// read the dependency cache from the disk
if (cache != null) {
- dependencyMap = readCachedDependencies();
- depCacheFile = new File(cache, CACHE_FILE_NAME);
- depCacheFileExists = depCacheFile.exists();
- depCacheFileLastModified = depCacheFile.lastModified();
+ cacheFile = new File(cache, CACHE_FILE_NAME);
+ cacheFileExists = cacheFile.exists();
+ cacheLastModified = cacheFile.lastModified();
+ if (cacheFileExists) {
+ dependencyMap = readCachedDependencies(cacheFile);
+ }
}
Enumeration classfileEnum = getClassFiles(destPath).elements();
while (classfileEnum.hasMoreElements()) {
@@ -310,8 +320,8 @@
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()) {
+ if (cacheFileExists
+ && cacheLastModified > info.absoluteFile.lastModified())
{
// depFile exists and is newer than the class file
// need to get dependency list from the map.
dependencyList =
(Vector)dependencyMap.get(info.className);
@@ -446,32 +456,57 @@
int count = 0;
Hashtable affectedClasses =
(Hashtable)affectedClassMap.get(className);
- if (affectedClasses != null) {
+ if (affectedClasses == null) {
+ return count;
+ }
for (Enumeration e = affectedClasses.keys();
e.hasMoreElements();) {
- String affectedClassName = (String)e.nextElement();
- ClassFileInfo affectedClassInfo =
(ClassFileInfo)affectedClasses.get(affectedClassName);
- if (affectedClassInfo.absoluteFile.exists()) {
- log("Deleting file " +
affectedClassInfo.absoluteFile.getPath() + " since " +
- className + " out of date", Project.MSG_VERBOSE);
+ String affectedClass = (String)e.nextElement();
+ ClassFileInfo affectedClassInfo
+ = (ClassFileInfo)affectedClasses.get(affectedClass);
+
+ if (!affectedClassInfo.absoluteFile.exists()) {
+ continue;
+ }
+
+ if (affectedClassInfo.sourceFile == null) {
+ if (!affectedClassInfo.isUserWarned) {
+ log("The class " + affectedClass + " in file "
+ + affectedClassInfo.absoluteFile.getPath()
+ + " is out of date due to " + className
+ + " but has not been deleted because its source
file"
+ + " could not be determined", Project.MSG_WARN);
+ affectedClassInfo.isUserWarned = true;
+ }
+ continue;
+ }
+
+ log("Deleting file " + affectedClassInfo.absoluteFile.getPath()
+ + " since " + className + " out of date",
Project.MSG_VERBOSE);
+
affectedClassInfo.absoluteFile.delete();
count++;
if (closure) {
- count += deleteAffectedFiles(affectedClassName);
+ count += deleteAffectedFiles(affectedClass);
} else {
// without closure we may delete an inner class but
not the
// top level class which would not trigger a
recompile.
- if (affectedClassName.indexOf("$") != -1) {
+ if (affectedClass.indexOf("$") == -1) {
+ continue;
+ }
// need to delete the main class
String topLevelClassName
- = affectedClassName.substring(0,
affectedClassName.indexOf("$"));
- log("Top level class = " + topLevelClassName,
Project.MSG_VERBOSE);
+ = affectedClass.substring(0,
affectedClass.indexOf("$"));
+ log("Top level class = " + topLevelClassName,
+ Project.MSG_VERBOSE);
ClassFileInfo topLevelClassInfo
=
(ClassFileInfo)classFileInfoMap.get(topLevelClassName);
if (topLevelClassInfo != null &&
topLevelClassInfo.absoluteFile.exists()) {
- log("Deleting file " +
topLevelClassInfo.absoluteFile.getPath() + " since " +
- "one of its inner classes was removed",
Project.MSG_VERBOSE);
+ log("Deleting file "
+ + topLevelClassInfo.absoluteFile.getPath()
+ + " since one of its inner classes was removed",
+ Project.MSG_VERBOSE);
topLevelClassInfo.absoluteFile.delete();
count++;
if (closure) {
@@ -480,9 +515,6 @@
}
}
}
- }
- }
- }
return count;
}
@@ -528,7 +560,7 @@
}
}
- private void determineOutOfDateClasses(String[] srcPathList) {
+ private void determineOutOfDateClasses() {
outOfDateClasses = new Hashtable();
for (int i = 0; i < srcPathList.length; i++) {
File srcDir = (File)project.resolveFile(srcPathList[i]);
@@ -583,7 +615,7 @@
location);
}
- String[] srcPathList = srcPath.list();
+ srcPathList = srcPath.list();
if (srcPathList.length == 0) {
throw new BuildException("srcdir attribute must be
non-empty",
location);
@@ -603,12 +635,10 @@
}
determineDependencies();
-
if (dump) {
dumpDependencies();
}
-
- determineOutOfDateClasses(srcPathList);
+ determineOutOfDateClasses();
int count = deleteAllAffectedFiles();
long duration = (System.currentTimeMillis() - start) / 1000;
@@ -678,6 +708,28 @@
}
/**
+ * Find the source file for a given class
+ *
+ * @param classname the classname in slash format.
+ */
+ private File findSourceFile(String classname) {
+ String sourceFilename = classname + ".java";
+ int innerIndex = classname.indexOf("$");
+ if (innerIndex != -1) {
+ sourceFilename = classname.substring(0, innerIndex) + ".java";
+ }
+
+ // search the various source path entries
+ for (int i = 0; i < srcPathList.length; ++i) {
+ File sourceFile = new File(srcPathList[i], sourceFilename);
+ if (sourceFile.exists()) {
+ return sourceFile;
+ }
+ }
+ return null;
+ }
+
+ /**
* Add the list of class files from the given directory to the class
* file vector, including any subdirectories.
*
@@ -692,9 +744,12 @@
private void addClassFiles(Vector classFileList, File dir, File root) {
String[] filesInDir = dir.list();
- if (filesInDir != null) {
+ if (filesInDir == null) {
+ return;
+ }
int length = filesInDir.length;
+ int rootLength = root.getPath().length();
for (int i = 0; i < length; ++i) {
File file = new File(dir, filesInDir[i]);
if (file.isDirectory()) {
@@ -702,14 +757,15 @@
} else if (file.getName().endsWith(".class")) {
ClassFileInfo info = new ClassFileInfo();
info.absoluteFile = file;
- info.relativeName =
file.getPath().substring(root.getPath().length() + 1,
+ String relativeName = file.getPath().substring(rootLength +
1,
file.getPath().length() - 6);
- info.className =
ClassFileUtils.convertSlashName(info.relativeName);
+ info.className
+ = ClassFileUtils.convertSlashName(relativeName);
+ info.sourceFile = findSourceFile(relativeName);
classFileList.addElement(info);
}
}
}
- }
/**
@@ -742,7 +798,7 @@
/**
* Set the closure flag. When not set, the depend task will only follow
* direct dependencies between classes. When set, transitive
- * dependenecies are followed until the closure of the dependency set if
+ * dependencies are followed until the closure of the dependency set if
* reached.
*
* @param closure indicate if dependency closure is required.
1.5 +13 -0
jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/optional/depend/DependTest.java
Index: DependTest.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/optional/depend/DependTest.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -w -u -r1.4 -r1.5
--- DependTest.java 9 Apr 2002 03:51:19 -0000 1.4
+++ DependTest.java 9 Apr 2002 13:20:08 -0000 1.5
@@ -187,4 +187,17 @@
executeTarget("testcache");
}
+ /**
+ * Test the detection and warning of non public classes
+ */
+ public void testNonPublic() {
+ executeTarget("testnonpublic");
+ String log = getLog();
+ assertTrue("Expected warning about APrivate",
+ log.indexOf("The class APrivate in file") != -1);
+ assertTrue("but has not been deleted because its source file "
+ + "could not be determined",
+ log.indexOf("The class APrivate in file") != -1);
+ }
+
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>