Browse Source

Zap the depend package as should really be reimplemented using BCEL

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271315 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 24 years ago
parent
commit
919e3c42b4
40 changed files with 0 additions and 5490 deletions
  1. +0
    -118
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFile.java
  2. +0
    -14
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileIterator.java
  3. +0
    -44
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileUtils.java
  4. +0
    -753
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
  5. +0
    -186
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java
  6. +0
    -95
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/JarFileIterator.java
  7. +0
    -89
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ClassCPInfo.java
  8. +0
    -57
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantCPInfo.java
  9. +0
    -374
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPool.java
  10. +0
    -243
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPoolEntry.java
  11. +0
    -50
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/DoubleCPInfo.java
  12. +0
    -111
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FieldRefCPInfo.java
  13. +0
    -54
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FloatCPInfo.java
  14. +0
    -54
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/IntegerCPInfo.java
  15. +0
    -112
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InterfaceMethodRefCPInfo.java
  16. +0
    -54
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/LongCPInfo.java
  17. +0
    -111
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodRefCPInfo.java
  18. +0
    -95
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/NameAndTypeCPInfo.java
  19. +0
    -71
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/StringCPInfo.java
  20. +0
    -60
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/Utf8CPInfo.java
  21. +0
    -118
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/ClassFile.java
  22. +0
    -14
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/ClassFileIterator.java
  23. +0
    -44
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/ClassFileUtils.java
  24. +0
    -753
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
  25. +0
    -186
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java
  26. +0
    -95
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/JarFileIterator.java
  27. +0
    -89
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ClassCPInfo.java
  28. +0
    -57
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantCPInfo.java
  29. +0
    -374
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPool.java
  30. +0
    -243
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPoolEntry.java
  31. +0
    -50
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/DoubleCPInfo.java
  32. +0
    -111
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FieldRefCPInfo.java
  33. +0
    -54
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FloatCPInfo.java
  34. +0
    -54
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/IntegerCPInfo.java
  35. +0
    -112
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InterfaceMethodRefCPInfo.java
  36. +0
    -54
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/LongCPInfo.java
  37. +0
    -111
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodRefCPInfo.java
  38. +0
    -95
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/NameAndTypeCPInfo.java
  39. +0
    -71
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/StringCPInfo.java
  40. +0
    -60
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/Utf8CPInfo.java

+ 0
- 118
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFile.java View File

@@ -1,118 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ClassCPInfo;
import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool;
import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPoolEntry;

/**
* A ClassFile object stores information about a Java class. The class may be
* read from a DataInputStream.and written to a DataOutputStream. These are
* usually streams from a Java class file or a class file component of a Jar
* file.
*
* @author Conor MacNeill
*/
public class ClassFile
{

/**
* The Magic Value that marks the start of a Java class file
*/
private final static int CLASS_MAGIC = 0xCAFEBABE;

/**
* The class name for this class.
*/
private String className;

/**
* This class' constant pool.
*/
private ConstantPool constantPool;

/**
* Get the classes which this class references.
*
* @return The ClassRefs value
*/
public ArrayList getClassRefs()
{

ArrayList classRefs = new ArrayList();

for( int i = 0; i < constantPool.size(); ++i )
{
ConstantPoolEntry entry = constantPool.getEntry( i );

if( entry != null && entry.getTag() == ConstantPoolEntry.CONSTANT_Class )
{
ClassCPInfo classEntry = (ClassCPInfo)entry;

if( !classEntry.getClassName().equals( className ) )
{
classRefs.add( ClassFileUtils.convertSlashName( classEntry.getClassName() ) );
}
}
}

return classRefs;
}

/**
* Get the class' fully qualified name in dot format.
*
* @return the class name in dot format (eg. java.lang.Object)
*/
public String getFullClassName()
{
return ClassFileUtils.convertSlashName( className );
}

/**
* Read the class from a data stream. This method takes an InputStream as
* input and parses the class from the stream. <p>
*
*
*
* @param stream an InputStream from which the class will be read
* @throws IOException if there is a problem reading from the given stream.
* @throws ClassFormatError if the class cannot be parsed correctly
*/
public void read( InputStream stream )
throws IOException, ClassFormatError
{
DataInputStream classStream = new DataInputStream( stream );

if( classStream.readInt() != CLASS_MAGIC )
{
throw new ClassFormatError( "No Magic Code Found - probably not a Java class file." );
}

// right we have a good looking class file.
int minorVersion = classStream.readUnsignedShort();
int majorVersion = classStream.readUnsignedShort();

// read the constant pool in and resolve it
constantPool = new ConstantPool();

constantPool.read( classStream );
constantPool.resolve();

int accessFlags = classStream.readUnsignedShort();
int thisClassIndex = classStream.readUnsignedShort();
int superClassIndex = classStream.readUnsignedShort();
className = ( (ClassCPInfo)constantPool.getEntry( thisClassIndex ) ).getClassName();
}
}


+ 0
- 14
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileIterator.java View File

@@ -1,14 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend;

public interface ClassFileIterator
{

ClassFile getNextClassFile();
}

+ 0
- 44
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileUtils.java View File

@@ -1,44 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend;

/**
* Utility class file routines. This class porovides a number of static utility
* methods to convert between the formats used in the Java class file format and
* those commonly used in Java programming.
*
* @author Conor MacNeill
*/
public class ClassFileUtils
{

/**
* Convert a class name from java source file dot notation to class file
* slash notation..
*
* @param dotName the class name in dot notation (eg. java.lang.Object).
* @return the class name in slash notation (eg. java/lang/Object).
*/
public static String convertDotName( String dotName )
{
return dotName.replace( '.', '/' );
}

/**
* Convert a class name from class file slash notation to java source file
* dot notation.
*
* @param name Description of Parameter
* @return the class name in dot notation (eg. java.lang.Object).
*/
public static String convertSlashName( String name )
{
return name.replace( '\\', '.' ).replace( '/', '.' );
}
}


+ 0
- 753
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java View File

@@ -1,753 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.PathUtil;

/**
* Generate a dependency file for a given set of classes
*
* @author Conor MacNeill
*/
public class Depend extends MatchingTask
{

/**
* constants used with the cache file
*/
private final static String CACHE_FILE_NAME = "dependencies.txt";
private final static String CLASSNAME_PREPEND = "||:";

/**
* indicates that the dependency relationships should be extended beyond
* direct dependencies to include all classes. So if A directly affects B
* abd B directly affects C, then A indirectly affects C.
*/
private boolean closure = false;

/**
* Flag which controls whether the reversed dependencies should be dumped to
* the log
*/
private boolean dump = false;

/**
* A map which gives for every class a list of te class which it affects.
*/
private Hashtable affectedClassMap;

/**
* The directory which contains the dependency cache.
*/
private File cache;

/**
* A map which gives information about a class
*/
private Hashtable classFileInfoMap;

/**
* A map which gives the list of jars and classes from the classpath that a
* class depends upon
*/
private Hashtable classpathDependencies;

/**
* The classpath to look for additional dependencies
*/
private Path dependClasspath;

/**
* The path where compiled class files exist.
*/
private Path destPath;

/**
* The list of classes which are out of date.
*/
private Hashtable outOfDateClasses;

/**
* The path where source files exist
*/
private Path srcPath;

public void setCache( File cache )
{
this.cache = cache;
}

/**
* Set the classpath to be used for this dependency check.
*
* @param classpath The new Classpath value
*/
public void setClasspath( Path classpath )
throws TaskException
{
if( dependClasspath == null )
{
dependClasspath = classpath;
}
else
{
dependClasspath.append( classpath );
}
}

public void setClosure( boolean closure )
{
this.closure = closure;
}

/**
* Set the destination directory where the compiled java files exist.
*
* @param destPath The new DestDir value
*/
public void setDestDir( Path destPath )
{
this.destPath = destPath;
}

/**
* Flag to indicate whether the reverse dependency list should be dumped to
* debug
*
* @param dump The new Dump value
*/
public void setDump( boolean dump )
{
this.dump = dump;
}

/**
* Set the source dirs to find the source Java files.
*
* @param srcPath The new Srcdir value
*/
public void setSrcdir( Path srcPath )
{
this.srcPath = srcPath;
}

/**
* Gets the classpath to be used for this dependency check.
*
* @return The Classpath value
*/
public Path getClasspath()
{
return dependClasspath;
}

/**
* Creates a nested classpath element.
*
* @return Description of the Returned Value
*/
public Path createClasspath()
throws TaskException
{
if( dependClasspath == null )
{
dependClasspath = new Path();
}
Path path1 = dependClasspath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Does the work.
*
* @exception TaskException Thrown in unrecovrable error.
*/
public void execute()
throws TaskException
{
try
{
long start = System.currentTimeMillis();
String[] srcPathList = srcPath.list();
if( srcPathList.length == 0 )
{
throw new TaskException( "srcdir attribute must be set!" );
}

if( destPath == null )
{
destPath = srcPath;
}

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

if( cache != null && !cache.exists() )
{
cache.mkdirs();
}

determineDependencies();

if( dump )
{
getLogger().debug( "Reverse Dependency Dump for " + affectedClassMap.size() + " classes:" );
for( Enumeration e = affectedClassMap.keys(); e.hasMoreElements(); )
{
String className = (String)e.nextElement();
getLogger().debug( " Class " + className + " affects:" );
Hashtable affectedClasses = (Hashtable)affectedClassMap.get( className );
for( Enumeration e2 = affectedClasses.keys(); e2.hasMoreElements(); )
{
String affectedClass = (String)e2.nextElement();
ClassFileInfo info = (ClassFileInfo)affectedClasses.get( affectedClass );
getLogger().debug( " " + affectedClass + " in " + info.absoluteFile.getPath() );
}
}

if( classpathDependencies != null )
{
getLogger().debug( "Classpath file dependencies (Forward):" );
for( Enumeration e = classpathDependencies.keys(); e.hasMoreElements(); )
{
String className = (String)e.nextElement();
getLogger().debug( " Class " + className + " depends on:" );
Hashtable dependencies = (Hashtable)classpathDependencies.get( className );
for( Enumeration e2 = dependencies.elements(); e2.hasMoreElements(); )
{
File classpathFile = (File)e2.nextElement();
getLogger().debug( " " + classpathFile.getPath() );
}
}
}

}

// 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.
outOfDateClasses = new Hashtable();
for( int i = 0; i < srcPathList.length; i++ )
{
File srcDir = (File)resolveFile( srcPathList[ i ] );
if( srcDir.exists() )
{
DirectoryScanner ds = this.getDirectoryScanner( srcDir );
String[] files = ds.getIncludedFiles();
scanDir( srcDir, files );
}
}

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

// if we have no info about the class - it may have been deleted already and we
// are using cached info.
if( info != null )
{
Hashtable dependencies = (Hashtable)classpathDependencies.get( className );
for( Enumeration e2 = dependencies.elements(); e2.hasMoreElements(); )
{
File classpathFile = (File)e2.nextElement();
if( classpathFile.lastModified() > info.absoluteFile.lastModified() )
{
getLogger().debug( "Class " + className + " is out of date with respect to " + classpathFile );
outOfDateClasses.put( className, className );
break;
}
}
}
}
}
}

// we now have a complete list of classes which are out of date
// We scan through the affected classes, deleting any affected classes.
int count = deleteAllAffectedFiles();

long duration = ( System.currentTimeMillis() - start ) / 1000;
getLogger().info( "Deleted " + count + " out of date files in " + duration + " seconds" );
}
catch( Exception e )
{
throw new TaskException( "Error", e );
}
}

/**
* Scans the directory looking for source files that are newer than their
* class files. The results are returned in the class variable compileList
*
* @param srcDir Description of Parameter
* @param files Description of Parameter
*/
protected void scanDir( File srcDir, String files[] )
{

long now = System.currentTimeMillis();

for( int i = 0; i < files.length; i++ )
{
File srcFile = new File( srcDir, files[ i ] );
if( files[ i ].endsWith( ".java" ) )
{
String filePath = srcFile.getPath();
String className = filePath.substring( srcDir.getPath().length() + 1,
filePath.length() - ".java".length() );
className = ClassFileUtils.convertSlashName( className );
ClassFileInfo info = (ClassFileInfo)classFileInfoMap.get( className );
if( info == null )
{
// there was no class file. add this class to the list
outOfDateClasses.put( className, className );
}
else
{
if( srcFile.lastModified() > info.absoluteFile.lastModified() )
{
outOfDateClasses.put( className, className );
}
}
}
}
}

