diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java deleted file mode 100644 index 777f617bf..000000000 --- a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java +++ /dev/null @@ -1,116 +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.jlink; - -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * Provides a quick and dirty way to determine the true name of a class given - * just an InputStream. Reads in just enough to perform this minimal task only. - * - * @author RT - */ -public class ClassNameReader extends Object -{ - - public static String getClassName( InputStream input ) - throws IOException - { - DataInputStream data = new DataInputStream( input ); - // verify this is a valid class file. - int cookie = data.readInt(); - if( cookie != 0xCAFEBABE ) - { - return null; - } - int version = data.readInt(); - // read the constant pool. - ConstantPool constants = new ConstantPool( data ); - Object[] values = constants.values; - // read access flags and class index. - int accessFlags = data.readUnsignedShort(); - int classIndex = data.readUnsignedShort(); - Integer stringIndex = (Integer)values[ classIndex ]; - String className = (String)values[ stringIndex.intValue() ]; - return className; - } - -} - -/** - * Reads just enough of a class file to determine the class' full name.
- * - * Extremely minimal constant pool implementation, mainly to support extracting - * strings from a class file. - * - * @author Patrick C. Beard . - */ -class ConstantPool extends Object -{ - - final static byte UTF8 = 1, UNUSED = 2, INTEGER = 3, FLOAT = 4, LONG = 5, DOUBLE = 6, - CLASS = 7, STRING = 8, FIELDREF = 9, METHODREF = 10, - INTERFACEMETHODREF = 11, NAMEANDTYPE = 12; - - byte[] types; - - Object[] values; - - ConstantPool( DataInput data ) - throws IOException - { - super(); - - int count = data.readUnsignedShort(); - types = new byte[ count ]; - values = new Object[ count ]; - // read in all constant pool entries. - for( int i = 1; i < count; i++ ) - { - byte type = data.readByte(); - types[ i ] = type; - switch( type ) - { - case UTF8: - values[ i ] = data.readUTF(); - break; - case UNUSED: - break; - case INTEGER: - values[ i ] = new Integer( data.readInt() ); - break; - case FLOAT: - values[ i ] = new Float( data.readFloat() ); - break; - case LONG: - values[ i ] = new Long( data.readLong() ); - ++i; - break; - case DOUBLE: - values[ i ] = new Double( data.readDouble() ); - ++i; - break; - case CLASS: - case STRING: - values[ i ] = new Integer( data.readUnsignedShort() ); - break; - case FIELDREF: - case METHODREF: - case INTERFACEMETHODREF: - case NAMEANDTYPE: - values[ i ] = new Integer( data.readInt() ); - break; - } - } - } - -} - diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java deleted file mode 100644 index 58b57984a..000000000 --- a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java +++ /dev/null @@ -1,210 +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.jlink; - -import java.io.File; -import org.apache.myrmidon.api.TaskException; -import org.apache.tools.ant.taskdefs.MatchingTask; -import org.apache.tools.ant.types.Path; - -/** - * This class defines objects that can link together various jar and zip files. - *
- * - * It is basically a wrapper for the jlink code written originally by Patrick Beard . The classes - * org.apache.tools.ant.taskdefs.optional.jlink.Jlink and - * org.apache.tools.ant.taskdefs.optional.jlink.ClassNameReader support this - * class.
- *
- * For example:
- *
- *
- * @author Matthew Kuperus Heun
- *
- */
-public class JlinkTask extends MatchingTask
-{
-
- private File outfile = null;
-
- private Path mergefiles = null;
-
- private Path addfiles = null;
-
- private boolean compress = false;
-
- private String ps = System.getProperty( "path.separator" );
-
- /**
- * Sets the files to be added into the output.
- *
- * @param addfiles The new Addfiles value
- */
- public void setAddfiles( Path addfiles )
- throws TaskException
- {
- if( this.addfiles == null )
- {
- this.addfiles = addfiles;
- }
- else
- {
- this.addfiles.append( addfiles );
- }
- }
-
- /**
- * Defines whether or not the output should be compacted.
- *
- * @param compress The new Compress value
- */
- public void setCompress( boolean compress )
- {
- this.compress = compress;
- }
-
- /**
- * Sets the files to be merged into the output.
- *
- * @param mergefiles The new Mergefiles value
- */
- public void setMergefiles( Path mergefiles )
- throws TaskException
- {
- if( this.mergefiles == null )
- {
- this.mergefiles = mergefiles;
- }
- else
- {
- this.mergefiles.append( mergefiles );
- }
- }
-
- /**
- * The output file for this run of jlink. Usually a jar or zip file.
- *
- * @param outfile The new Outfile value
- */
- public void setOutfile( File outfile )
- {
- this.outfile = outfile;
- }
-
- /**
- * Establishes the object that contains the files to be added to the output.
- *
- * @return Description of the Returned Value
- */
- public Path createAddfiles()
- throws TaskException
- {
- if( this.addfiles == null )
- {
- this.addfiles = new Path();
- }
- return this.addfiles.createPath();
- }
-
- /**
- * Establishes the object that contains the files to be merged into the
- * output.
- *
- * @return Description of the Returned Value
- */
- public Path createMergefiles()
- throws TaskException
- {
- if( this.mergefiles == null )
- {
- this.mergefiles = new Path();
- }
- return this.mergefiles.createPath();
- }
-
- /**
- * Does the adding and merging.
- *
- * @exception TaskException Description of Exception
- */
- public void execute()
- throws TaskException
- {
- //Be sure everything has been set.
- if( outfile == null )
- {
- throw new TaskException( "outfile attribute is required! Please set." );
- }
- if( !haveAddFiles() && !haveMergeFiles() )
- {
- throw new TaskException( "addfiles or mergefiles required! Please set." );
- }
- getLogger().info( "linking: " + outfile.getPath() );
- getLogger().debug( "compression: " + compress );
- jlink linker = new jlink();
- linker.setOutfile( outfile.getPath() );
- linker.setCompression( compress );
- if( haveMergeFiles() )
- {
- getLogger().debug( "merge files: " + mergefiles.toString() );
- linker.addMergeFiles( mergefiles.list() );
- }
- if( haveAddFiles() )
- {
- getLogger().debug( "add files: " + addfiles.toString() );
- linker.addAddFiles( addfiles.list() );
- }
- try
- {
- linker.link();
- }
- catch( Exception ex )
- {
- throw new TaskException( "Error", ex );
- }
- }
-
- private boolean haveAddFiles()
- throws TaskException
- {
- return haveEntries( addfiles );
- }
-
- private boolean haveEntries( Path p )
- throws TaskException
- {
- if( p == null )
- {
- return false;
- }
- if( p.size() > 0 )
- {
- return true;
- }
- return false;
- }
-
- private boolean haveMergeFiles()
- throws TaskException
- {
- return haveEntries( mergefiles );
- }
-}
-
diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java
deleted file mode 100644
index c1b33c9bb..000000000
--- a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java
+++ /dev/null
@@ -1,469 +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.jlink;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.zip.CRC32;
-import java.util.zip.Deflater;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipOutputStream;
-
-public class jlink extends Object
-{
-
- private String outfile = null;
-
- private ArrayList mergefiles = new ArrayList( 10 );
-
- private ArrayList addfiles = new ArrayList( 10 );
-
- private boolean compression = false;
-
- byte[] buffer = new byte[ 8192 ];
-
- public static void main( String[] args )
- {
- // jlink output input1 ... inputN
- if( args.length < 2 )
- {
- System.out.println( "usage: jlink output input1 ... inputN" );
- System.exit( 1 );
- }
- jlink linker = new jlink();
- linker.setOutfile( args[ 0 ] );
- //To maintain compatibility with the command-line version, we will only add files to be merged.
- for( int i = 1; i < args.length; i++ )
- {
- linker.addMergeFile( args[ i ] );
- }
- try
- {
- linker.link();
- }
- catch( Exception ex )
- {
- System.err.print( ex.getMessage() );
- }
- }
-
- /**
- * Determines whether output will be compressed.
- *
- * @param compress The new Compression value
- */
- public void setCompression( boolean compress )
- {
- this.compression = compress;
- }
-
- /**
- * The file that will be created by this instance of jlink.
- *
- * @param outfile The new Outfile value
- */
- public void setOutfile( String outfile )
- {
- if( outfile == null )
- {
- return;
- }
- this.outfile = outfile;
- }
-
- /**
- * Adds a file to be added into the output.
- *
- * @param addfile The feature to be added to the AddFile attribute
- */
- public void addAddFile( String addfile )
- {
- if( addfile == null )
- {
- return;
- }
- addfiles.add( addfile );
- }
-
- /**
- * Adds several file to be added into the output.
- *
- * @param addfiles The feature to be added to the AddFiles attribute
- */
- public void addAddFiles( String[] addfiles )
- {
- if( addfiles == null )
- {
- return;
- }
- for( int i = 0; i < addfiles.length; i++ )
- {
- addAddFile( addfiles[ i ] );
- }
- }
-
- /**
- * Adds a file to be merged into the output.
- *
- * @param mergefile The feature to be added to the MergeFile attribute
- */
- public void addMergeFile( String mergefile )
- {
- if( mergefile == null )
- {
- return;
- }
- mergefiles.add( mergefile );
- }
-
- /**
- * Adds several files to be merged into the output.
- *
- * @param mergefiles The feature to be added to the MergeFiles attribute
- */
- public void addMergeFiles( String[] mergefiles )
- {
- if( mergefiles == null )
- {
- return;
- }
- for( int i = 0; i < mergefiles.length; i++ )
- {
- addMergeFile( mergefiles[ i ] );
- }
- }
-
- /**
- * Performs the linking of files. Addfiles are added to the output as-is.
- * For example, a jar file is added to the output as a jar file. However,
- * mergefiles are first examined for their type. If it is a jar or zip file,
- * the contents will be extracted from the mergefile and entered into the
- * output. If a zip or jar file is encountered in a subdirectory it will be
- * added, not merged. If a directory is encountered, it becomes the root
- * entry of all the files below it. Thus, you can provide multiple, disjoint
- * directories, as addfiles: they will all be added in a rational manner to
- * outfile.
- *
- * @exception Exception Description of Exception
- */
- public void link()
- throws Exception
- {
- ZipOutputStream output = new ZipOutputStream( new FileOutputStream( outfile ) );
- if( compression )
- {
- output.setMethod( ZipOutputStream.DEFLATED );
- output.setLevel( Deflater.DEFAULT_COMPRESSION );
- }
- else
- {
- output.setMethod( ZipOutputStream.STORED );
- }
- Iterator merges = mergefiles.iterator();
- while( merges.hasNext() )
- {
- String path = (String)merges.next();
- File f = new File( path );
- if( f.getName().endsWith( ".jar" ) || f.getName().endsWith( ".zip" ) )
- {
- //Do the merge
- mergeZipJarContents( output, f );
- }
- else
- {
- //Add this file to the addfiles ArrayList and add it
- //later at the top level of the output file.
- addAddFile( path );
- }
- }
- Iterator adds = addfiles.iterator();
- while( adds.hasNext() )
- {
- String name = (String)adds.next();
- File f = new File( name );
- if( f.isDirectory() )
- {
- //System.out.println("in jlink: adding directory contents of " + f.getPath());
- addDirContents( output, f, f.getName() + '/', compression );
- }
- else
- {
- addFile( output, f, "", compression );
- }
- }
- if( output != null )
- {
- try
- {
- output.close();
- }
- catch( IOException ioe )
- {
- }
- }
- }
-
- /*
- * Gets the name of an entry in the file. This is the real name
- * which for a class is the name of the package with the class
- * name appended.
- */
- private String getEntryName( File file, String prefix )
- {
- String name = file.getName();
- if( !name.endsWith( ".class" ) )
- {
- // see if the file is in fact a .class file, and determine its actual name.
- try
- {
- InputStream input = new FileInputStream( file );
- String className = ClassNameReader.getClassName( input );
- input.close();
- if( className != null )
- {
- return className.replace( '.', '/' ) + ".class";
- }
- }
- catch( IOException ioe )
- {
- }
- }
- System.out.println( "From " + file.getPath() + " and prefix " + prefix + ", creating entry " + prefix + name );
- return ( prefix + name );
- }
-
- /*
- * Adds contents of a directory to the output.
- */
- private void addDirContents( ZipOutputStream output, File dir, String prefix, boolean compress )
- throws IOException
- {
- String[] contents = dir.list();
- for( int i = 0; i < contents.length; ++i )
- {
- String name = contents[ i ];
- File file = new File( dir, name );
- if( file.isDirectory() )
- {
- addDirContents( output, file, prefix + name + '/', compress );
- }
- else
- {
- addFile( output, file, prefix, compress );
- }
- }
- }
-
- /*
- * Adds a file to the output stream.
- */
- private void addFile( ZipOutputStream output, File file, String prefix, boolean compress )
- throws IOException
- {
- //Make sure file exists
- long checksum = 0;
- if( !file.exists() )
- {
- return;
- }
- ZipEntry entry = new ZipEntry( getEntryName( file, prefix ) );
- entry.setTime( file.lastModified() );
- entry.setSize( file.length() );
- if( !compress )
- {
- entry.setCrc( calcChecksum( file ) );
- }
- FileInputStream input = new FileInputStream( file );
- addToOutputStream( output, input, entry );
- }
-
- /*
- * A convenience method that several other methods might call.
- */
- private void addToOutputStream( ZipOutputStream output, InputStream input, ZipEntry ze )
- throws IOException
- {
- try
- {
- output.putNextEntry( ze );
- }
- catch( ZipException zipEx )
- {
- //This entry already exists. So, go with the first one.
- input.close();
- return;
- }
- int numBytes = -1;
- while( ( numBytes = input.read( buffer ) ) > 0 )
- {
- output.write( buffer, 0, numBytes );
- }
- output.closeEntry();
- input.close();
- }
-
- /*
- * Necessary in the case where you add a entry that
- * is not compressed.
- */
- private long calcChecksum( File f )
- throws IOException
- {
- BufferedInputStream in = new BufferedInputStream( new FileInputStream( f ) );
- return calcChecksum( in, f.length() );
- }
-
- /*
- * Necessary in the case where you add a entry that
- * is not compressed.
- */
- private long calcChecksum( InputStream in, long size )
- throws IOException
- {
- CRC32 crc = new CRC32();
- int len = buffer.length;
- int count = -1;
- int haveRead = 0;
- while( ( count = in.read( buffer, 0, len ) ) > 0 )
- {
- haveRead += count;
- crc.update( buffer, 0, count );
- }
- in.close();
- return crc.getValue();
- }
-
- /*
- * Actually performs the merging of f into the output.
- * f should be a zip or jar file.
- */
- private void mergeZipJarContents( ZipOutputStream output, File f )
- throws IOException
- {
- //Check to see that the file with name "name" exists.
- if( !f.exists() )
- {
- return;
- }
- ZipFile zipf = new ZipFile( f );
- Enumeration entries = zipf.entries();
- while( entries.hasMoreElements() )
- {
- ZipEntry inputEntry = (ZipEntry)entries.nextElement();
- //Ignore manifest entries. They're bound to cause conflicts between
- //files that are being merged. User should supply their own
- //manifest file when doing the merge.
- String inputEntryName = inputEntry.getName();
- int index = inputEntryName.indexOf( "META-INF" );
- if( index < 0 )
- {
- //META-INF not found in the name of the entry. Go ahead and process it.
- try
- {
- output.putNextEntry( processEntry( zipf, inputEntry ) );
- }
- catch( ZipException ex )
- {
- //If we get here, it could be because we are trying to put a
- //directory entry that already exists.
- //For example, we're trying to write "com", but a previous
- //entry from another mergefile was called "com".
- //In that case, just ignore the error and go on to the
- //next entry.
- String mess = ex.getMessage();
- if( mess.indexOf( "duplicate" ) >= 0 )
- {
- //It was the duplicate entry.
- continue;
- }
- else
- {
- //I hate to admit it, but we don't know what happened here. Throw the Exception.
- throw ex;
- }
- }
- InputStream in = zipf.getInputStream( inputEntry );
- int len = buffer.length;
- int count = -1;
- while( ( count = in.read( buffer, 0, len ) ) > 0 )
- {
- output.write( buffer, 0, count );
- }
- in.close();
- output.closeEntry();
- }
- }
- zipf.close();
- }
-
- /*
- * A method that does the work on a given entry in a mergefile.
- * The big deal is to set the right parameters in the ZipEntry
- * on the output stream.
- */
- private ZipEntry processEntry( ZipFile zip, ZipEntry inputEntry )
- throws IOException
- {
- /*
- * First, some notes.
- * On MRJ 2.2.2, getting the size, compressed size, and CRC32 from the
- * ZipInputStream does not work for compressed (deflated) files. Those calls return -1.
- * For uncompressed (stored) files, those calls do work.
- * However, using ZipFile.getEntries() works for both compressed and
- * uncompressed files.
- * Now, from some simple testing I did, it seems that the value of CRC-32 is
- * independent of the compression setting. So, it should be easy to pass this
- * information on to the output entry.
- */
- String name = inputEntry.getName();
- if( !( inputEntry.isDirectory() || name.endsWith( ".class" ) ) )
- {
- try
- {
- InputStream input = zip.getInputStream( zip.getEntry( name ) );
- String className = ClassNameReader.getClassName( input );
- input.close();
- if( className != null )
- {
- name = className.replace( '.', '/' ) + ".class";
- }
- }
- catch( IOException ioe )
- {
- }
- }
- ZipEntry outputEntry = new ZipEntry( name );
- outputEntry.setTime( inputEntry.getTime() );
- outputEntry.setExtra( inputEntry.getExtra() );
- outputEntry.setComment( inputEntry.getComment() );
- outputEntry.setTime( inputEntry.getTime() );
- if( compression )
- {
- outputEntry.setMethod( ZipEntry.DEFLATED );
- //Note, don't need to specify size or crc for compressed files.
- }
- else
- {
- outputEntry.setMethod( ZipEntry.STORED );
- outputEntry.setCrc( inputEntry.getCrc() );
- outputEntry.setSize( inputEntry.getSize() );
- }
- return outputEntry;
- }
-
-}
-
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java
deleted file mode 100644
index 777f617bf..000000000
--- a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java
+++ /dev/null
@@ -1,116 +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.jlink;
-
-import java.io.DataInput;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Provides a quick and dirty way to determine the true name of a class given
- * just an InputStream. Reads in just enough to perform this minimal task only.
- *
- * @author RT
- */
-public class ClassNameReader extends Object
-{
-
- public static String getClassName( InputStream input )
- throws IOException
- {
- DataInputStream data = new DataInputStream( input );
- // verify this is a valid class file.
- int cookie = data.readInt();
- if( cookie != 0xCAFEBABE )
- {
- return null;
- }
- int version = data.readInt();
- // read the constant pool.
- ConstantPool constants = new ConstantPool( data );
- Object[] values = constants.values;
- // read access flags and class index.
- int accessFlags = data.readUnsignedShort();
- int classIndex = data.readUnsignedShort();
- Integer stringIndex = (Integer)values[ classIndex ];
- String className = (String)values[ stringIndex.intValue() ];
- return className;
- }
-
-}
-
-/**
- * Reads just enough of a class file to determine the class' full name.
- * <jlink compress="false" outfile="out.jar"/>
- * <mergefiles>
- * <pathelement path="${build.dir}/mergefoo.jar"/>
- * <pathelement path="${build.dir}/mergebar.jar"/>
- * </mergefiles>
- * <addfiles>
- * <pathelement path="${build.dir}/mac.jar"/>
- * <pathelement path="${build.dir}/pc.zip"/>
- * </addfiles>
- * </jlink>
- *
- * - * Extremely minimal constant pool implementation, mainly to support extracting - * strings from a class file. - * - * @author Patrick C. Beard . - */ -class ConstantPool extends Object -{ - - final static byte UTF8 = 1, UNUSED = 2, INTEGER = 3, FLOAT = 4, LONG = 5, DOUBLE = 6, - CLASS = 7, STRING = 8, FIELDREF = 9, METHODREF = 10, - INTERFACEMETHODREF = 11, NAMEANDTYPE = 12; - - byte[] types; - - Object[] values; - - ConstantPool( DataInput data ) - throws IOException - { - super(); - - int count = data.readUnsignedShort(); - types = new byte[ count ]; - values = new Object[ count ]; - // read in all constant pool entries. - for( int i = 1; i < count; i++ ) - { - byte type = data.readByte(); - types[ i ] = type; - switch( type ) - { - case UTF8: - values[ i ] = data.readUTF(); - break; - case UNUSED: - break; - case INTEGER: - values[ i ] = new Integer( data.readInt() ); - break; - case FLOAT: - values[ i ] = new Float( data.readFloat() ); - break; - case LONG: - values[ i ] = new Long( data.readLong() ); - ++i; - break; - case DOUBLE: - values[ i ] = new Double( data.readDouble() ); - ++i; - break; - case CLASS: - case STRING: - values[ i ] = new Integer( data.readUnsignedShort() ); - break; - case FIELDREF: - case METHODREF: - case INTERFACEMETHODREF: - case NAMEANDTYPE: - values[ i ] = new Integer( data.readInt() ); - break; - } - } - } - -} - diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java deleted file mode 100644 index 58b57984a..000000000 --- a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java +++ /dev/null @@ -1,210 +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.jlink; - -import java.io.File; -import org.apache.myrmidon.api.TaskException; -import org.apache.tools.ant.taskdefs.MatchingTask; -import org.apache.tools.ant.types.Path; - -/** - * This class defines objects that can link together various jar and zip files. - *
- * - * It is basically a wrapper for the jlink code written originally by Patrick Beard . The classes - * org.apache.tools.ant.taskdefs.optional.jlink.Jlink and - * org.apache.tools.ant.taskdefs.optional.jlink.ClassNameReader support this - * class.
- *
- * For example:
- *
- *
- * @author Matthew Kuperus Heun
- *
- */
-public class JlinkTask extends MatchingTask
-{
-
- private File outfile = null;
-
- private Path mergefiles = null;
-
- private Path addfiles = null;
-
- private boolean compress = false;
-
- private String ps = System.getProperty( "path.separator" );
-
- /**
- * Sets the files to be added into the output.
- *
- * @param addfiles The new Addfiles value
- */
- public void setAddfiles( Path addfiles )
- throws TaskException
- {
- if( this.addfiles == null )
- {
- this.addfiles = addfiles;
- }
- else
- {
- this.addfiles.append( addfiles );
- }
- }
-
- /**
- * Defines whether or not the output should be compacted.
- *
- * @param compress The new Compress value
- */
- public void setCompress( boolean compress )
- {
- this.compress = compress;
- }
-
- /**
- * Sets the files to be merged into the output.
- *
- * @param mergefiles The new Mergefiles value
- */
- public void setMergefiles( Path mergefiles )
- throws TaskException
- {
- if( this.mergefiles == null )
- {
- this.mergefiles = mergefiles;
- }
- else
- {
- this.mergefiles.append( mergefiles );
- }
- }
-
- /**
- * The output file for this run of jlink. Usually a jar or zip file.
- *
- * @param outfile The new Outfile value
- */
- public void setOutfile( File outfile )
- {
- this.outfile = outfile;
- }
-
- /**
- * Establishes the object that contains the files to be added to the output.
- *
- * @return Description of the Returned Value
- */
- public Path createAddfiles()
- throws TaskException
- {
- if( this.addfiles == null )
- {
- this.addfiles = new Path();
- }
- return this.addfiles.createPath();
- }
-
- /**
- * Establishes the object that contains the files to be merged into the
- * output.
- *
- * @return Description of the Returned Value
- */
- public Path createMergefiles()
- throws TaskException
- {
- if( this.mergefiles == null )
- {
- this.mergefiles = new Path();
- }
- return this.mergefiles.createPath();
- }
-
- /**
- * Does the adding and merging.
- *
- * @exception TaskException Description of Exception
- */
- public void execute()
- throws TaskException
- {
- //Be sure everything has been set.
- if( outfile == null )
- {
- throw new TaskException( "outfile attribute is required! Please set." );
- }
- if( !haveAddFiles() && !haveMergeFiles() )
- {
- throw new TaskException( "addfiles or mergefiles required! Please set." );
- }
- getLogger().info( "linking: " + outfile.getPath() );
- getLogger().debug( "compression: " + compress );
- jlink linker = new jlink();
- linker.setOutfile( outfile.getPath() );
- linker.setCompression( compress );
- if( haveMergeFiles() )
- {
- getLogger().debug( "merge files: " + mergefiles.toString() );
- linker.addMergeFiles( mergefiles.list() );
- }
- if( haveAddFiles() )
- {
- getLogger().debug( "add files: " + addfiles.toString() );
- linker.addAddFiles( addfiles.list() );
- }
- try
- {
- linker.link();
- }
- catch( Exception ex )
- {
- throw new TaskException( "Error", ex );
- }
- }
-
- private boolean haveAddFiles()
- throws TaskException
- {
- return haveEntries( addfiles );
- }
-
- private boolean haveEntries( Path p )
- throws TaskException
- {
- if( p == null )
- {
- return false;
- }
- if( p.size() > 0 )
- {
- return true;
- }
- return false;
- }
-
- private boolean haveMergeFiles()
- throws TaskException
- {
- return haveEntries( mergefiles );
- }
-}
-
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java
deleted file mode 100644
index c1b33c9bb..000000000
--- a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java
+++ /dev/null
@@ -1,469 +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.jlink;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.zip.CRC32;
-import java.util.zip.Deflater;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipOutputStream;
-
-public class jlink extends Object
-{
-
- private String outfile = null;
-
- private ArrayList mergefiles = new ArrayList( 10 );
-
- private ArrayList addfiles = new ArrayList( 10 );
-
- private boolean compression = false;
-
- byte[] buffer = new byte[ 8192 ];
-
- public static void main( String[] args )
- {
- // jlink output input1 ... inputN
- if( args.length < 2 )
- {
- System.out.println( "usage: jlink output input1 ... inputN" );
- System.exit( 1 );
- }
- jlink linker = new jlink();
- linker.setOutfile( args[ 0 ] );
- //To maintain compatibility with the command-line version, we will only add files to be merged.
- for( int i = 1; i < args.length; i++ )
- {
- linker.addMergeFile( args[ i ] );
- }
- try
- {
- linker.link();
- }
- catch( Exception ex )
- {
- System.err.print( ex.getMessage() );
- }
- }
-
- /**
- * Determines whether output will be compressed.
- *
- * @param compress The new Compression value
- */
- public void setCompression( boolean compress )
- {
- this.compression = compress;
- }
-
- /**
- * The file that will be created by this instance of jlink.
- *
- * @param outfile The new Outfile value
- */
- public void setOutfile( String outfile )
- {
- if( outfile == null )
- {
- return;
- }
- this.outfile = outfile;
- }
-
- /**
- * Adds a file to be added into the output.
- *
- * @param addfile The feature to be added to the AddFile attribute
- */
- public void addAddFile( String addfile )
- {
- if( addfile == null )
- {
- return;
- }
- addfiles.add( addfile );
- }
-
- /**
- * Adds several file to be added into the output.
- *
- * @param addfiles The feature to be added to the AddFiles attribute
- */
- public void addAddFiles( String[] addfiles )
- {
- if( addfiles == null )
- {
- return;
- }
- for( int i = 0; i < addfiles.length; i++ )
- {
- addAddFile( addfiles[ i ] );
- }
- }
-
- /**
- * Adds a file to be merged into the output.
- *
- * @param mergefile The feature to be added to the MergeFile attribute
- */
- public void addMergeFile( String mergefile )
- {
- if( mergefile == null )
- {
- return;
- }
- mergefiles.add( mergefile );
- }
-
- /**
- * Adds several files to be merged into the output.
- *
- * @param mergefiles The feature to be added to the MergeFiles attribute
- */
- public void addMergeFiles( String[] mergefiles )
- {
- if( mergefiles == null )
- {
- return;
- }
- for( int i = 0; i < mergefiles.length; i++ )
- {
- addMergeFile( mergefiles[ i ] );
- }
- }
-
- /**
- * Performs the linking of files. Addfiles are added to the output as-is.
- * For example, a jar file is added to the output as a jar file. However,
- * mergefiles are first examined for their type. If it is a jar or zip file,
- * the contents will be extracted from the mergefile and entered into the
- * output. If a zip or jar file is encountered in a subdirectory it will be
- * added, not merged. If a directory is encountered, it becomes the root
- * entry of all the files below it. Thus, you can provide multiple, disjoint
- * directories, as addfiles: they will all be added in a rational manner to
- * outfile.
- *
- * @exception Exception Description of Exception
- */
- public void link()
- throws Exception
- {
- ZipOutputStream output = new ZipOutputStream( new FileOutputStream( outfile ) );
- if( compression )
- {
- output.setMethod( ZipOutputStream.DEFLATED );
- output.setLevel( Deflater.DEFAULT_COMPRESSION );
- }
- else
- {
- output.setMethod( ZipOutputStream.STORED );
- }
- Iterator merges = mergefiles.iterator();
- while( merges.hasNext() )
- {
- String path = (String)merges.next();
- File f = new File( path );
- if( f.getName().endsWith( ".jar" ) || f.getName().endsWith( ".zip" ) )
- {
- //Do the merge
- mergeZipJarContents( output, f );
- }
- else
- {
- //Add this file to the addfiles ArrayList and add it
- //later at the top level of the output file.
- addAddFile( path );
- }
- }
- Iterator adds = addfiles.iterator();
- while( adds.hasNext() )
- {
- String name = (String)adds.next();
- File f = new File( name );
- if( f.isDirectory() )
- {
- //System.out.println("in jlink: adding directory contents of " + f.getPath());
- addDirContents( output, f, f.getName() + '/', compression );
- }
- else
- {
- addFile( output, f, "", compression );
- }
- }
- if( output != null )
- {
- try
- {
- output.close();
- }
- catch( IOException ioe )
- {
- }
- }
- }
-
- /*
- * Gets the name of an entry in the file. This is the real name
- * which for a class is the name of the package with the class
- * name appended.
- */
- private String getEntryName( File file, String prefix )
- {
- String name = file.getName();
- if( !name.endsWith( ".class" ) )
- {
- // see if the file is in fact a .class file, and determine its actual name.
- try
- {
- InputStream input = new FileInputStream( file );
- String className = ClassNameReader.getClassName( input );
- input.close();
- if( className != null )
- {
- return className.replace( '.', '/' ) + ".class";
- }
- }
- catch( IOException ioe )
- {
- }
- }
- System.out.println( "From " + file.getPath() + " and prefix " + prefix + ", creating entry " + prefix + name );
- return ( prefix + name );
- }
-
- /*
- * Adds contents of a directory to the output.
- */
- private void addDirContents( ZipOutputStream output, File dir, String prefix, boolean compress )
- throws IOException
- {
- String[] contents = dir.list();
- for( int i = 0; i < contents.length; ++i )
- {
- String name = contents[ i ];
- File file = new File( dir, name );
- if( file.isDirectory() )
- {
- addDirContents( output, file, prefix + name + '/', compress );
- }
- else
- {
- addFile( output, file, prefix, compress );
- }
- }
- }
-
- /*
- * Adds a file to the output stream.
- */
- private void addFile( ZipOutputStream output, File file, String prefix, boolean compress )
- throws IOException
- {
- //Make sure file exists
- long checksum = 0;
- if( !file.exists() )
- {
- return;
- }
- ZipEntry entry = new ZipEntry( getEntryName( file, prefix ) );
- entry.setTime( file.lastModified() );
- entry.setSize( file.length() );
- if( !compress )
- {
- entry.setCrc( calcChecksum( file ) );
- }
- FileInputStream input = new FileInputStream( file );
- addToOutputStream( output, input, entry );
- }
-
- /*
- * A convenience method that several other methods might call.
- */
- private void addToOutputStream( ZipOutputStream output, InputStream input, ZipEntry ze )
- throws IOException
- {
- try
- {
- output.putNextEntry( ze );
- }
- catch( ZipException zipEx )
- {
- //This entry already exists. So, go with the first one.
- input.close();
- return;
- }
- int numBytes = -1;
- while( ( numBytes = input.read( buffer ) ) > 0 )
- {
- output.write( buffer, 0, numBytes );
- }
- output.closeEntry();
- input.close();
- }
-
- /*
- * Necessary in the case where you add a entry that
- * is not compressed.
- */
- private long calcChecksum( File f )
- throws IOException
- {
- BufferedInputStream in = new BufferedInputStream( new FileInputStream( f ) );
- return calcChecksum( in, f.length() );
- }
-
- /*
- * Necessary in the case where you add a entry that
- * is not compressed.
- */
- private long calcChecksum( InputStream in, long size )
- throws IOException
- {
- CRC32 crc = new CRC32();
- int len = buffer.length;
- int count = -1;
- int haveRead = 0;
- while( ( count = in.read( buffer, 0, len ) ) > 0 )
- {
- haveRead += count;
- crc.update( buffer, 0, count );
- }
- in.close();
- return crc.getValue();
- }
-
- /*
- * Actually performs the merging of f into the output.
- * f should be a zip or jar file.
- */
- private void mergeZipJarContents( ZipOutputStream output, File f )
- throws IOException
- {
- //Check to see that the file with name "name" exists.
- if( !f.exists() )
- {
- return;
- }
- ZipFile zipf = new ZipFile( f );
- Enumeration entries = zipf.entries();
- while( entries.hasMoreElements() )
- {
- ZipEntry inputEntry = (ZipEntry)entries.nextElement();
- //Ignore manifest entries. They're bound to cause conflicts between
- //files that are being merged. User should supply their own
- //manifest file when doing the merge.
- String inputEntryName = inputEntry.getName();
- int index = inputEntryName.indexOf( "META-INF" );
- if( index < 0 )
- {
- //META-INF not found in the name of the entry. Go ahead and process it.
- try
- {
- output.putNextEntry( processEntry( zipf, inputEntry ) );
- }
- catch( ZipException ex )
- {
- //If we get here, it could be because we are trying to put a
- //directory entry that already exists.
- //For example, we're trying to write "com", but a previous
- //entry from another mergefile was called "com".
- //In that case, just ignore the error and go on to the
- //next entry.
- String mess = ex.getMessage();
- if( mess.indexOf( "duplicate" ) >= 0 )
- {
- //It was the duplicate entry.
- continue;
- }
- else
- {
- //I hate to admit it, but we don't know what happened here. Throw the Exception.
- throw ex;
- }
- }
- InputStream in = zipf.getInputStream( inputEntry );
- int len = buffer.length;
- int count = -1;
- while( ( count = in.read( buffer, 0, len ) ) > 0 )
- {
- output.write( buffer, 0, count );
- }
- in.close();
- output.closeEntry();
- }
- }
- zipf.close();
- }
-
- /*
- * A method that does the work on a given entry in a mergefile.
- * The big deal is to set the right parameters in the ZipEntry
- * on the output stream.
- */
- private ZipEntry processEntry( ZipFile zip, ZipEntry inputEntry )
- throws IOException
- {
- /*
- * First, some notes.
- * On MRJ 2.2.2, getting the size, compressed size, and CRC32 from the
- * ZipInputStream does not work for compressed (deflated) files. Those calls return -1.
- * For uncompressed (stored) files, those calls do work.
- * However, using ZipFile.getEntries() works for both compressed and
- * uncompressed files.
- * Now, from some simple testing I did, it seems that the value of CRC-32 is
- * independent of the compression setting. So, it should be easy to pass this
- * information on to the output entry.
- */
- String name = inputEntry.getName();
- if( !( inputEntry.isDirectory() || name.endsWith( ".class" ) ) )
- {
- try
- {
- InputStream input = zip.getInputStream( zip.getEntry( name ) );
- String className = ClassNameReader.getClassName( input );
- input.close();
- if( className != null )
- {
- name = className.replace( '.', '/' ) + ".class";
- }
- }
- catch( IOException ioe )
- {
- }
- }
- ZipEntry outputEntry = new ZipEntry( name );
- outputEntry.setTime( inputEntry.getTime() );
- outputEntry.setExtra( inputEntry.getExtra() );
- outputEntry.setComment( inputEntry.getComment() );
- outputEntry.setTime( inputEntry.getTime() );
- if( compression )
- {
- outputEntry.setMethod( ZipEntry.DEFLATED );
- //Note, don't need to specify size or crc for compressed files.
- }
- else
- {
- outputEntry.setMethod( ZipEntry.STORED );
- outputEntry.setCrc( inputEntry.getCrc() );
- outputEntry.setSize( inputEntry.getSize() );
- }
- return outputEntry;
- }
-
-}
-
- * <jlink compress="false" outfile="out.jar"/>
- * <mergefiles>
- * <pathelement path="${build.dir}/mergefoo.jar"/>
- * <pathelement path="${build.dir}/mergebar.jar"/>
- * </mergefiles>
- * <addfiles>
- * <pathelement path="${build.dir}/mac.jar"/>
- * <pathelement path="${build.dir}/pc.zip"/>
- * </addfiles>
- * </jlink>
- *