/**
* Get the list of class files we are going to analyse.
*
* @param classLocations a path structure containing all the directories
* where classes can be found.
* @return a vector containing the classes to analyse.
*/
private ArrayList getClassFiles( Path classLocations )
throws TaskException
{
// break the classLocations into its components.
String[] classLocationsList = classLocations.list();

ArrayList classFileList = new ArrayList();

for( int i = 0; i < classLocationsList.length; ++i )
{
File dir = new File( classLocationsList[ i ] );
if( dir.isDirectory() )
{
addClassFiles( classFileList, dir, dir );
}
}

return classFileList;
}

/**
* Add the list of class files from the given directory to the class file
* vector, including any subdirectories.
*
* @param classFileList The feature to be added to the ClassFiles attribute
* @param dir The feature to be added to the ClassFiles attribute
* @param root The feature to be added to the ClassFiles attribute
*/
private void addClassFiles( ArrayList classFileList, File dir, File root )
{
String[] filesInDir = dir.list();

if( filesInDir != null )
{
int length = filesInDir.length;

for( int i = 0; i < length; ++i )
{
File file = new File( dir, filesInDir[ i ] );
if( file.isDirectory() )
{
addClassFiles( classFileList, file, root );
}
else if( file.getName().endsWith( ".class" ) )
{
ClassFileInfo info = new ClassFileInfo();
info.absoluteFile = file;
info.relativeName = file.getPath().substring( root.getPath().length() + 1,
file.getPath().length() - 6 );
info.className = ClassFileUtils.convertSlashName( info.relativeName );
classFileList.add( info );
}
}
}
}

private int deleteAffectedFiles( String className )
{
int count = 0;

Hashtable affectedClasses = (Hashtable)affectedClassMap.get( className );
if( affectedClasses != null )
{
for( Enumeration e = affectedClasses.keys(); e.hasMoreElements(); )
{
String affectedClassName = (String)e.nextElement();
ClassFileInfo affectedClassInfo = (ClassFileInfo)affectedClasses.get( affectedClassName );
if( affectedClassInfo.absoluteFile.exists() )
{
getLogger().debug( "Deleting file " + affectedClassInfo.absoluteFile.getPath() + " since " + className + " out of date" );
affectedClassInfo.absoluteFile.delete();
count++;
if( closure )
{
count += deleteAffectedFiles( affectedClassName );
}
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 )
{
// need to delete the main class
String topLevelClassName
= affectedClassName.substring( 0, affectedClassName.indexOf( "$" ) );
getLogger().debug( "Top level class = " + topLevelClassName );
ClassFileInfo topLevelClassInfo
= (ClassFileInfo)classFileInfoMap.get( topLevelClassName );
if( topLevelClassInfo != null &&
topLevelClassInfo.absoluteFile.exists() )
{
getLogger().debug( "Deleting file " + topLevelClassInfo.absoluteFile.getPath() + " since " + "one of its inner classes was removed" );
topLevelClassInfo.absoluteFile.delete();
count++;
if( closure )
{
count += deleteAffectedFiles( topLevelClassName );
}
}
}
}
}
}
}
return count;
}

private int deleteAllAffectedFiles()
{
int count = 0;
for( Enumeration e = outOfDateClasses.elements(); e.hasMoreElements(); )
{
String className = (String)e.nextElement();
count += deleteAffectedFiles( className );
ClassFileInfo classInfo = (ClassFileInfo)classFileInfoMap.get( className );
if( classInfo != null && classInfo.absoluteFile.exists() )
{
classInfo.absoluteFile.delete();
count++;
}
}
return count;
}

/**
* Determine the dependencies between classes. Class dependencies are
* determined by examining the class references in a class file to other
* classes
*
* @exception IOException Description of Exception
*/
private void determineDependencies()
throws IOException, TaskException
{
affectedClassMap = new Hashtable();
classFileInfoMap = new Hashtable();
boolean cacheDirty = false;

Hashtable dependencyMap = new Hashtable();
File depCacheFile = null;
boolean depCacheFileExists = true;
long depCacheFileLastModified = 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();
}
for( Iterator e = getClassFiles( destPath ).iterator(); e.hasNext(); )
{
ClassFileInfo info = (ClassFileInfo)e.next();
getLogger().debug( "Adding class info for " + info.className );
classFileInfoMap.put( info.className, info );

ArrayList dependencyList = 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() )
{
// depFile exists and is newer than the class file
// need to get dependency list from the map.
dependencyList = (ArrayList)dependencyMap.get( info.className );
}
}

if( dependencyList == null )
{
// not cached - so need to read directly from the class file
FileInputStream inFileStream = null;
try
{
inFileStream = new FileInputStream( info.absoluteFile );
ClassFile classFile = new ClassFile();
classFile.read( inFileStream );

dependencyList = classFile.getClassRefs();
if( dependencyList != null )
{
cacheDirty = true;
dependencyMap.put( info.className, dependencyList );
}

}
finally
{
if( inFileStream != null )
{
inFileStream.close();
}
}
}

// This class depends on each class in the dependency list. For each
// one of those, add this class into their affected classes list
for( Iterator depEnum = dependencyList.iterator(); depEnum.hasNext(); )
{
String dependentClass = (String)depEnum.next();

Hashtable affectedClasses = (Hashtable)affectedClassMap.get( dependentClass );
if( affectedClasses == null )
{
affectedClasses = new Hashtable();
affectedClassMap.put( dependentClass, affectedClasses );
}

affectedClasses.put( info.className, info );
}
}

classpathDependencies = null;
if( dependClasspath != null )
{
// now determine which jars each class depends upon
classpathDependencies = new Hashtable();
final URL[] urls = PathUtil.toURLs( dependClasspath );
final ClassLoader classLoader = new URLClassLoader( urls );

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

if( !dependency.startsWith( "java." ) && !dependency.startsWith( "javax." ) )
{
final String name = dependency.replace( '.', '/' ) + ".class";
URL classURL = classLoader.getResource( name );
if( classURL != null )
{
if( classURL.getProtocol().equals( "jar" ) )
{
String jarFilePath = classURL.getFile();
if( jarFilePath.startsWith( "file:" ) )
{
int classMarker = jarFilePath.indexOf( '!' );
jarFilePath = jarFilePath.substring( 5, classMarker );
}
classpathFileObject = new File( jarFilePath );
}
else if( classURL.getProtocol().equals( "file" ) )
{
String classFilePath = classURL.getFile();
classpathFileObject = new File( classFilePath );
}
getLogger().debug( "Class " + className + " depends on " + classpathFileObject + " due to " + dependency );
}
}
classpathFileCache.put( dependency, classpathFileObject );
}
if( classpathFileObject != null && classpathFileObject != nullFileMarker )
{
// we need to add this jar to the list for this class.
File jarFile = (File)classpathFileObject;
dependencies.put( jarFile, jarFile );
}
}
}
}

// write the dependency cache to the disk
if( cache != null && cacheDirty )
{
writeCachedDependencies( dependencyMap );
}
}

/**
* Read the dependencies from cache file
*
* @return Description of the Returned Value
* @exception IOException Description of Exception
*/
private Hashtable readCachedDependencies()
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;
ArrayList dependencyList = null;
String className = null;
int prependLength = CLASSNAME_PREPEND.length();
while( ( line = in.readLine() ) != null )
{
if( line.startsWith( CLASSNAME_PREPEND ) )
{
dependencyList = new ArrayList();
className = line.substring( prependLength );
dependencyMap.put( className, dependencyList );
}
else
{
dependencyList.add( line );
}
}
}
finally
{
if( in != null )
{
in.close();
}
}
}
}

return dependencyMap;
}

/**
* Write the dependencies to cache file
*
* @param dependencyMap Description of Parameter
* @exception IOException Description of Exception
*/
private void writeCachedDependencies( Hashtable dependencyMap )
throws IOException
{
if( cache != null )
{
PrintWriter pw = null;
try
{
cache.mkdirs();
File depFile = new File( cache, CACHE_FILE_NAME );

pw = new PrintWriter( new FileWriter( depFile ) );
for( Enumeration deps = dependencyMap.keys(); deps.hasMoreElements(); )
{
String className = (String)deps.nextElement();

pw.println( CLASSNAME_PREPEND + className );

ArrayList dependencyList = (ArrayList)dependencyMap.get( className );
int size = dependencyList.size();
for( int x = 0; x < size; x++ )
{
pw.println( dependencyList.get( x ) );
}
}
}
finally
{
if( pw != null )
{
pw.close();
}
}
}
}

/**
* A class (struct) user to manage information about a class
*
* @author RT
*/
private static class ClassFileInfo
{
/**
* The file where the class file is stored in the file system
*/
public File absoluteFile;

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

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


+ 0
- 186
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java View File

@@ -1,186 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Stack;

/**
* An iterator which iterates through the contents of a java directory. The
* iterator should be created with the directory at the root of the Java
* namespace.
*
* @author Conor MacNeill
*/
public class DirectoryIterator implements ClassFileIterator
{

/**
* The length of the root directory. This is used to remove the root
* directory from full paths.
*/
int rootLength;

/**
* The current directory iterator. As directories encounter lower level
* directories, the current iterator is pushed onto the iterator stack and a
* new iterator over the sub directory becomes the current directory. This
* implements a depth first traversal of the directory namespace.
*/
private Iterator currentEnum;

/**
* This is a stack of current iterators supporting the depth first traversal
* of the directory tree.
*/
private Stack enumStack;

/**
* Creates a directory iterator. The directory iterator is created to scan
* the root directory. If the changeInto flag is given, then the entries
* returned will be relative to this directory and not the current
* directory.
*
* @param rootDirectory the root if the directory namespace which is to be
* iterated over
* @param changeInto if true then the returned entries will be relative to
* the rootDirectory and not the current directory.
* @exception IOException Description of Exception
* @throws IOException if there is a problem reading the directory
* information.
*/
public DirectoryIterator( File rootDirectory, boolean changeInto )
throws IOException
{
super();

enumStack = new Stack();

if( rootDirectory.isAbsolute() || changeInto )
{
rootLength = rootDirectory.getPath().length() + 1;
}
else
{
rootLength = 0;
}

ArrayList filesInRoot = getDirectoryEntries( rootDirectory );

currentEnum = filesInRoot.iterator();
}

/**
* Template method to allow subclasses to supply elements for the iteration.
* The directory iterator maintains a stack of iterators covering each level
* in the directory hierarchy. The current iterator covers the current
* directory being scanned. If the next entry in that directory is a
* subdirectory, the current iterator is pushed onto the stack and a new
* iterator is created for the subdirectory. If the entry is a file, it is
* returned as the next element and the iterator remains valid. If there are
* no more entries in the current directory, the topmost iterator on the
* statck is popped off to become the current iterator.
*
* @return the next ClassFile in the iteration.
*/
public ClassFile getNextClassFile()
{
ClassFile next = null;

try
{
while( next == null )
{
if( currentEnum.hasNext() )
{
File element = (File)currentEnum.next();

if( element.isDirectory() )
{

// push the current iterator onto the stack and then
// iterate through this directory.
enumStack.push( currentEnum );

ArrayList files = getDirectoryEntries( element );

currentEnum = files.iterator();
}
else
{

// we have a file. create a stream for it
FileInputStream inFileStream = new FileInputStream( element );

if( element.getName().endsWith( ".class" ) )
{

// create a data input stream from the jar input stream
ClassFile javaClass = new ClassFile();

javaClass.read( inFileStream );

next = javaClass;
}
}
}
else
{
// this iterator is exhausted. Can we pop one off the stack
if( enumStack.empty() )
{
break;
}
else
{
currentEnum = (Iterator)enumStack.pop();
}
}
}
}
catch( IOException e )
{
next = null;
}

return next;
}

/**
* Get a vector covering all the entries (files and subdirectories in a
* directory).
*
* @param directory the directory to be scanned.
* @return a vector containing File objects for each entry in the directory.
*/
private ArrayList getDirectoryEntries( File directory )
{
ArrayList files = new ArrayList();

// File[] filesInDir = directory.listFiles();
String[] filesInDir = directory.list();

if( filesInDir != null )
{
int length = filesInDir.length;

for( int i = 0; i < length; ++i )
{
files.add( new File( directory, filesInDir[ i ] ) );
}
}

return files;
}

}


+ 0
- 95
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/JarFileIterator.java View File

@@ -1,95 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
* A class file iterator which iterates through the contents of a Java jar file.
*
* @author Conor MacNeill
*/
public class JarFileIterator implements ClassFileIterator
{
private ZipInputStream jarStream;

public JarFileIterator( InputStream stream )
throws IOException
{
super();

jarStream = new ZipInputStream( stream );
}

public ClassFile getNextClassFile()
{
ZipEntry jarEntry;
ClassFile next = null;

try
{
jarEntry = jarStream.getNextEntry();

while( next == null && jarEntry != null )
{
String entryName = jarEntry.getName();

if( !jarEntry.isDirectory() && entryName.endsWith( ".class" ) )
{

// create a data input stream from the jar input stream
ClassFile javaClass = new ClassFile();

javaClass.read( jarStream );

next = javaClass;
}
else
{

jarEntry = jarStream.getNextEntry();
}
}
}
catch( IOException e )
{
String message = e.getMessage();
String text = e.getClass().getName();

if( message != null )
{
text += ": " + message;
}

throw new RuntimeException( "Problem reading JAR file: " + text );
}

return next;
}

private byte[] getEntryBytes( InputStream stream )
throws IOException
{
byte[] buffer = new byte[ 8192 ];
ByteArrayOutputStream baos = new ByteArrayOutputStream( 2048 );
int n;

while( ( n = stream.read( buffer, 0, buffer.length ) ) != -1 )
{
baos.write( buffer, 0, n );
}

return baos.toByteArray();
}

}


+ 0
- 89
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ClassCPInfo.java View File

@@ -1,89 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* The constant pool entry which stores class information.
*
* @author Conor MacNeill
*/
public class ClassCPInfo extends ConstantPoolEntry
{

/**
* The class' name. This will be only valid if the entry has been resolved
* against the constant pool.
*/
private String className;

/**
* The index into the constant pool where this class' name is stored. If the
* class name is changed, this entry is invalid until this entry is
* connected to a constant pool.
*/
private int index;

/**
* Constructor. Sets the tag value for this entry to type Class
*/
public ClassCPInfo()
{
super( CONSTANT_Class, 1 );
}

/**
* Get the class name of this entry.
*
* @return the class' name.
*/
public String getClassName()
{
return className;
}

/**
* Read the entry from a stream.
*
* @param cpStream the stream containing the constant pool entry to be read.
* @exception IOException thrown if there is a problem reading the entry
* from the stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
index = cpStream.readUnsignedShort();
className = "unresolved";
}

/**
* Resolve this class info against the given constant pool.
*
* @param constantPool the constant pool with which to resolve the class.
*/
public void resolve( ConstantPool constantPool )
{
className = ( (Utf8CPInfo)constantPool.getEntry( index ) ).getValue();

super.resolve( constantPool );
}

/**
* Generate a string readable version of this entry
*
* @return Description of the Returned Value
*/
public String toString()
{
return "Class Constant Pool Entry for " + className + "[" + index + "]";
}

}


+ 0
- 57
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantCPInfo.java View File

@@ -1,57 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

/**
* A Constant Pool entry which represents a constant value.
*
* @author Conor MacNeill
*/
public abstract class ConstantCPInfo extends ConstantPoolEntry
{

/**
* The entry's untyped value. Each subclass interprets the constant value
* based on the subclass's type. The value here must be compatible.
*/
private Object value;

/**
* Initialise the constant entry.
*
* @param tagValue the constant pool entry type to be used.
* @param entries the number of constant pool entry slots occupied by this
* entry.
*/
protected ConstantCPInfo( int tagValue, int entries )
{
super( tagValue, entries );
}

/**
* Set the constant value.
*
* @param newValue the new untyped value of this constant.
*/
public void setValue( Object newValue )
{
value = newValue;
}

/**
* Get the value of the constant.
*
* @return the value of the constant (untyped).
*/
public Object getValue()
{
return value;
}

}


+ 0
- 374
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPool.java View File

@@ -1,374 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;

/**
* The constant pool of a Java class. The constant pool is a collection of
* constants used in a Java class file. It stores strings, constant values,
* class names, method names, field names etc.
*
* @author Conor MacNeill
* @see <a href="http://java.sun.com/docs/books/vmspec/">The Java Virtual
* Machine Specification</a>
*/
public class ConstantPool
{

/**
* The entries in the constant pool.
*/
private ArrayList entries;

/**
* A Hashtable of UTF8 entries - used to get constant pool indexes of the
* UTF8 values quickly
*/
private Hashtable utf8Indexes;

/**
* Initialise the constant pool.
*/
public ConstantPool()
{
entries = new ArrayList();

// The zero index is never present in the constant pool itself so
// we add a null entry for it
entries.add( null );

utf8Indexes = new Hashtable();
}

/**
* Get the index of a given CONSTANT_Class entry in the constant pool.
*
* @param className the name of the class for which the class entry index is
* required.
* @return the index at which the given class entry occurs in the constant
* pool or -1 if the value does not occur.
*/
public int getClassEntry( String className )
{
int index = -1;

for( int i = 0; i < entries.size() && index == -1; ++i )
{
Object element = entries.get( i );

if( element instanceof ClassCPInfo )
{
ClassCPInfo classinfo = (ClassCPInfo)element;

if( classinfo.getClassName().equals( className ) )
{
index = i;
}
}
}

return index;
}

/**
* Get the index of a given constant value entry in the constant pool.
*
* @param constantValue the constant value for which the index is required.
* @return the index at which the given value entry occurs in the constant
* pool or -1 if the value does not occur.
*/
public int getConstantEntry( Object constantValue )
{
int index = -1;

for( int i = 0; i < entries.size() && index == -1; ++i )
{
Object element = entries.get( i );

if( element instanceof ConstantCPInfo )
{
ConstantCPInfo constantEntry = (ConstantCPInfo)element;

if( constantEntry.getValue().equals( constantValue ) )
{
index = i;
}
}
}

return index;
}

/**
* Get an constant pool entry at a particular index.
*
* @param index the index into the constant pool.
* @return the constant pool entry at that index.
*/
public ConstantPoolEntry getEntry( int index )
{
return (ConstantPoolEntry)entries.get( index );
}

/**
* Get the index of a given CONSTANT_FieldRef entry in the constant pool.
*
* @param fieldClassName the name of the class which contains the field
* being referenced.
* @param fieldName the name of the field being referenced.
* @param fieldType the type descriptor of the field being referenced.
* @return the index at which the given field ref entry occurs in the
* constant pool or -1 if the value does not occur.
*/
public int getFieldRefEntry( String fieldClassName, String fieldName, String fieldType )
{
int index = -1;

for( int i = 0; i < entries.size() && index == -1; ++i )
{
Object element = entries.get( i );

if( element instanceof FieldRefCPInfo )
{
FieldRefCPInfo fieldRefEntry = (FieldRefCPInfo)element;

if( fieldRefEntry.getFieldClassName().equals( fieldClassName ) && fieldRefEntry.getFieldName().equals( fieldName )
&& fieldRefEntry.getFieldType().equals( fieldType ) )
{
index = i;
}
}
}

return index;
}

/**
* Get the index of a given CONSTANT_InterfaceMethodRef entry in the
* constant pool.
*
* @param interfaceMethodClassName the name of the interface which contains
* the method being referenced.
* @param interfaceMethodName the name of the method being referenced.
* @param interfaceMethodType the type descriptor of the metho dbeing
* referenced.
* @return the index at which the given method ref entry occurs in the
* constant pool or -1 if the value does not occur.
*/
public int getInterfaceMethodRefEntry( String interfaceMethodClassName, String interfaceMethodName, String interfaceMethodType )
{
int index = -1;

for( int i = 0; i < entries.size() && index == -1; ++i )
{
Object element = entries.get( i );

if( element instanceof InterfaceMethodRefCPInfo )
{
InterfaceMethodRefCPInfo interfaceMethodRefEntry = (InterfaceMethodRefCPInfo)element;

if( interfaceMethodRefEntry.getInterfaceMethodClassName().equals( interfaceMethodClassName )
&& interfaceMethodRefEntry.getInterfaceMethodName().equals( interfaceMethodName )
&& interfaceMethodRefEntry.getInterfaceMethodType().equals( interfaceMethodType ) )
{
index = i;
}
}
}

return index;
}

/**
* Get the index of a given CONSTANT_MethodRef entry in the constant pool.
*
* @param methodClassName the name of the class which contains the method
* being referenced.
* @param methodName the name of the method being referenced.
* @param methodType the type descriptor of the metho dbeing referenced.
* @return the index at which the given method ref entry occurs in the
* constant pool or -1 if the value does not occur.
*/
public int getMethodRefEntry( String methodClassName, String methodName, String methodType )
{
int index = -1;

for( int i = 0; i < entries.size() && index == -1; ++i )
{
Object element = entries.get( i );

if( element instanceof MethodRefCPInfo )
{
MethodRefCPInfo methodRefEntry = (MethodRefCPInfo)element;

if( methodRefEntry.getMethodClassName().equals( methodClassName )
&& methodRefEntry.getMethodName().equals( methodName ) && methodRefEntry.getMethodType().equals( methodType ) )
{
index = i;
}
}
}

return index;
}

/**
* Get the index of a given CONSTANT_NameAndType entry in the constant pool.
*
* @param name the name
* @param type the type
* @return the index at which the given NameAndType entry occurs in the
* constant pool or -1 if the value does not occur.
*/
public int getNameAndTypeEntry( String name, String type )
{
int index = -1;

for( int i = 0; i < entries.size() && index == -1; ++i )
{
Object element = entries.get( i );

if( element instanceof NameAndTypeCPInfo )
{
NameAndTypeCPInfo nameAndTypeEntry = (NameAndTypeCPInfo)element;

if( nameAndTypeEntry.getName().equals( name ) && nameAndTypeEntry.getType().equals( type ) )
{
index = i;
}
}
}

return index;
}

/**
* Get the index of a given UTF8 constant pool entry.
*
* @param value the string value of the UTF8 entry.
* @return the index at which the given string occurs in the constant pool
* or -1 if the value does not occur.
*/
public int getUTF8Entry( String value )
{
int index = -1;
Integer indexInteger = (Integer)utf8Indexes.get( value );

if( indexInteger != null )
{
index = indexInteger.intValue();
}

return index;
}

/**
* Add an entry to the constant pool.
*
* @param entry the new entry to be added to the constant pool.
* @return the index into the constant pool at which the entry is stored.
*/
public int addEntry( ConstantPoolEntry entry )
{
int index = entries.size();

entries.add( entry );

int numSlots = entry.getNumEntries();

// add null entries for any additional slots required.
for( int j = 0; j < numSlots - 1; ++j )
{
entries.add( null );
}

if( entry instanceof Utf8CPInfo )
{
Utf8CPInfo utf8Info = (Utf8CPInfo)entry;

utf8Indexes.put( utf8Info.getValue(), new Integer( index ) );
}

return index;
}

/**
* Read the constant pool from a class input stream.
*
* @param classStream the DataInputStream of a class file.
* @throws IOException if there is a problem reading the constant pool from
* the stream
*/
public void read( DataInputStream classStream )
throws IOException
{
int numEntries = classStream.readUnsignedShort();

for( int i = 1; i < numEntries; )
{
ConstantPoolEntry nextEntry = ConstantPoolEntry.readEntry( classStream );

i += nextEntry.getNumEntries();

addEntry( nextEntry );
}
}

/**
* Resolve the entries in the constant pool. Resolution of the constant pool
* involves transforming indexes to other constant pool entries into the
* actual data for that entry.
*/
public void resolve()
{
for( Iterator i = entries.iterator(); i.hasNext(); )
{
ConstantPoolEntry poolInfo = (ConstantPoolEntry)i.next();

if( poolInfo != null && !poolInfo.isResolved() )
{
poolInfo.resolve( this );
}
}
}

/**
* Get the size of the constant pool.
*
* @return Description of the Returned Value
*/
public int size()
{
return entries.size();
}

/**
* Dump the constant pool to a string.
*
* @return the constant pool entries as strings
*/
public String toString()
{
StringBuffer sb = new StringBuffer( "\n" );
int size = entries.size();

for( int i = 0; i < size; ++i )
{
sb.append( "[" + i + "] = " + getEntry( i ) + "\n" );
}

return sb.toString();
}

}


+ 0
- 243
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPoolEntry.java View File

@@ -1,243 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* An entry in the constant pool. This class contains a represenation of the
* constant pool entries. It is an abstract base class for all the different
* forms of constant pool entry.
*
* @author Conor MacNeill
* @see ConstantPool
*/
public abstract class ConstantPoolEntry
{

/**
* Tag value for UTF8 entries.
*/
public final static int CONSTANT_Utf8 = 1;

/**
* Tag value for Integer entries.
*/
public final static int CONSTANT_Integer = 3;

/**
* Tag value for Float entries.
*/
public final static int CONSTANT_Float = 4;

/**
* Tag value for Long entries.
*/
public final static int CONSTANT_Long = 5;

/**
* Tag value for Double entries.
*/
public final static int CONSTANT_Double = 6;

/**
* Tag value for Class entries.
*/
public final static int CONSTANT_Class = 7;

/**
* Tag value for String entries.
*/
public final static int CONSTANT_String = 8;

/**
* Tag value for Field Reference entries.
*/
public final static int CONSTANT_FieldRef = 9;

/**
* Tag value for Method Reference entries.
*/
public final static int CONSTANT_MethodRef = 10;

/**
* Tag value for Interface Method Reference entries.
*/
public final static int CONSTANT_InterfaceMethodRef = 11;

/**
* Tag value for Name and Type entries.
*/
public final static int CONSTANT_NameAndType = 12;

/**
* The number of slots in the constant pool, occupied by this entry.
*/
private int numEntries;

/**
* A flag which indiciates if this entry has been resolved or not.
*/
private boolean resolved;

/**
* This entry's tag which identifies the type of this constant pool entry.
*/
private int tag;

/**
* Initialse the constant pool entry.
*
* @param tagValue the tag value which identifies which type of constant
* pool entry this is.
* @param entries the number of constant pool entry slots this entry
* occupies.
*/
public ConstantPoolEntry( int tagValue, int entries )
{
tag = tagValue;
numEntries = entries;
resolved = false;
}

/**
* Read a constant pool entry from a stream. This is a factory method which
* reads a constant pool entry form a stream and returns the appropriate
* subclass for the entry.
*
* @param cpStream the stream from which the constant pool entry is to be
* read.
* @return Description of the Returned Value
* @exception IOException Description of Exception
* @returns the appropriate ConstantPoolEntry subclass representing the
* constant pool entry from the stream.
* @throws IOExcception if there is a problem reading the entry from the
* stream.
*/
public static ConstantPoolEntry readEntry( DataInputStream cpStream )
throws IOException
{
ConstantPoolEntry cpInfo = null;
int cpTag = cpStream.readUnsignedByte();

switch( cpTag )
{

case CONSTANT_Utf8:
cpInfo = new Utf8CPInfo();

break;
case CONSTANT_Integer:
cpInfo = new IntegerCPInfo();

break;
case CONSTANT_Float:
cpInfo = new FloatCPInfo();

break;
case CONSTANT_Long:
cpInfo = new LongCPInfo();

break;
case CONSTANT_Double:
cpInfo = new DoubleCPInfo();

break;
case CONSTANT_Class:
cpInfo = new ClassCPInfo();

break;
case CONSTANT_String:
cpInfo = new StringCPInfo();

break;
case CONSTANT_FieldRef:
cpInfo = new FieldRefCPInfo();

break;
case CONSTANT_MethodRef:
cpInfo = new MethodRefCPInfo();

break;
case CONSTANT_InterfaceMethodRef:
cpInfo = new InterfaceMethodRefCPInfo();

break;
case CONSTANT_NameAndType:
cpInfo = new NameAndTypeCPInfo();

break;
default:
throw new ClassFormatError( "Invalid Constant Pool entry Type " + cpTag );
}

cpInfo.read( cpStream );

return cpInfo;
}

/**
* Get the number of Constant Pool Entry slots within the constant pool
* occupied by this entry.
*
* @return the number of slots used.
*/
public final int getNumEntries()
{
return numEntries;
}

/**
* Get the Entry's type tag.
*
* @return The Tag value of this entry
*/
public int getTag()
{
return tag;
}

/**
* Indicates whether this entry has been resolved. In general a constant
* pool entry can reference another constant pool entry by its index value.
* Resolution involves replacing this index value with the constant pool
* entry at that index.
*
* @return true if this entry has been resolved.
*/
public boolean isResolved()
{
return resolved;
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public abstract void read( DataInputStream cpStream )
throws IOException;

/**
* Resolve this constant pool entry with respect to its dependents in the
* constant pool.
*
* @param constantPool the constant pool of which this entry is a member and
* against which this entry is to be resolved.
*/
public void resolve( ConstantPool constantPool )
{
resolved = true;
}

}


+ 0
- 50
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/DoubleCPInfo.java View File

@@ -1,50 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* The constant pool entry subclass used to represent double constant values.
*
* @author Conor MacNeill
*/
public class DoubleCPInfo extends ConstantCPInfo
{
public DoubleCPInfo()
{
super( CONSTANT_Double, 2 );
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
setValue( new Double( cpStream.readDouble() ) );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
return "Double Constant Pool Entry: " + getValue();
}

}


+ 0
- 111
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FieldRefCPInfo.java View File

@@ -1,111 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A FieldRef CP Info
*
* @author Conor MacNeill
*/
public class FieldRefCPInfo extends ConstantPoolEntry
{
private int classIndex;
private String fieldClassName;
private String fieldName;
private String fieldType;
private int nameAndTypeIndex;

/**
* Constructor.
*/
public FieldRefCPInfo()
{
super( CONSTANT_FieldRef, 1 );
}

public String getFieldClassName()
{
return fieldClassName;
}

public String getFieldName()
{
return fieldName;
}

public String getFieldType()
{
return fieldType;
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
classIndex = cpStream.readUnsignedShort();
nameAndTypeIndex = cpStream.readUnsignedShort();
}

/**
* Resolve this constant pool entry with respect to its dependents in the
* constant pool.
*
* @param constantPool the constant pool of which this entry is a member and
* against which this entry is to be resolved.
*/
public void resolve( ConstantPool constantPool )
{
ClassCPInfo fieldClass = (ClassCPInfo)constantPool.getEntry( classIndex );

fieldClass.resolve( constantPool );

fieldClassName = fieldClass.getClassName();

NameAndTypeCPInfo nt = (NameAndTypeCPInfo)constantPool.getEntry( nameAndTypeIndex );

nt.resolve( constantPool );

fieldName = nt.getName();
fieldType = nt.getType();

super.resolve( constantPool );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
String value;

if( isResolved() )
{
value = "Field : Class = " + fieldClassName + ", name = " + fieldName + ", type = " + fieldType;
}
else
{
value = "Field : Class index = " + classIndex + ", name and type index = " + nameAndTypeIndex;
}

return value;
}

}


+ 0
- 54
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FloatCPInfo.java View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A Float CP Info
*
* @author Conor MacNeill
*/
public class FloatCPInfo extends ConstantCPInfo
{

/**
* Constructor.
*/
public FloatCPInfo()
{
super( CONSTANT_Float, 1 );
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
setValue( new Float( cpStream.readFloat() ) );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
return "Float Constant Pool Entry: " + getValue();
}

}


+ 0
- 54
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/IntegerCPInfo.java View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* An Integer CP Info
*
* @author Conor MacNeill
*/
public class IntegerCPInfo extends ConstantCPInfo
{

/**
* Constructor.
*/
public IntegerCPInfo()
{
super( CONSTANT_Integer, 1 );
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
setValue( new Integer( cpStream.readInt() ) );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
return "Integer Constant Pool Entry: " + getValue();
}

}


+ 0
- 112
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InterfaceMethodRefCPInfo.java View File

@@ -1,112 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A InterfaceMethodRef CP Info
*
* @author Conor MacNeill
*/
public class InterfaceMethodRefCPInfo extends ConstantPoolEntry
{
private int classIndex;
private String interfaceMethodClassName;
private String interfaceMethodName;
private String interfaceMethodType;
private int nameAndTypeIndex;

/**
* Constructor.
*/
public InterfaceMethodRefCPInfo()
{
super( CONSTANT_InterfaceMethodRef, 1 );
}

public String getInterfaceMethodClassName()
{
return interfaceMethodClassName;
}

public String getInterfaceMethodName()
{
return interfaceMethodName;
}

public String getInterfaceMethodType()
{
return interfaceMethodType;
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
classIndex = cpStream.readUnsignedShort();
nameAndTypeIndex = cpStream.readUnsignedShort();
}

/**
* Resolve this constant pool entry with respect to its dependents in the
* constant pool.
*
* @param constantPool the constant pool of which this entry is a member and
* against which this entry is to be resolved.
*/
public void resolve( ConstantPool constantPool )
{
ClassCPInfo interfaceMethodClass = (ClassCPInfo)constantPool.getEntry( classIndex );

interfaceMethodClass.resolve( constantPool );

interfaceMethodClassName = interfaceMethodClass.getClassName();

NameAndTypeCPInfo nt = (NameAndTypeCPInfo)constantPool.getEntry( nameAndTypeIndex );

nt.resolve( constantPool );

interfaceMethodName = nt.getName();
interfaceMethodType = nt.getType();

super.resolve( constantPool );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
String value;

if( isResolved() )
{
value = "InterfaceMethod : Class = " + interfaceMethodClassName + ", name = " + interfaceMethodName + ", type = "
+ interfaceMethodType;
}
else
{
value = "InterfaceMethod : Class index = " + classIndex + ", name and type index = " + nameAndTypeIndex;
}

return value;
}

}


+ 0
- 54
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/LongCPInfo.java View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A Long CP Info
*
* @author Conor MacNeill
*/
public class LongCPInfo extends ConstantCPInfo
{

/**
* Constructor.
*/
public LongCPInfo()
{
super( CONSTANT_Long, 2 );
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
setValue( new Long( cpStream.readLong() ) );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
return "Long Constant Pool Entry: " + getValue();
}

}


+ 0
- 111
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodRefCPInfo.java View File

@@ -1,111 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A MethodRef CP Info
*
* @author Conor MacNeill
*/
public class MethodRefCPInfo extends ConstantPoolEntry
{
private int classIndex;
private String methodClassName;
private String methodName;
private String methodType;
private int nameAndTypeIndex;

/**
* Constructor.
*/
public MethodRefCPInfo()
{
super( CONSTANT_MethodRef, 1 );
}

public String getMethodClassName()
{
return methodClassName;
}

public String getMethodName()
{
return methodName;
}

public String getMethodType()
{
return methodType;
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
classIndex = cpStream.readUnsignedShort();
nameAndTypeIndex = cpStream.readUnsignedShort();
}

/**
* Resolve this constant pool entry with respect to its dependents in the
* constant pool.
*
* @param constantPool the constant pool of which this entry is a member and
* against which this entry is to be resolved.
*/
public void resolve( ConstantPool constantPool )
{
ClassCPInfo methodClass = (ClassCPInfo)constantPool.getEntry( classIndex );

methodClass.resolve( constantPool );

methodClassName = methodClass.getClassName();

NameAndTypeCPInfo nt = (NameAndTypeCPInfo)constantPool.getEntry( nameAndTypeIndex );

nt.resolve( constantPool );

methodName = nt.getName();
methodType = nt.getType();

super.resolve( constantPool );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
String value;

if( isResolved() )
{
value = "Method : Class = " + methodClassName + ", name = " + methodName + ", type = " + methodType;
}
else
{
value = "Method : Class index = " + classIndex + ", name and type index = " + nameAndTypeIndex;
}

return value;
}

}


+ 0
- 95
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/NameAndTypeCPInfo.java View File

@@ -1,95 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A NameAndType CP Info
*
* @author Conor MacNeill
*/
public class NameAndTypeCPInfo extends ConstantPoolEntry
{
private int descriptorIndex;

private String name;
private int nameIndex;
private String type;

/**
* Constructor.
*/
public NameAndTypeCPInfo()
{
super( CONSTANT_NameAndType, 1 );
}

public String getName()
{
return name;
}

public String getType()
{
return type;
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
nameIndex = cpStream.readUnsignedShort();
descriptorIndex = cpStream.readUnsignedShort();
}

/**
* Resolve this constant pool entry with respect to its dependents in the
* constant pool.
*
* @param constantPool the constant pool of which this entry is a member and
* against which this entry is to be resolved.
*/
public void resolve( ConstantPool constantPool )
{
name = ( (Utf8CPInfo)constantPool.getEntry( nameIndex ) ).getValue();
type = ( (Utf8CPInfo)constantPool.getEntry( descriptorIndex ) ).getValue();

super.resolve( constantPool );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
String value;

if( isResolved() )
{
value = "Name = " + name + ", type = " + type;
}
else
{
value = "Name index = " + nameIndex + ", descriptor index = " + descriptorIndex;
}

return value;
}
}


+ 0
- 71
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/StringCPInfo.java View File

@@ -1,71 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A String Constant Pool Entry. The String info contains an index into the
* constant pool where a UTF8 string is stored.
*
* @author Conor MacNeill
*/
public class StringCPInfo extends ConstantCPInfo
{

private int index;

/**
* Constructor.
*/
public StringCPInfo()
{
super( CONSTANT_String, 1 );
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
index = cpStream.readUnsignedShort();

setValue( "unresolved" );
}

/**
* Resolve this constant pool entry with respect to its dependents in the
* constant pool.
*
* @param constantPool the constant pool of which this entry is a member and
* against which this entry is to be resolved.
*/
public void resolve( ConstantPool constantPool )
{
setValue( ( (Utf8CPInfo)constantPool.getEntry( index ) ).getValue() );
super.resolve( constantPool );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
return "String Constant Pool Entry for " + getValue() + "[" + index + "]";
}
}


+ 0
- 60
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/Utf8CPInfo.java View File

@@ -1,60 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A UTF8 Constant Pool Entry.
*
* @author Conor MacNeill
*/
public class Utf8CPInfo extends ConstantPoolEntry
{
private String value;

/**
* Constructor.
*/
public Utf8CPInfo()
{
super( CONSTANT_Utf8, 1 );
}

public String getValue()
{
return value;
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
value = cpStream.readUTF();
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
return "UTF8 Value = " + value;
}

}


+ 0
- 118
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/ClassFile.java View File

@@ -1,118 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ClassCPInfo;
import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool;
import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPoolEntry;

/**
* A ClassFile object stores information about a Java class. The class may be
* read from a DataInputStream.and written to a DataOutputStream. These are
* usually streams from a Java class file or a class file component of a Jar
* file.
*
* @author Conor MacNeill
*/
public class ClassFile
{

/**
* The Magic Value that marks the start of a Java class file
*/
private final static int CLASS_MAGIC = 0xCAFEBABE;

/**
* The class name for this class.
*/
private String className;

/**
* This class' constant pool.
*/
private ConstantPool constantPool;

/**
* Get the classes which this class references.
*
* @return The ClassRefs value
*/
public ArrayList getClassRefs()
{

ArrayList classRefs = new ArrayList();

for( int i = 0; i < constantPool.size(); ++i )
{
ConstantPoolEntry entry = constantPool.getEntry( i );

if( entry != null && entry.getTag() == ConstantPoolEntry.CONSTANT_Class )
{
ClassCPInfo classEntry = (ClassCPInfo)entry;

if( !classEntry.getClassName().equals( className ) )
{
classRefs.add( ClassFileUtils.convertSlashName( classEntry.getClassName() ) );
}
}
}

return classRefs;
}

/**
* Get the class' fully qualified name in dot format.
*
* @return the class name in dot format (eg. java.lang.Object)
*/
public String getFullClassName()
{
return ClassFileUtils.convertSlashName( className );
}

/**
* Read the class from a data stream. This method takes an InputStream as
* input and parses the class from the stream. <p>
*
*
*
* @param stream an InputStream from which the class will be read
* @throws IOException if there is a problem reading from the given stream.
* @throws ClassFormatError if the class cannot be parsed correctly
*/
public void read( InputStream stream )
throws IOException, ClassFormatError
{
DataInputStream classStream = new DataInputStream( stream );

if( classStream.readInt() != CLASS_MAGIC )
{
throw new ClassFormatError( "No Magic Code Found - probably not a Java class file." );
}

// right we have a good looking class file.
int minorVersion = classStream.readUnsignedShort();
int majorVersion = classStream.readUnsignedShort();

// read the constant pool in and resolve it
constantPool = new ConstantPool();

constantPool.read( classStream );
constantPool.resolve();

int accessFlags = classStream.readUnsignedShort();
int thisClassIndex = classStream.readUnsignedShort();
int superClassIndex = classStream.readUnsignedShort();
className = ( (ClassCPInfo)constantPool.getEntry( thisClassIndex ) ).getClassName();
}
}


+ 0
- 14
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/ClassFileIterator.java View File

@@ -1,14 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend;

public interface ClassFileIterator
{

ClassFile getNextClassFile();
}

+ 0
- 44
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/ClassFileUtils.java View File

@@ -1,44 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend;

/**
* Utility class file routines. This class porovides a number of static utility
* methods to convert between the formats used in the Java class file format and
* those commonly used in Java programming.
*
* @author Conor MacNeill
*/
public class ClassFileUtils
{

/**
* Convert a class name from java source file dot notation to class file
* slash notation..
*
* @param dotName the class name in dot notation (eg. java.lang.Object).
* @return the class name in slash notation (eg. java/lang/Object).
*/
public static String convertDotName( String dotName )
{
return dotName.replace( '.', '/' );
}

/**
* Convert a class name from class file slash notation to java source file
* dot notation.
*
* @param name Description of Parameter
* @return the class name in dot notation (eg. java.lang.Object).
*/
public static String convertSlashName( String name )
{
return name.replace( '\\', '.' ).replace( '/', '.' );
}
}


+ 0
- 753
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/Depend.java View File

@@ -1,753 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.PathUtil;

/**
* Generate a dependency file for a given set of classes
*
* @author Conor MacNeill
*/
public class Depend extends MatchingTask
{

/**
* constants used with the cache file
*/
private final static String CACHE_FILE_NAME = "dependencies.txt";
private final static String CLASSNAME_PREPEND = "||:";

/**
* indicates that the dependency relationships should be extended beyond
* direct dependencies to include all classes. So if A directly affects B
* abd B directly affects C, then A indirectly affects C.
*/
private boolean closure = false;

/**
* Flag which controls whether the reversed dependencies should be dumped to
* the log
*/
private boolean dump = false;

/**
* A map which gives for every class a list of te class which it affects.
*/
private Hashtable affectedClassMap;

/**
* The directory which contains the dependency cache.
*/
private File cache;

/**
* A map which gives information about a class
*/
private Hashtable classFileInfoMap;

/**
* A map which gives the list of jars and classes from the classpath that a
* class depends upon
*/
private Hashtable classpathDependencies;

/**
* The classpath to look for additional dependencies
*/
private Path dependClasspath;

/**
* The path where compiled class files exist.
*/
private Path destPath;

/**
* The list of classes which are out of date.
*/
private Hashtable outOfDateClasses;

/**
* The path where source files exist
*/
private Path srcPath;

public void setCache( File cache )
{
this.cache = cache;
}

/**
* Set the classpath to be used for this dependency check.
*
* @param classpath The new Classpath value
*/
public void setClasspath( Path classpath )
throws TaskException
{
if( dependClasspath == null )
{
dependClasspath = classpath;
}
else
{
dependClasspath.append( classpath );
}
}

public void setClosure( boolean closure )
{
this.closure = closure;
}

/**
* Set the destination directory where the compiled java files exist.
*
* @param destPath The new DestDir value
*/
public void setDestDir( Path destPath )
{
this.destPath = destPath;
}

/**
* Flag to indicate whether the reverse dependency list should be dumped to
* debug
*
* @param dump The new Dump value
*/
public void setDump( boolean dump )
{
this.dump = dump;
}

/**
* Set the source dirs to find the source Java files.
*
* @param srcPath The new Srcdir value
*/
public void setSrcdir( Path srcPath )
{
this.srcPath = srcPath;
}

/**
* Gets the classpath to be used for this dependency check.
*
* @return The Classpath value
*/
public Path getClasspath()
{
return dependClasspath;
}

/**
* Creates a nested classpath element.
*
* @return Description of the Returned Value
*/
public Path createClasspath()
throws TaskException
{
if( dependClasspath == null )
{
dependClasspath = new Path();
}
Path path1 = dependClasspath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Does the work.
*
* @exception TaskException Thrown in unrecovrable error.
*/
public void execute()
throws TaskException
{
try
{
long start = System.currentTimeMillis();
String[] srcPathList = srcPath.list();
if( srcPathList.length == 0 )
{
throw new TaskException( "srcdir attribute must be set!" );
}

if( destPath == null )
{
destPath = srcPath;
}

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

if( cache != null && !cache.exists() )
{
cache.mkdirs();
}

determineDependencies();

if( dump )
{
getLogger().debug( "Reverse Dependency Dump for " + affectedClassMap.size() + " classes:" );
for( Enumeration e = affectedClassMap.keys(); e.hasMoreElements(); )
{
String className = (String)e.nextElement();
getLogger().debug( " Class " + className + " affects:" );
Hashtable affectedClasses = (Hashtable)affectedClassMap.get( className );
for( Enumeration e2 = affectedClasses.keys(); e2.hasMoreElements(); )
{
String affectedClass = (String)e2.nextElement();
ClassFileInfo info = (ClassFileInfo)affectedClasses.get( affectedClass );
getLogger().debug( " " + affectedClass + " in " + info.absoluteFile.getPath() );
}
}

if( classpathDependencies != null )
{
getLogger().debug( "Classpath file dependencies (Forward):" );
for( Enumeration e = classpathDependencies.keys(); e.hasMoreElements(); )
{
String className = (String)e.nextElement();
getLogger().debug( " Class " + className + " depends on:" );
Hashtable dependencies = (Hashtable)classpathDependencies.get( className );
for( Enumeration e2 = dependencies.elements(); e2.hasMoreElements(); )
{
File classpathFile = (File)e2.nextElement();
getLogger().debug( " " + classpathFile.getPath() );
}
}
}

}

// 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.
outOfDateClasses = new Hashtable();
for( int i = 0; i < srcPathList.length; i++ )
{
File srcDir = (File)resolveFile( srcPathList[ i ] );
if( srcDir.exists() )
{
DirectoryScanner ds = this.getDirectoryScanner( srcDir );
String[] files = ds.getIncludedFiles();
scanDir( srcDir, files );
}
}

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

// if we have no info about the class - it may have been deleted already and we
// are using cached info.
if( info != null )
{
Hashtable dependencies = (Hashtable)classpathDependencies.get( className );
for( Enumeration e2 = dependencies.elements(); e2.hasMoreElements(); )
{
File classpathFile = (File)e2.nextElement();
if( classpathFile.lastModified() > info.absoluteFile.lastModified() )
{
getLogger().debug( "Class " + className + " is out of date with respect to " + classpathFile );
outOfDateClasses.put( className, className );
break;
}
}
}
}
}
}

// we now have a complete list of classes which are out of date
// We scan through the affected classes, deleting any affected classes.
int count = deleteAllAffectedFiles();

long duration = ( System.currentTimeMillis() - start ) / 1000;
getLogger().info( "Deleted " + count + " out of date files in " + duration + " seconds" );
}
catch( Exception e )
{
throw new TaskException( "Error", e );
}
}

/**
* Scans the directory looking for source files that are newer than their
* class files. The results are returned in the class variable compileList
*
* @param srcDir Description of Parameter
* @param files Description of Parameter
*/
protected void scanDir( File srcDir, String files[] )
{

long now = System.currentTimeMillis();

for( int i = 0; i < files.length; i++ )
{
File srcFile = new File( srcDir, files[ i ] );
if( files[ i ].endsWith( ".java" ) )
{
String filePath = srcFile.getPath();
String className = filePath.substring( srcDir.getPath().length() + 1,
filePath.length() - ".java".length() );
className = ClassFileUtils.convertSlashName( className );
ClassFileInfo info = (ClassFileInfo)classFileInfoMap.get( className );
if( info == null )
{
// there was no class file. add this class to the list
outOfDateClasses.put( className, className );
}
else
{
if( srcFile.lastModified() > info.absoluteFile.lastModified() )
{
outOfDateClasses.put( className, className );
}
}
}
}
}

/**
* Get the list of class files we are going to analyse.
*
* @param classLocations a path structure containing all the directories
* where classes can be found.
* @return a vector containing the classes to analyse.
*/
private ArrayList getClassFiles( Path classLocations )
throws TaskException
{
// break the classLocations into its components.
String[] classLocationsList = classLocations.list();

ArrayList classFileList = new ArrayList();

for( int i = 0; i < classLocationsList.length; ++i )
{
File dir = new File( classLocationsList[ i ] );
if( dir.isDirectory() )
{
addClassFiles( classFileList, dir, dir );
}
}

return classFileList;
}

/**
* Add the list of class files from the given directory to the class file
* vector, including any subdirectories.
*
* @param classFileList The feature to be added to the ClassFiles attribute
* @param dir The feature to be added to the ClassFiles attribute
* @param root The feature to be added to the ClassFiles attribute
*/
private void addClassFiles( ArrayList classFileList, File dir, File root )
{
String[] filesInDir = dir.list();

if( filesInDir != null )
{
int length = filesInDir.length;

for( int i = 0; i < length; ++i )
{
File file = new File( dir, filesInDir[ i ] );
if( file.isDirectory() )
{
addClassFiles( classFileList, file, root );
}
else if( file.getName().endsWith( ".class" ) )
{
ClassFileInfo info = new ClassFileInfo();
info.absoluteFile = file;
info.relativeName = file.getPath().substring( root.getPath().length() + 1,
file.getPath().length() - 6 );
info.className = ClassFileUtils.convertSlashName( info.relativeName );
classFileList.add( info );
}
}
}
}

private int deleteAffectedFiles( String className )
{
int count = 0;

Hashtable affectedClasses = (Hashtable)affectedClassMap.get( className );
if( affectedClasses != null )
{
for( Enumeration e = affectedClasses.keys(); e.hasMoreElements(); )
{
String affectedClassName = (String)e.nextElement();
ClassFileInfo affectedClassInfo = (ClassFileInfo)affectedClasses.get( affectedClassName );
if( affectedClassInfo.absoluteFile.exists() )
{
getLogger().debug( "Deleting file " + affectedClassInfo.absoluteFile.getPath() + " since " + className + " out of date" );
affectedClassInfo.absoluteFile.delete();
count++;
if( closure )
{
count += deleteAffectedFiles( affectedClassName );
}
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 )
{
// need to delete the main class
String topLevelClassName
= affectedClassName.substring( 0, affectedClassName.indexOf( "$" ) );
getLogger().debug( "Top level class = " + topLevelClassName );
ClassFileInfo topLevelClassInfo
= (ClassFileInfo)classFileInfoMap.get( topLevelClassName );
if( topLevelClassInfo != null &&
topLevelClassInfo.absoluteFile.exists() )
{
getLogger().debug( "Deleting file " + topLevelClassInfo.absoluteFile.getPath() + " since " + "one of its inner classes was removed" );
topLevelClassInfo.absoluteFile.delete();
count++;
if( closure )
{
count += deleteAffectedFiles( topLevelClassName );
}
}
}
}
}
}
}
return count;
}

private int deleteAllAffectedFiles()
{
int count = 0;
for( Enumeration e = outOfDateClasses.elements(); e.hasMoreElements(); )
{
String className = (String)e.nextElement();
count += deleteAffectedFiles( className );
ClassFileInfo classInfo = (ClassFileInfo)classFileInfoMap.get( className );
if( classInfo != null && classInfo.absoluteFile.exists() )
{
classInfo.absoluteFile.delete();
count++;
}
}
return count;
}

/**
* Determine the dependencies between classes. Class dependencies are
* determined by examining the class references in a class file to other
* classes
*
* @exception IOException Description of Exception
*/
private void determineDependencies()
throws IOException, TaskException
{
affectedClassMap = new Hashtable();
classFileInfoMap = new Hashtable();
boolean cacheDirty = false;

Hashtable dependencyMap = new Hashtable();
File depCacheFile = null;
boolean depCacheFileExists = true;
long depCacheFileLastModified = 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();
}
for( Iterator e = getClassFiles( destPath ).iterator(); e.hasNext(); )
{
ClassFileInfo info = (ClassFileInfo)e.next();
getLogger().debug( "Adding class info for " + info.className );
classFileInfoMap.put( info.className, info );

ArrayList dependencyList = 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() )
{
// depFile exists and is newer than the class file
// need to get dependency list from the map.
dependencyList = (ArrayList)dependencyMap.get( info.className );
}
}

if( dependencyList == null )
{
// not cached - so need to read directly from the class file
FileInputStream inFileStream = null;
try
{
inFileStream = new FileInputStream( info.absoluteFile );
ClassFile classFile = new ClassFile();
classFile.read( inFileStream );

dependencyList = classFile.getClassRefs();
if( dependencyList != null )
{
cacheDirty = true;
dependencyMap.put( info.className, dependencyList );
}

}
finally
{
if( inFileStream != null )
{
inFileStream.close();
}
}
}

// This class depends on each class in the dependency list. For each
// one of those, add this class into their affected classes list
for( Iterator depEnum = dependencyList.iterator(); depEnum.hasNext(); )
{
String dependentClass = (String)depEnum.next();

Hashtable affectedClasses = (Hashtable)affectedClassMap.get( dependentClass );
if( affectedClasses == null )
{
affectedClasses = new Hashtable();
affectedClassMap.put( dependentClass, affectedClasses );
}

affectedClasses.put( info.className, info );
}
}

classpathDependencies = null;
if( dependClasspath != null )
{
// now determine which jars each class depends upon
classpathDependencies = new Hashtable();
final URL[] urls = PathUtil.toURLs( dependClasspath );
final ClassLoader classLoader = new URLClassLoader( urls );

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

if( !dependency.startsWith( "java." ) && !dependency.startsWith( "javax." ) )
{
final String name = dependency.replace( '.', '/' ) + ".class";
URL classURL = classLoader.getResource( name );
if( classURL != null )
{
if( classURL.getProtocol().equals( "jar" ) )
{
String jarFilePath = classURL.getFile();
if( jarFilePath.startsWith( "file:" ) )
{
int classMarker = jarFilePath.indexOf( '!' );
jarFilePath = jarFilePath.substring( 5, classMarker );
}
classpathFileObject = new File( jarFilePath );
}
else if( classURL.getProtocol().equals( "file" ) )
{
String classFilePath = classURL.getFile();
classpathFileObject = new File( classFilePath );
}
getLogger().debug( "Class " + className + " depends on " + classpathFileObject + " due to " + dependency );
}
}
classpathFileCache.put( dependency, classpathFileObject );
}
if( classpathFileObject != null && classpathFileObject != nullFileMarker )
{
// we need to add this jar to the list for this class.
File jarFile = (File)classpathFileObject;
dependencies.put( jarFile, jarFile );
}
}
}
}

// write the dependency cache to the disk
if( cache != null && cacheDirty )
{
writeCachedDependencies( dependencyMap );
}
}

/**
* Read the dependencies from cache file
*
* @return Description of the Returned Value
* @exception IOException Description of Exception
*/
private Hashtable readCachedDependencies()
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;
ArrayList dependencyList = null;
String className = null;
int prependLength = CLASSNAME_PREPEND.length();
while( ( line = in.readLine() ) != null )
{
if( line.startsWith( CLASSNAME_PREPEND ) )
{
dependencyList = new ArrayList();
className = line.substring( prependLength );
dependencyMap.put( className, dependencyList );
}
else
{
dependencyList.add( line );
}
}
}
finally
{
if( in != null )
{
in.close();
}
}
}
}

return dependencyMap;
}

/**
* Write the dependencies to cache file
*
* @param dependencyMap Description of Parameter
* @exception IOException Description of Exception
*/
private void writeCachedDependencies( Hashtable dependencyMap )
throws IOException
{
if( cache != null )
{
PrintWriter pw = null;
try
{
cache.mkdirs();
File depFile = new File( cache, CACHE_FILE_NAME );

pw = new PrintWriter( new FileWriter( depFile ) );
for( Enumeration deps = dependencyMap.keys(); deps.hasMoreElements(); )
{
String className = (String)deps.nextElement();

pw.println( CLASSNAME_PREPEND + className );

ArrayList dependencyList = (ArrayList)dependencyMap.get( className );
int size = dependencyList.size();
for( int x = 0; x < size; x++ )
{
pw.println( dependencyList.get( x ) );
}
}
}
finally
{
if( pw != null )
{
pw.close();
}
}
}
}

/**
* A class (struct) user to manage information about a class
*
* @author RT
*/
private static class ClassFileInfo
{
/**
* The file where the class file is stored in the file system
*/
public File absoluteFile;

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

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


+ 0
- 186
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java View File

@@ -1,186 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Stack;

/**
* An iterator which iterates through the contents of a java directory. The
* iterator should be created with the directory at the root of the Java
* namespace.
*
* @author Conor MacNeill
*/
public class DirectoryIterator implements ClassFileIterator
{

/**
* The length of the root directory. This is used to remove the root
* directory from full paths.
*/
int rootLength;

/**
* The current directory iterator. As directories encounter lower level
* directories, the current iterator is pushed onto the iterator stack and a
* new iterator over the sub directory becomes the current directory. This
* implements a depth first traversal of the directory namespace.
*/
private Iterator currentEnum;

/**
* This is a stack of current iterators supporting the depth first traversal
* of the directory tree.
*/
private Stack enumStack;

/**
* Creates a directory iterator. The directory iterator is created to scan
* the root directory. If the changeInto flag is given, then the entries
* returned will be relative to this directory and not the current
* directory.
*
* @param rootDirectory the root if the directory namespace which is to be
* iterated over
* @param changeInto if true then the returned entries will be relative to
* the rootDirectory and not the current directory.
* @exception IOException Description of Exception
* @throws IOException if there is a problem reading the directory
* information.
*/
public DirectoryIterator( File rootDirectory, boolean changeInto )
throws IOException
{
super();

enumStack = new Stack();

if( rootDirectory.isAbsolute() || changeInto )
{
rootLength = rootDirectory.getPath().length() + 1;
}
else
{
rootLength = 0;
}

ArrayList filesInRoot = getDirectoryEntries( rootDirectory );

currentEnum = filesInRoot.iterator();
}

/**
* Template method to allow subclasses to supply elements for the iteration.
* The directory iterator maintains a stack of iterators covering each level
* in the directory hierarchy. The current iterator covers the current
* directory being scanned. If the next entry in that directory is a
* subdirectory, the current iterator is pushed onto the stack and a new
* iterator is created for the subdirectory. If the entry is a file, it is
* returned as the next element and the iterator remains valid. If there are
* no more entries in the current directory, the topmost iterator on the
* statck is popped off to become the current iterator.
*
* @return the next ClassFile in the iteration.
*/
public ClassFile getNextClassFile()
{
ClassFile next = null;

try
{
while( next == null )
{
if( currentEnum.hasNext() )
{
File element = (File)currentEnum.next();

if( element.isDirectory() )
{

// push the current iterator onto the stack and then
// iterate through this directory.
enumStack.push( currentEnum );

ArrayList files = getDirectoryEntries( element );

currentEnum = files.iterator();
}
else
{

// we have a file. create a stream for it
FileInputStream inFileStream = new FileInputStream( element );

if( element.getName().endsWith( ".class" ) )
{

// create a data input stream from the jar input stream
ClassFile javaClass = new ClassFile();

javaClass.read( inFileStream );

next = javaClass;
}
}
}
else
{
// this iterator is exhausted. Can we pop one off the stack
if( enumStack.empty() )
{
break;
}
else
{
currentEnum = (Iterator)enumStack.pop();
}
}
}
}
catch( IOException e )
{
next = null;
}

return next;
}

/**
* Get a vector covering all the entries (files and subdirectories in a
* directory).
*
* @param directory the directory to be scanned.
* @return a vector containing File objects for each entry in the directory.
*/
private ArrayList getDirectoryEntries( File directory )
{
ArrayList files = new ArrayList();

// File[] filesInDir = directory.listFiles();
String[] filesInDir = directory.list();

if( filesInDir != null )
{
int length = filesInDir.length;

for( int i = 0; i < length; ++i )
{
files.add( new File( directory, filesInDir[ i ] ) );
}
}

return files;
}

}


+ 0
- 95
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/JarFileIterator.java View File

@@ -1,95 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
* A class file iterator which iterates through the contents of a Java jar file.
*
* @author Conor MacNeill
*/
public class JarFileIterator implements ClassFileIterator
{
private ZipInputStream jarStream;

public JarFileIterator( InputStream stream )
throws IOException
{
super();

jarStream = new ZipInputStream( stream );
}

public ClassFile getNextClassFile()
{
ZipEntry jarEntry;
ClassFile next = null;

try
{
jarEntry = jarStream.getNextEntry();

while( next == null && jarEntry != null )
{
String entryName = jarEntry.getName();

if( !jarEntry.isDirectory() && entryName.endsWith( ".class" ) )
{

// create a data input stream from the jar input stream
ClassFile javaClass = new ClassFile();

javaClass.read( jarStream );

next = javaClass;
}
else
{

jarEntry = jarStream.getNextEntry();
}
}
}
catch( IOException e )
{
String message = e.getMessage();
String text = e.getClass().getName();

if( message != null )
{
text += ": " + message;
}

throw new RuntimeException( "Problem reading JAR file: " + text );
}

return next;
}

private byte[] getEntryBytes( InputStream stream )
throws IOException
{
byte[] buffer = new byte[ 8192 ];
ByteArrayOutputStream baos = new ByteArrayOutputStream( 2048 );
int n;

while( ( n = stream.read( buffer, 0, buffer.length ) ) != -1 )
{
baos.write( buffer, 0, n );
}

return baos.toByteArray();
}

}


+ 0
- 89
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ClassCPInfo.java View File

@@ -1,89 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* The constant pool entry which stores class information.
*
* @author Conor MacNeill
*/
public class ClassCPInfo extends ConstantPoolEntry
{

/**
* The class' name. This will be only valid if the entry has been resolved
* against the constant pool.
*/
private String className;

/**
* The index into the constant pool where this class' name is stored. If the
* class name is changed, this entry is invalid until this entry is
* connected to a constant pool.
*/
private int index;

/**
* Constructor. Sets the tag value for this entry to type Class
*/
public ClassCPInfo()
{
super( CONSTANT_Class, 1 );
}

/**
* Get the class name of this entry.
*
* @return the class' name.
*/
public String getClassName()
{
return className;
}

/**
* Read the entry from a stream.
*
* @param cpStream the stream containing the constant pool entry to be read.
* @exception IOException thrown if there is a problem reading the entry
* from the stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
index = cpStream.readUnsignedShort();
className = "unresolved";
}

/**
* Resolve this class info against the given constant pool.
*
* @param constantPool the constant pool with which to resolve the class.
*/
public void resolve( ConstantPool constantPool )
{
className = ( (Utf8CPInfo)constantPool.getEntry( index ) ).getValue();

super.resolve( constantPool );
}

/**
* Generate a string readable version of this entry
*
* @return Description of the Returned Value
*/
public String toString()
{
return "Class Constant Pool Entry for " + className + "[" + index + "]";
}

}


+ 0
- 57
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantCPInfo.java View File

@@ -1,57 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

/**
* A Constant Pool entry which represents a constant value.
*
* @author Conor MacNeill
*/
public abstract class ConstantCPInfo extends ConstantPoolEntry
{

/**
* The entry's untyped value. Each subclass interprets the constant value
* based on the subclass's type. The value here must be compatible.
*/
private Object value;

/**
* Initialise the constant entry.
*
* @param tagValue the constant pool entry type to be used.
* @param entries the number of constant pool entry slots occupied by this
* entry.
*/
protected ConstantCPInfo( int tagValue, int entries )
{
super( tagValue, entries );
}

/**
* Set the constant value.
*
* @param newValue the new untyped value of this constant.
*/
public void setValue( Object newValue )
{
value = newValue;
}

/**
* Get the value of the constant.
*
* @return the value of the constant (untyped).
*/
public Object getValue()
{
return value;
}

}


+ 0
- 374
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPool.java View File

@@ -1,374 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;

/**
* The constant pool of a Java class. The constant pool is a collection of
* constants used in a Java class file. It stores strings, constant values,
* class names, method names, field names etc.
*
* @author Conor MacNeill
* @see <a href="http://java.sun.com/docs/books/vmspec/">The Java Virtual
* Machine Specification</a>
*/
public class ConstantPool
{

/**
* The entries in the constant pool.
*/
private ArrayList entries;

/**
* A Hashtable of UTF8 entries - used to get constant pool indexes of the
* UTF8 values quickly
*/
private Hashtable utf8Indexes;

/**
* Initialise the constant pool.
*/
public ConstantPool()
{
entries = new ArrayList();

// The zero index is never present in the constant pool itself so
// we add a null entry for it
entries.add( null );

utf8Indexes = new Hashtable();
}

/**
* Get the index of a given CONSTANT_Class entry in the constant pool.
*
* @param className the name of the class for which the class entry index is
* required.
* @return the index at which the given class entry occurs in the constant
* pool or -1 if the value does not occur.
*/
public int getClassEntry( String className )
{
int index = -1;

for( int i = 0; i < entries.size() && index == -1; ++i )
{
Object element = entries.get( i );

if( element instanceof ClassCPInfo )
{
ClassCPInfo classinfo = (ClassCPInfo)element;

if( classinfo.getClassName().equals( className ) )
{
index = i;
}
}
}

return index;
}

/**
* Get the index of a given constant value entry in the constant pool.
*
* @param constantValue the constant value for which the index is required.
* @return the index at which the given value entry occurs in the constant
* pool or -1 if the value does not occur.
*/
public int getConstantEntry( Object constantValue )
{
int index = -1;

for( int i = 0; i < entries.size() && index == -1; ++i )
{
Object element = entries.get( i );

if( element instanceof ConstantCPInfo )
{
ConstantCPInfo constantEntry = (ConstantCPInfo)element;

if( constantEntry.getValue().equals( constantValue ) )
{
index = i;
}
}
}

return index;
}

/**
* Get an constant pool entry at a particular index.
*
* @param index the index into the constant pool.
* @return the constant pool entry at that index.
*/
public ConstantPoolEntry getEntry( int index )
{
return (ConstantPoolEntry)entries.get( index );
}

/**
* Get the index of a given CONSTANT_FieldRef entry in the constant pool.
*
* @param fieldClassName the name of the class which contains the field
* being referenced.
* @param fieldName the name of the field being referenced.
* @param fieldType the type descriptor of the field being referenced.
* @return the index at which the given field ref entry occurs in the
* constant pool or -1 if the value does not occur.
*/
public int getFieldRefEntry( String fieldClassName, String fieldName, String fieldType )
{
int index = -1;

for( int i = 0; i < entries.size() && index == -1; ++i )
{
Object element = entries.get( i );

if( element instanceof FieldRefCPInfo )
{
FieldRefCPInfo fieldRefEntry = (FieldRefCPInfo)element;

if( fieldRefEntry.getFieldClassName().equals( fieldClassName ) && fieldRefEntry.getFieldName().equals( fieldName )
&& fieldRefEntry.getFieldType().equals( fieldType ) )
{
index = i;
}
}
}

return index;
}

/**
* Get the index of a given CONSTANT_InterfaceMethodRef entry in the
* constant pool.
*
* @param interfaceMethodClassName the name of the interface which contains
* the method being referenced.
* @param interfaceMethodName the name of the method being referenced.
* @param interfaceMethodType the type descriptor of the metho dbeing
* referenced.
* @return the index at which the given method ref entry occurs in the
* constant pool or -1 if the value does not occur.
*/
public int getInterfaceMethodRefEntry( String interfaceMethodClassName, String interfaceMethodName, String interfaceMethodType )
{
int index = -1;

for( int i = 0; i < entries.size() && index == -1; ++i )
{
Object element = entries.get( i );

if( element instanceof InterfaceMethodRefCPInfo )
{
InterfaceMethodRefCPInfo interfaceMethodRefEntry = (InterfaceMethodRefCPInfo)element;

if( interfaceMethodRefEntry.getInterfaceMethodClassName().equals( interfaceMethodClassName )
&& interfaceMethodRefEntry.getInterfaceMethodName().equals( interfaceMethodName )
&& interfaceMethodRefEntry.getInterfaceMethodType().equals( interfaceMethodType ) )
{
index = i;
}
}
}

return index;
}

/**
* Get the index of a given CONSTANT_MethodRef entry in the constant pool.
*
* @param methodClassName the name of the class which contains the method
* being referenced.
* @param methodName the name of the method being referenced.
* @param methodType the type descriptor of the metho dbeing referenced.
* @return the index at which the given method ref entry occurs in the
* constant pool or -1 if the value does not occur.
*/
public int getMethodRefEntry( String methodClassName, String methodName, String methodType )
{
int index = -1;

for( int i = 0; i < entries.size() && index == -1; ++i )
{
Object element = entries.get( i );

if( element instanceof MethodRefCPInfo )
{
MethodRefCPInfo methodRefEntry = (MethodRefCPInfo)element;

if( methodRefEntry.getMethodClassName().equals( methodClassName )
&& methodRefEntry.getMethodName().equals( methodName ) && methodRefEntry.getMethodType().equals( methodType ) )
{
index = i;
}
}
}

return index;
}

/**
* Get the index of a given CONSTANT_NameAndType entry in the constant pool.
*
* @param name the name
* @param type the type
* @return the index at which the given NameAndType entry occurs in the
* constant pool or -1 if the value does not occur.
*/
public int getNameAndTypeEntry( String name, String type )
{
int index = -1;

for( int i = 0; i < entries.size() && index == -1; ++i )
{
Object element = entries.get( i );

if( element instanceof NameAndTypeCPInfo )
{
NameAndTypeCPInfo nameAndTypeEntry = (NameAndTypeCPInfo)element;

if( nameAndTypeEntry.getName().equals( name ) && nameAndTypeEntry.getType().equals( type ) )
{
index = i;
}
}
}

return index;
}

/**
* Get the index of a given UTF8 constant pool entry.
*
* @param value the string value of the UTF8 entry.
* @return the index at which the given string occurs in the constant pool
* or -1 if the value does not occur.
*/
public int getUTF8Entry( String value )
{
int index = -1;
Integer indexInteger = (Integer)utf8Indexes.get( value );

if( indexInteger != null )
{
index = indexInteger.intValue();
}

return index;
}

/**
* Add an entry to the constant pool.
*
* @param entry the new entry to be added to the constant pool.
* @return the index into the constant pool at which the entry is stored.
*/
public int addEntry( ConstantPoolEntry entry )
{
int index = entries.size();

entries.add( entry );

int numSlots = entry.getNumEntries();

// add null entries for any additional slots required.
for( int j = 0; j < numSlots - 1; ++j )
{
entries.add( null );
}

if( entry instanceof Utf8CPInfo )
{
Utf8CPInfo utf8Info = (Utf8CPInfo)entry;

utf8Indexes.put( utf8Info.getValue(), new Integer( index ) );
}

return index;
}

/**
* Read the constant pool from a class input stream.
*
* @param classStream the DataInputStream of a class file.
* @throws IOException if there is a problem reading the constant pool from
* the stream
*/
public void read( DataInputStream classStream )
throws IOException
{
int numEntries = classStream.readUnsignedShort();

for( int i = 1; i < numEntries; )
{
ConstantPoolEntry nextEntry = ConstantPoolEntry.readEntry( classStream );

i += nextEntry.getNumEntries();

addEntry( nextEntry );
}
}

/**
* Resolve the entries in the constant pool. Resolution of the constant pool
* involves transforming indexes to other constant pool entries into the
* actual data for that entry.
*/
public void resolve()
{
for( Iterator i = entries.iterator(); i.hasNext(); )
{
ConstantPoolEntry poolInfo = (ConstantPoolEntry)i.next();

if( poolInfo != null && !poolInfo.isResolved() )
{
poolInfo.resolve( this );
}
}
}

/**
* Get the size of the constant pool.
*
* @return Description of the Returned Value
*/
public int size()
{
return entries.size();
}

/**
* Dump the constant pool to a string.
*
* @return the constant pool entries as strings
*/
public String toString()
{
StringBuffer sb = new StringBuffer( "\n" );
int size = entries.size();

for( int i = 0; i < size; ++i )
{
sb.append( "[" + i + "] = " + getEntry( i ) + "\n" );
}

return sb.toString();
}

}


+ 0
- 243
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPoolEntry.java View File

@@ -1,243 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* An entry in the constant pool. This class contains a represenation of the
* constant pool entries. It is an abstract base class for all the different
* forms of constant pool entry.
*
* @author Conor MacNeill
* @see ConstantPool
*/
public abstract class ConstantPoolEntry
{

/**
* Tag value for UTF8 entries.
*/
public final static int CONSTANT_Utf8 = 1;

/**
* Tag value for Integer entries.
*/
public final static int CONSTANT_Integer = 3;

/**
* Tag value for Float entries.
*/
public final static int CONSTANT_Float = 4;

/**
* Tag value for Long entries.
*/
public final static int CONSTANT_Long = 5;

/**
* Tag value for Double entries.
*/
public final static int CONSTANT_Double = 6;

/**
* Tag value for Class entries.
*/
public final static int CONSTANT_Class = 7;

/**
* Tag value for String entries.
*/
public final static int CONSTANT_String = 8;

/**
* Tag value for Field Reference entries.
*/
public final static int CONSTANT_FieldRef = 9;

/**
* Tag value for Method Reference entries.
*/
public final static int CONSTANT_MethodRef = 10;

/**
* Tag value for Interface Method Reference entries.
*/
public final static int CONSTANT_InterfaceMethodRef = 11;

/**
* Tag value for Name and Type entries.
*/
public final static int CONSTANT_NameAndType = 12;

/**
* The number of slots in the constant pool, occupied by this entry.
*/
private int numEntries;

/**
* A flag which indiciates if this entry has been resolved or not.
*/
private boolean resolved;

/**
* This entry's tag which identifies the type of this constant pool entry.
*/
private int tag;

/**
* Initialse the constant pool entry.
*
* @param tagValue the tag value which identifies which type of constant
* pool entry this is.
* @param entries the number of constant pool entry slots this entry
* occupies.
*/
public ConstantPoolEntry( int tagValue, int entries )
{
tag = tagValue;
numEntries = entries;
resolved = false;
}

/**
* Read a constant pool entry from a stream. This is a factory method which
* reads a constant pool entry form a stream and returns the appropriate
* subclass for the entry.
*
* @param cpStream the stream from which the constant pool entry is to be
* read.
* @return Description of the Returned Value
* @exception IOException Description of Exception
* @returns the appropriate ConstantPoolEntry subclass representing the
* constant pool entry from the stream.
* @throws IOExcception if there is a problem reading the entry from the
* stream.
*/
public static ConstantPoolEntry readEntry( DataInputStream cpStream )
throws IOException
{
ConstantPoolEntry cpInfo = null;
int cpTag = cpStream.readUnsignedByte();

switch( cpTag )
{

case CONSTANT_Utf8:
cpInfo = new Utf8CPInfo();

break;
case CONSTANT_Integer:
cpInfo = new IntegerCPInfo();

break;
case CONSTANT_Float:
cpInfo = new FloatCPInfo();

break;
case CONSTANT_Long:
cpInfo = new LongCPInfo();

break;
case CONSTANT_Double:
cpInfo = new DoubleCPInfo();

break;
case CONSTANT_Class:
cpInfo = new ClassCPInfo();

break;
case CONSTANT_String:
cpInfo = new StringCPInfo();

break;
case CONSTANT_FieldRef:
cpInfo = new FieldRefCPInfo();

break;
case CONSTANT_MethodRef:
cpInfo = new MethodRefCPInfo();

break;
case CONSTANT_InterfaceMethodRef:
cpInfo = new InterfaceMethodRefCPInfo();

break;
case CONSTANT_NameAndType:
cpInfo = new NameAndTypeCPInfo();

break;
default:
throw new ClassFormatError( "Invalid Constant Pool entry Type " + cpTag );
}

cpInfo.read( cpStream );

return cpInfo;
}

/**
* Get the number of Constant Pool Entry slots within the constant pool
* occupied by this entry.
*
* @return the number of slots used.
*/
public final int getNumEntries()
{
return numEntries;
}

/**
* Get the Entry's type tag.
*
* @return The Tag value of this entry
*/
public int getTag()
{
return tag;
}

/**
* Indicates whether this entry has been resolved. In general a constant
* pool entry can reference another constant pool entry by its index value.
* Resolution involves replacing this index value with the constant pool
* entry at that index.
*
* @return true if this entry has been resolved.
*/
public boolean isResolved()
{
return resolved;
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public abstract void read( DataInputStream cpStream )
throws IOException;

/**
* Resolve this constant pool entry with respect to its dependents in the
* constant pool.
*
* @param constantPool the constant pool of which this entry is a member and
* against which this entry is to be resolved.
*/
public void resolve( ConstantPool constantPool )
{
resolved = true;
}

}


+ 0
- 50
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/DoubleCPInfo.java View File

@@ -1,50 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* The constant pool entry subclass used to represent double constant values.
*
* @author Conor MacNeill
*/
public class DoubleCPInfo extends ConstantCPInfo
{
public DoubleCPInfo()
{
super( CONSTANT_Double, 2 );
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
setValue( new Double( cpStream.readDouble() ) );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
return "Double Constant Pool Entry: " + getValue();
}

}


+ 0
- 111
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FieldRefCPInfo.java View File

@@ -1,111 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A FieldRef CP Info
*
* @author Conor MacNeill
*/
public class FieldRefCPInfo extends ConstantPoolEntry
{
private int classIndex;
private String fieldClassName;
private String fieldName;
private String fieldType;
private int nameAndTypeIndex;

/**
* Constructor.
*/
public FieldRefCPInfo()
{
super( CONSTANT_FieldRef, 1 );
}

public String getFieldClassName()
{
return fieldClassName;
}

public String getFieldName()
{
return fieldName;
}

public String getFieldType()
{
return fieldType;
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
classIndex = cpStream.readUnsignedShort();
nameAndTypeIndex = cpStream.readUnsignedShort();
}

/**
* Resolve this constant pool entry with respect to its dependents in the
* constant pool.
*
* @param constantPool the constant pool of which this entry is a member and
* against which this entry is to be resolved.
*/
public void resolve( ConstantPool constantPool )
{
ClassCPInfo fieldClass = (ClassCPInfo)constantPool.getEntry( classIndex );

fieldClass.resolve( constantPool );

fieldClassName = fieldClass.getClassName();

NameAndTypeCPInfo nt = (NameAndTypeCPInfo)constantPool.getEntry( nameAndTypeIndex );

nt.resolve( constantPool );

fieldName = nt.getName();
fieldType = nt.getType();

super.resolve( constantPool );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
String value;

if( isResolved() )
{
value = "Field : Class = " + fieldClassName + ", name = " + fieldName + ", type = " + fieldType;
}
else
{
value = "Field : Class index = " + classIndex + ", name and type index = " + nameAndTypeIndex;
}

return value;
}

}


+ 0
- 54
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FloatCPInfo.java View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A Float CP Info
*
* @author Conor MacNeill
*/
public class FloatCPInfo extends ConstantCPInfo
{

/**
* Constructor.
*/
public FloatCPInfo()
{
super( CONSTANT_Float, 1 );
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
setValue( new Float( cpStream.readFloat() ) );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
return "Float Constant Pool Entry: " + getValue();
}

}


+ 0
- 54
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/IntegerCPInfo.java View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* An Integer CP Info
*
* @author Conor MacNeill
*/
public class IntegerCPInfo extends ConstantCPInfo
{

/**
* Constructor.
*/
public IntegerCPInfo()
{
super( CONSTANT_Integer, 1 );
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
setValue( new Integer( cpStream.readInt() ) );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
return "Integer Constant Pool Entry: " + getValue();
}

}


+ 0
- 112
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InterfaceMethodRefCPInfo.java View File

@@ -1,112 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A InterfaceMethodRef CP Info
*
* @author Conor MacNeill
*/
public class InterfaceMethodRefCPInfo extends ConstantPoolEntry
{
private int classIndex;
private String interfaceMethodClassName;
private String interfaceMethodName;
private String interfaceMethodType;
private int nameAndTypeIndex;

/**
* Constructor.
*/
public InterfaceMethodRefCPInfo()
{
super( CONSTANT_InterfaceMethodRef, 1 );
}

public String getInterfaceMethodClassName()
{
return interfaceMethodClassName;
}

public String getInterfaceMethodName()
{
return interfaceMethodName;
}

public String getInterfaceMethodType()
{
return interfaceMethodType;
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
classIndex = cpStream.readUnsignedShort();
nameAndTypeIndex = cpStream.readUnsignedShort();
}

/**
* Resolve this constant pool entry with respect to its dependents in the
* constant pool.
*
* @param constantPool the constant pool of which this entry is a member and
* against which this entry is to be resolved.
*/
public void resolve( ConstantPool constantPool )
{
ClassCPInfo interfaceMethodClass = (ClassCPInfo)constantPool.getEntry( classIndex );

interfaceMethodClass.resolve( constantPool );

interfaceMethodClassName = interfaceMethodClass.getClassName();

NameAndTypeCPInfo nt = (NameAndTypeCPInfo)constantPool.getEntry( nameAndTypeIndex );

nt.resolve( constantPool );

interfaceMethodName = nt.getName();
interfaceMethodType = nt.getType();

super.resolve( constantPool );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
String value;

if( isResolved() )
{
value = "InterfaceMethod : Class = " + interfaceMethodClassName + ", name = " + interfaceMethodName + ", type = "
+ interfaceMethodType;
}
else
{
value = "InterfaceMethod : Class index = " + classIndex + ", name and type index = " + nameAndTypeIndex;
}

return value;
}

}


+ 0
- 54
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/LongCPInfo.java View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A Long CP Info
*
* @author Conor MacNeill
*/
public class LongCPInfo extends ConstantCPInfo
{

/**
* Constructor.
*/
public LongCPInfo()
{
super( CONSTANT_Long, 2 );
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
setValue( new Long( cpStream.readLong() ) );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
return "Long Constant Pool Entry: " + getValue();
}

}


+ 0
- 111
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodRefCPInfo.java View File

@@ -1,111 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A MethodRef CP Info
*
* @author Conor MacNeill
*/
public class MethodRefCPInfo extends ConstantPoolEntry
{
private int classIndex;
private String methodClassName;
private String methodName;
private String methodType;
private int nameAndTypeIndex;

/**
* Constructor.
*/
public MethodRefCPInfo()
{
super( CONSTANT_MethodRef, 1 );
}

public String getMethodClassName()
{
return methodClassName;
}

public String getMethodName()
{
return methodName;
}

public String getMethodType()
{
return methodType;
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
classIndex = cpStream.readUnsignedShort();
nameAndTypeIndex = cpStream.readUnsignedShort();
}

/**
* Resolve this constant pool entry with respect to its dependents in the
* constant pool.
*
* @param constantPool the constant pool of which this entry is a member and
* against which this entry is to be resolved.
*/
public void resolve( ConstantPool constantPool )
{
ClassCPInfo methodClass = (ClassCPInfo)constantPool.getEntry( classIndex );

methodClass.resolve( constantPool );

methodClassName = methodClass.getClassName();

NameAndTypeCPInfo nt = (NameAndTypeCPInfo)constantPool.getEntry( nameAndTypeIndex );

nt.resolve( constantPool );

methodName = nt.getName();
methodType = nt.getType();

super.resolve( constantPool );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
String value;

if( isResolved() )
{
value = "Method : Class = " + methodClassName + ", name = " + methodName + ", type = " + methodType;
}
else
{
value = "Method : Class index = " + classIndex + ", name and type index = " + nameAndTypeIndex;
}

return value;
}

}


+ 0
- 95
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/NameAndTypeCPInfo.java View File

@@ -1,95 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A NameAndType CP Info
*
* @author Conor MacNeill
*/
public class NameAndTypeCPInfo extends ConstantPoolEntry
{
private int descriptorIndex;

private String name;
private int nameIndex;
private String type;

/**
* Constructor.
*/
public NameAndTypeCPInfo()
{
super( CONSTANT_NameAndType, 1 );
}

public String getName()
{
return name;
}

public String getType()
{
return type;
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
nameIndex = cpStream.readUnsignedShort();
descriptorIndex = cpStream.readUnsignedShort();
}

/**
* Resolve this constant pool entry with respect to its dependents in the
* constant pool.
*
* @param constantPool the constant pool of which this entry is a member and
* against which this entry is to be resolved.
*/
public void resolve( ConstantPool constantPool )
{
name = ( (Utf8CPInfo)constantPool.getEntry( nameIndex ) ).getValue();
type = ( (Utf8CPInfo)constantPool.getEntry( descriptorIndex ) ).getValue();

super.resolve( constantPool );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
String value;

if( isResolved() )
{
value = "Name = " + name + ", type = " + type;
}
else
{
value = "Name index = " + nameIndex + ", descriptor index = " + descriptorIndex;
}

return value;
}
}


+ 0
- 71
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/StringCPInfo.java View File

@@ -1,71 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A String Constant Pool Entry. The String info contains an index into the
* constant pool where a UTF8 string is stored.
*
* @author Conor MacNeill
*/
public class StringCPInfo extends ConstantCPInfo
{

private int index;

/**
* Constructor.
*/
public StringCPInfo()
{
super( CONSTANT_String, 1 );
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
index = cpStream.readUnsignedShort();

setValue( "unresolved" );
}

/**
* Resolve this constant pool entry with respect to its dependents in the
* constant pool.
*
* @param constantPool the constant pool of which this entry is a member and
* against which this entry is to be resolved.
*/
public void resolve( ConstantPool constantPool )
{
setValue( ( (Utf8CPInfo)constantPool.getEntry( index ) ).getValue() );
super.resolve( constantPool );
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
return "String Constant Pool Entry for " + getValue() + "[" + index + "]";
}
}


+ 0
- 60
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/depend/constantpool/Utf8CPInfo.java View File

@@ -1,60 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.depend.constantpool;

import java.io.DataInputStream;
import java.io.IOException;

/**
* A UTF8 Constant Pool Entry.
*
* @author Conor MacNeill
*/
public class Utf8CPInfo extends ConstantPoolEntry
{
private String value;

/**
* Constructor.
*/
public Utf8CPInfo()
{
super( CONSTANT_Utf8, 1 );
}

public String getValue()
{
return value;
}

/**
* read a constant pool entry from a class stream.
*
* @param cpStream the DataInputStream which contains the constant pool
* entry to be read.
* @throws IOException if there is a problem reading the entry from the
* stream.
*/
public void read( DataInputStream cpStream )
throws IOException
{
value = cpStream.readUTF();
}

/**
* Print a readable version of the constant pool entry.
*
* @return the string representation of this constant pool entry.
*/
public String toString()
{
return "UTF8 Value = " + value;
}

}


Loading…
Cancel
Save