Browse Source

Zap the zip files which are no w in a separate library

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271954 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 23 years ago
parent
commit
0af1e9e5da
24 changed files with 6 additions and 3274 deletions
  1. BIN
      proposal/myrmidon/lib/excalibur-zip-1.0.jar
  2. +0
    -362
      proposal/myrmidon/src/java/org/apache/aut/zip/AsiExtraField.java
  3. +0
    -194
      proposal/myrmidon/src/java/org/apache/aut/zip/ExtraFieldUtils.java
  4. +0
    -66
      proposal/myrmidon/src/java/org/apache/aut/zip/UnixStat.java
  5. +0
    -99
      proposal/myrmidon/src/java/org/apache/aut/zip/UnrecognizedExtraField.java
  6. +0
    -435
      proposal/myrmidon/src/java/org/apache/aut/zip/ZipEntry.java
  7. +0
    -81
      proposal/myrmidon/src/java/org/apache/aut/zip/ZipExtraField.java
  8. +0
    -113
      proposal/myrmidon/src/java/org/apache/aut/zip/ZipLong.java
  9. +0
    -715
      proposal/myrmidon/src/java/org/apache/aut/zip/ZipOutputStream.java
  10. +0
    -109
      proposal/myrmidon/src/java/org/apache/aut/zip/ZipShort.java
  11. +0
    -167
      proposal/myrmidon/src/test/org/apache/aut/zip/test/AsiExtraFieldTestCase.java
  12. +0
    -120
      proposal/myrmidon/src/test/org/apache/aut/zip/test/ExtraFieldUtilsTestCase.java
  13. +0
    -99
      proposal/myrmidon/src/test/org/apache/aut/zip/test/ZipEntryTestCase.java
  14. +0
    -80
      proposal/myrmidon/src/test/org/apache/aut/zip/test/ZipLongTestCase.java
  15. +0
    -76
      proposal/myrmidon/src/test/org/apache/aut/zip/test/ZipShortTestCase.java
  16. +0
    -167
      proposal/myrmidon/src/testcases/org/apache/aut/zip/test/AsiExtraFieldTestCase.java
  17. +0
    -120
      proposal/myrmidon/src/testcases/org/apache/aut/zip/test/ExtraFieldUtilsTestCase.java
  18. +0
    -99
      proposal/myrmidon/src/testcases/org/apache/aut/zip/test/ZipEntryTestCase.java
  19. +0
    -80
      proposal/myrmidon/src/testcases/org/apache/aut/zip/test/ZipLongTestCase.java
  20. +0
    -76
      proposal/myrmidon/src/testcases/org/apache/aut/zip/test/ZipShortTestCase.java
  21. +1
    -3
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Ear.java
  22. +1
    -3
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Jar.java
  23. +1
    -4
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/War.java
  24. +3
    -6
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Zip.java

BIN
proposal/myrmidon/lib/excalibur-zip-1.0.jar View File


+ 0
- 362
proposal/myrmidon/src/java/org/apache/aut/zip/AsiExtraField.java View File

@@ -1,362 +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.aut.zip;

import java.util.zip.CRC32;
import java.util.zip.ZipException;

/**
* Adds Unix file permission and UID/GID fields as well as symbolic link
* handling. <p>
*
* This class uses the ASi extra field in the format: <pre>
* Value Size Description
* ----- ---- -----------
* (Unix3) 0x756e Short tag for this extra block type
* TSize Short total data size for this block
* CRC Long CRC-32 of the remaining data
* Mode Short file permissions
* SizDev Long symlink'd size OR major/minor dev num
* UID Short user ID
* GID Short group ID
* (var.) variable symbolic link filename
* </pre> taken from appnote.iz (Info-ZIP note, 981119) found at <a
* href="ftp://ftp.uu.net/pub/archiving/zip/doc/">
* ftp://ftp.uu.net/pub/archiving/zip/doc/</a> </p> <p>
*
* Short is two bytes and Long is four bytes in big endian byte and word order,
* device numbers are currently not supported.</p>
*
* @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$
*/
public class AsiExtraField implements ZipExtraField, UnixStat, Cloneable
{

private final static ZipShort HEADER_ID = new ZipShort( 0x756E );

/**
* Standard Unix stat(2) file mode.
*
* @since 1.1
*/
private int mode = 0;
/**
* User ID.
*
* @since 1.1
*/
private int uid = 0;
/**
* Group ID.
*
* @since 1.1
*/
private int gid = 0;
/**
* File this entry points to, if it is a symbolic link. <p>
*
* empty string - if entry is not a symbolic link.</p>
*
* @since 1.1
*/
private String link = "";
/**
* Is this an entry for a directory?
*
* @since 1.1
*/
private boolean dirFlag = false;

/**
* Instance used to calculate checksums.
*
* @since 1.1
*/
private CRC32 crc = new CRC32();

public AsiExtraField()
{
}

/**
* Indicate whether this entry is a directory.
*
* @param dirFlag The new Directory value
* @since 1.1
*/
public void setDirectory( boolean dirFlag )
{
this.dirFlag = dirFlag;
mode = getMode( mode );
}

/**
* Set the group id.
*
* @param gid The new GroupId value
* @since 1.1
*/
public void setGroupId( int gid )
{
this.gid = gid;
}

/**
* Indicate that this entry is a symbolic link to the given filename.
*
* @param name Name of the file this entry links to, empty String if it is
* not a symbolic link.
* @since 1.1
*/
public void setLinkedFile( String name )
{
link = name;
mode = getMode( mode );
}

/**
* File mode of this file.
*
* @param mode The new Mode value
* @since 1.1
*/
public void setMode( int mode )
{
this.mode = getMode( mode );
}

/**
* Set the user id.
*
* @param uid The new UserId value
* @since 1.1
*/
public void setUserId( int uid )
{
this.uid = uid;
}

/**
* Delegate to local file data.
*
* @return The CentralDirectoryData value
* @since 1.1
*/
public byte[] getCentralDirectoryData()
{
return getLocalFileDataData();
}

/**
* Delegate to local file data.
*
* @return The CentralDirectoryLength value
* @since 1.1
*/
public ZipShort getCentralDirectoryLength()
{
return getLocalFileDataLength();
}

/**
* Get the group id.
*
* @return The GroupId value
* @since 1.1
*/
public int getGroupId()
{
return gid;
}

/**
* The Header-ID.
*
* @return The HeaderId value
* @since 1.1
*/
public ZipShort getHeaderId()
{
return HEADER_ID;
}

/**
* Name of linked file
*
* @return name of the file this entry links to if it is a symbolic link,
* the empty string otherwise.
* @since 1.1
*/
public String getLinkedFile()
{
return link;
}

/**
* The actual data to put into local file data - without Header-ID or length
* specifier.
*
* @return The LocalFileDataData value
* @since 1.1
*/
public byte[] getLocalFileDataData()
{
// CRC will be added later
byte[] data = new byte[ getLocalFileDataLength().getValue() - 4 ];
System.arraycopy( ( new ZipShort( getMode() ) ).getBytes(), 0, data, 0, 2 );

byte[] linkArray = getLinkedFile().getBytes();
System.arraycopy( ( new ZipLong( linkArray.length ) ).getBytes(),
0, data, 2, 4 );

System.arraycopy( ( new ZipShort( getUserId() ) ).getBytes(),
0, data, 6, 2 );
System.arraycopy( ( new ZipShort( getGroupId() ) ).getBytes(),
0, data, 8, 2 );

System.arraycopy( linkArray, 0, data, 10, linkArray.length );

crc.reset();
crc.update( data );
long checksum = crc.getValue();

byte[] result = new byte[ data.length + 4 ];
System.arraycopy( ( new ZipLong( checksum ) ).getBytes(), 0, result, 0, 4 );
System.arraycopy( data, 0, result, 4, data.length );
return result;
}

/**
* Length of the extra field in the local file data - without Header-ID or
* length specifier.
*
* @return The LocalFileDataLength value
* @since 1.1
*/
public ZipShort getLocalFileDataLength()
{
return new ZipShort( 4// CRC
+ 2// Mode
+ 4// SizDev
+ 2// UID
+ 2// GID
+ getLinkedFile().getBytes().length );
}

/**
* File mode of this file.
*
* @return The Mode value
* @since 1.1
*/
public int getMode()
{
return mode;
}

/**
* Get the user id.
*
* @return The UserId value
* @since 1.1
*/
public int getUserId()
{
return uid;
}

/**
* Is this entry a directory?
*
* @return The Directory value
* @since 1.1
*/
public boolean isDirectory()
{
return dirFlag && !isLink();
}

/**
* Is this entry a symbolic link?
*
* @return The Link value
* @since 1.1
*/
public boolean isLink()
{
return getLinkedFile().length() != 0;
}

/**
* Populate data from this array as if it was in local file data.
*
* @param data Description of Parameter
* @param offset Description of Parameter
* @param length Description of Parameter
* @exception ZipException Description of Exception
* @since 1.1
*/
public void parseFromLocalFileData( byte[] data, int offset, int length )
throws ZipException
{

long givenChecksum = ( new ZipLong( data, offset ) ).getValue();
byte[] tmp = new byte[ length - 4 ];
System.arraycopy( data, offset + 4, tmp, 0, length - 4 );
crc.reset();
crc.update( tmp );
long realChecksum = crc.getValue();
if( givenChecksum != realChecksum )
{
throw new ZipException( "bad CRC checksum "
+ Long.toHexString( givenChecksum )
+ " instead of "
+ Long.toHexString( realChecksum ) );
}

int newMode = ( new ZipShort( tmp, 0 ) ).getValue();
byte[] linkArray = new byte[ (int)( new ZipLong( tmp, 2 ) ).getValue() ];
uid = ( new ZipShort( tmp, 6 ) ).getValue();
gid = ( new ZipShort( tmp, 8 ) ).getValue();

if( linkArray.length == 0 )
{
link = "";
}
else
{
System.arraycopy( tmp, 10, linkArray, 0, linkArray.length );
link = new String( linkArray );
}
setDirectory( ( newMode & DIR_FLAG ) != 0 );
setMode( newMode );
}

/**
* Get the file mode for given permissions with the correct file type.
*
* @param mode Description of Parameter
* @return The Mode value
* @since 1.1
*/
protected int getMode( int mode )
{
int type = FILE_FLAG;
if( isLink() )
{
type = LINK_FLAG;
}
else if( isDirectory() )
{
type = DIR_FLAG;
}
return type | ( mode & PERM_MASK );
}

}

+ 0
- 194
proposal/myrmidon/src/java/org/apache/aut/zip/ExtraFieldUtils.java View File

@@ -1,194 +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.aut.zip;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.zip.ZipException;

/**
* ZipExtraField related methods
*
* @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$
*/
public class ExtraFieldUtils
{

/**
* Static registry of known extra fields.
*
* @since 1.1
*/
private static Hashtable implementations;

static
{
implementations = new Hashtable();
register( AsiExtraField.class );
}

/**
* Create an instance of the approriate ExtraField, falls back to {@link
* UnrecognizedExtraField UnrecognizedExtraField}.
*
* @param headerId Description of Parameter
* @return Description of the Returned Value
* @exception InstantiationException Description of Exception
* @exception IllegalAccessException Description of Exception
* @since 1.1
*/
public static ZipExtraField createExtraField( ZipShort headerId )
throws InstantiationException, IllegalAccessException
{
Class c = (Class)implementations.get( headerId );
if( c != null )
{
return (ZipExtraField)c.newInstance();
}
UnrecognizedExtraField u = new UnrecognizedExtraField();
u.setHeaderId( headerId );
return u;
}

/**
* Merges the central directory fields of the given ZipExtraFields.
*
* @param data Description of Parameter
* @return Description of the Returned Value
* @since 1.1
*/
public static byte[] mergeCentralDirectoryData( ZipExtraField[] data )
{
int sum = 4 * data.length;
for( int i = 0; i < data.length; i++ )
{
sum += data[ i ].getCentralDirectoryLength().getValue();
}
byte[] result = new byte[ sum ];
int start = 0;
for( int i = 0; i < data.length; i++ )
{
System.arraycopy( data[ i ].getHeaderId().getBytes(),
0, result, start, 2 );
System.arraycopy( data[ i ].getCentralDirectoryLength().getBytes(),
0, result, start + 2, 2 );
byte[] local = data[ i ].getCentralDirectoryData();
System.arraycopy( local, 0, result, start + 4, local.length );
start += ( local.length + 4 );
}
return result;
}

/**
* Merges the local file data fields of the given ZipExtraFields.
*
* @param data Description of Parameter
* @return Description of the Returned Value
* @since 1.1
*/
public static byte[] mergeLocalFileDataData( ZipExtraField[] data )
{
int sum = 4 * data.length;
for( int i = 0; i < data.length; i++ )
{
sum += data[ i ].getLocalFileDataLength().getValue();
}
byte[] result = new byte[ sum ];
int start = 0;
for( int i = 0; i < data.length; i++ )
{
System.arraycopy( data[ i ].getHeaderId().getBytes(),
0, result, start, 2 );
System.arraycopy( data[ i ].getLocalFileDataLength().getBytes(),
0, result, start + 2, 2 );
byte[] local = data[ i ].getLocalFileDataData();
System.arraycopy( local, 0, result, start + 4, local.length );
start += ( local.length + 4 );
}
return result;
}

/**
* Split the array into ExtraFields and populate them with the give data.
*
* @param data Description of Parameter
* @return Description of the Returned Value
* @exception ZipException Description of Exception
* @since 1.1
*/
public static ZipExtraField[] parse( byte[] data )
throws ZipException
{
ArrayList v = new ArrayList();
int start = 0;
while( start <= data.length - 4 )
{
ZipShort headerId = new ZipShort( data, start );
int length = ( new ZipShort( data, start + 2 ) ).getValue();
if( start + 4 + length > data.length )
{
throw new ZipException( "data starting at " + start + " is in unknown format" );
}
try
{
ZipExtraField ze = createExtraField( headerId );
ze.parseFromLocalFileData( data, start + 4, length );
v.add( ze );
}
catch( InstantiationException ie )
{
throw new ZipException( ie.getMessage() );
}
catch( IllegalAccessException iae )
{
throw new ZipException( iae.getMessage() );
}
start += ( length + 4 );
}
if( start != data.length )
{// array not exhausted
throw new ZipException( "data starting at " + start + " is in unknown format" );
}

final ZipExtraField[] result = new ZipExtraField[ v.size() ];
return (ZipExtraField[])v.toArray( result );
}

/**
* Register a ZipExtraField implementation. <p>
*
* The given class must have a no-arg constructor and implement the {@link
* ZipExtraField ZipExtraField interface}.</p>
*
* @param c Description of Parameter
* @since 1.1
*/
public static void register( Class c )
{
try
{
ZipExtraField ze = (ZipExtraField)c.newInstance();
implementations.put( ze.getHeaderId(), c );
}
catch( ClassCastException cc )
{
throw new RuntimeException( c +
" doesn\'t implement ZipExtraField" );
}
catch( InstantiationException ie )
{
throw new RuntimeException( c + " is not a concrete class" );
}
catch( IllegalAccessException ie )
{
throw new RuntimeException( c +
"\'s no-arg constructor is not public" );
}
}
}

+ 0
- 66
proposal/myrmidon/src/java/org/apache/aut/zip/UnixStat.java View File

@@ -1,66 +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.aut.zip;

/**
* Constants from stat.h on Unix systems.
*
* @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$
*/
public interface UnixStat
{
/**
* Bits used for permissions (and sticky bit)
*
* @since 1.1
*/
int PERM_MASK = 07777;
/**
* Indicates symbolic links.
*
* @since 1.1
*/
int LINK_FLAG = 0120000;
/**
* Indicates plain files.
*
* @since 1.1
*/
int FILE_FLAG = 0100000;
/**
* Indicates directories.
*
* @since 1.1
*/
int DIR_FLAG = 040000;

// ----------------------------------------------------------
// somewhat arbitrary choices that are quite common for shared
// installations
// -----------------------------------------------------------

/**
* Default permissions for symbolic links.
*
* @since 1.1
*/
int DEFAULT_LINK_PERM = 0777;
/**
* Default permissions for directories.
*
* @since 1.1
*/
int DEFAULT_DIR_PERM = 0755;
/**
* Default permissions for plain files.
*
* @since 1.1
*/
int DEFAULT_FILE_PERM = 0644;
}

+ 0
- 99
proposal/myrmidon/src/java/org/apache/aut/zip/UnrecognizedExtraField.java View File

@@ -1,99 +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.aut.zip;

/**
* Simple placeholder for all those extra fields we don't want to deal with. <p>
*
* Assumes local file data and central directory entries are identical - unless
* told the opposite.</p>
*
* @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$
*/
public class UnrecognizedExtraField
implements ZipExtraField
{
/**
* Extra field data in central directory - without Header-ID or length
* specifier.
*
* @since 1.1
*/
private byte[] centralData;

/**
* The Header-ID.
*
* @since 1.1
*/
private ZipShort headerId;

/**
* Extra field data in local file data - without Header-ID or length
* specifier.
*
* @since 1.1
*/
private byte[] localData;

public void setCentralDirectoryData( byte[] data )
{
centralData = data;
}

public void setHeaderId( ZipShort headerId )
{
this.headerId = headerId;
}

public void setLocalFileDataData( byte[] data )
{
localData = data;
}

public byte[] getCentralDirectoryData()
{
if( centralData != null )
{
return centralData;
}
return getLocalFileDataData();
}

public ZipShort getCentralDirectoryLength()
{
if( centralData != null )
{
return new ZipShort( centralData.length );
}
return getLocalFileDataLength();
}

public ZipShort getHeaderId()
{
return headerId;
}

public byte[] getLocalFileDataData()
{
return localData;
}

public ZipShort getLocalFileDataLength()
{
return new ZipShort( localData.length );
}

public void parseFromLocalFileData( byte[] data, int offset, int length )
{
byte[] tmp = new byte[ length ];
System.arraycopy( data, offset, tmp, 0, length );
setLocalFileDataData( tmp );
}
}

+ 0
- 435
proposal/myrmidon/src/java/org/apache/aut/zip/ZipEntry.java View File

@@ -1,435 +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.aut.zip;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.zip.ZipException;

/**
* Extension that adds better handling of extra fields and provides access to
* the internal and external file attributes.
*
* @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$
*/
public class ZipEntry
extends java.util.zip.ZipEntry
{
/**
* Helper for JDK 1.1
*
* @since 1.2
*/
private static Method setCompressedSizeMethod = null;
/**
* Helper for JDK 1.1
*
* @since 1.2
*/
private static Object lockReflection = new Object();
/**
* Helper for JDK 1.1
*
* @since 1.2
*/
private static boolean triedToGetMethod = false;

private int internalAttributes = 0;
private long externalAttributes = 0;
private ArrayList extraFields = new ArrayList();

/**
* Helper for JDK 1.1 <-> 1.2 incompatibility.
*
* @since 1.2
*/
private Long compressedSize = null;

/**
* Creates a new zip entry with the specified name.
*
* @param name Description of Parameter
* @since 1.1
*/
public ZipEntry( String name )
{
super( name );
}

/**
* Creates a new zip entry with fields taken from the specified zip entry.
*
* @param entry Description of Parameter
* @exception ZipException Description of Exception
* @since 1.1
*/
public ZipEntry( java.util.zip.ZipEntry entry )
throws ZipException
{
/*
* REVISIT: call super(entry) instead of this stuff in Ant2,
* "copy constructor" has not been available in JDK 1.1
*/
super( entry.getName() );

setComment( entry.getComment() );
setMethod( entry.getMethod() );
setTime( entry.getTime() );

long size = entry.getSize();
if( size > 0 )
{
setSize( size );
}
long cSize = entry.getCompressedSize();
if( cSize > 0 )
{
setComprSize( cSize );
}
long crc = entry.getCrc();
if( crc > 0 )
{
setCrc( crc );
}

byte[] extra = entry.getExtra();
if( extra != null )
{
setExtraFields( ExtraFieldUtils.parse( extra ) );
}
else
{
// initializes extra data to an empty byte array
setExtra();
}
}

/**
* Creates a new zip entry with fields taken from the specified zip entry.
*
* @param entry Description of Parameter
* @exception ZipException Description of Exception
* @since 1.1
*/
public ZipEntry( ZipEntry entry )
throws ZipException
{
this( (java.util.zip.ZipEntry)entry );
setInternalAttributes( entry.getInternalAttributes() );
setExternalAttributes( entry.getExternalAttributes() );
setExtraFields( entry.getExtraFields() );
}

/**
* Try to get a handle to the setCompressedSize method.
*
* @since 1.2
*/
private static void checkSCS()
{
if( !triedToGetMethod )
{
synchronized( lockReflection )
{
triedToGetMethod = true;
try
{
setCompressedSizeMethod =
java.util.zip.ZipEntry.class.getMethod( "setCompressedSize",
new Class[]{Long.TYPE} );
}
catch( NoSuchMethodException nse )
{
}
}
}
}

/**
* Are we running JDK 1.2 or higher?
*
* @return Description of the Returned Value
* @since 1.2
*/
private static boolean haveSetCompressedSize()
{
checkSCS();
return setCompressedSizeMethod != null;
}

/**
* Invoke setCompressedSize via reflection.
*
* @param ze Description of Parameter
* @param size Description of Parameter
* @since 1.2
*/
private static void performSetCompressedSize( ZipEntry ze, long size )
{
Long[] s = {new Long( size )};
try
{
setCompressedSizeMethod.invoke( ze, s );
}
catch( InvocationTargetException ite )
{
Throwable nested = ite.getTargetException();
throw new RuntimeException( "Exception setting the compressed size "
+ "of " + ze + ": "
+ nested.getMessage() );
}
catch( Throwable other )
{
throw new RuntimeException( "Exception setting the compressed size "
+ "of " + ze + ": "
+ other.getMessage() );
}
}

/**
* Make this class work in JDK 1.1 like a 1.2 class. <p>
*
* This either stores the size for later usage or invokes setCompressedSize
* via reflection.</p>
*
* @param size The new ComprSize value
* @since 1.2
*/
public void setComprSize( long size )
{
if( haveSetCompressedSize() )
{
performSetCompressedSize( this, size );
}
else
{
compressedSize = new Long( size );
}
}

/**
* Sets the external file attributes.
*
* @param value The new ExternalAttributes value
* @since 1.1
*/
public void setExternalAttributes( long value )
{
externalAttributes = value;
}

/**
* Throws an Exception if extra data cannot be parsed into extra fields.
*
* @param extra The new Extra value
* @exception RuntimeException Description of Exception
* @since 1.1
*/
public void setExtra( byte[] extra )
throws RuntimeException
{
try
{
setExtraFields( ExtraFieldUtils.parse( extra ) );
}
catch( Exception e )
{
throw new RuntimeException( e.getMessage() );
}
}

/**
* Replaces all currently attached extra fields with the new array.
*
* @param fields The new ExtraFields value
* @since 1.1
*/
public void setExtraFields( ZipExtraField[] fields )
{
extraFields.clear();
for( int i = 0; i < fields.length; i++ )
{
extraFields.add( fields[ i ] );
}
setExtra();
}

/**
* Sets the internal file attributes.
*
* @param value The new InternalAttributes value
* @since 1.1
*/
public void setInternalAttributes( int value )
{
internalAttributes = value;
}

/**
* Retrieves the extra data for the central directory.
*
* @return The CentralDirectoryExtra value
* @since 1.1
*/
public byte[] getCentralDirectoryExtra()
{
return ExtraFieldUtils.mergeCentralDirectoryData( getExtraFields() );
}

/**
* Override to make this class work in JDK 1.1 like a 1.2 class.
*
* @return The CompressedSize value
* @since 1.2
*/
public long getCompressedSize()
{
if( compressedSize != null )
{
// has been set explicitly and we are running in a 1.1 VM
return compressedSize.longValue();
}
return super.getCompressedSize();
}

/**
* Retrieves the external file attributes.
*
* @return The ExternalAttributes value
* @since 1.1
*/
public long getExternalAttributes()
{
return externalAttributes;
}

/**
* Retrieves extra fields.
*
* @return The ExtraFields value
* @since 1.1
*/
public ZipExtraField[] getExtraFields()
{
final ZipExtraField[] result = new ZipExtraField[ extraFields.size() ];
return (ZipExtraField[])extraFields.toArray( result );
}

/**
* Retrieves the internal file attributes.
*
* @return The InternalAttributes value
* @since 1.1
*/
public int getInternalAttributes()
{
return internalAttributes;
}

/**
* Retrieves the extra data for the local file data.
*
* @return The LocalFileDataExtra value
* @since 1.1
*/
public byte[] getLocalFileDataExtra()
{
byte[] extra = getExtra();
return extra != null ? extra : new byte[ 0 ];
}

/**
* Adds an extra fields - replacing an already present extra field of the
* same type.
*
* @param ze The feature to be added to the ExtraField attribute
* @since 1.1
*/
public void addExtraField( ZipExtraField ze )
{
ZipShort type = ze.getHeaderId();
boolean done = false;
for( int i = 0; !done && i < extraFields.size(); i++ )
{
if( ( (ZipExtraField)extraFields.get( i ) ).getHeaderId().equals( type ) )
{
extraFields.set( i, ze );
done = true;
}
}
if( !done )
{
extraFields.add( ze );
}
setExtra();
}

/**
* Overwrite clone
*
* @return Description of the Returned Value
* @since 1.1
*/
public Object clone()
{
ZipEntry e = null;
try
{
e = new ZipEntry( (java.util.zip.ZipEntry)super.clone() );
}
catch( Exception ex )
{
// impossible as extra data is in correct format
ex.printStackTrace();
}
e.setInternalAttributes( getInternalAttributes() );
e.setExternalAttributes( getExternalAttributes() );
e.setExtraFields( getExtraFields() );
return e;
}

/**
* Remove an extra fields.
*
* @param type Description of Parameter
* @since 1.1
*/
public void removeExtraField( ZipShort type )
{
boolean done = false;
for( int i = 0; !done && i < extraFields.size(); i++ )
{
if( ( (ZipExtraField)extraFields.get( i ) ).getHeaderId().equals( type ) )
{
extraFields.remove( i );
done = true;
}
}
if( !done )
{
throw new java.util.NoSuchElementException();
}
setExtra();
}

/**
* Unfortunately {@link java.util.zip.ZipOutputStream
* java.util.zip.ZipOutputStream} seems to access the extra data directly,
* so overriding getExtra doesn't help - we need to modify super's data
* directly.
*
* @since 1.1
*/
protected void setExtra()
{
super.setExtra( ExtraFieldUtils.mergeLocalFileDataData( getExtraFields() ) );
}

}

+ 0
- 81
proposal/myrmidon/src/java/org/apache/aut/zip/ZipExtraField.java View File

@@ -1,81 +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.aut.zip;

import java.util.zip.ZipException;

/**
* General format of extra field data. <p>
*
* Extra fields usually appear twice per file, once in the local file data and
* once in the central directory. Usually they are the same, but they don't have
* to be. {@link java.util.zip.ZipOutputStream java.util.zip.ZipOutputStream}
* will only use the local file data in both places.</p>
*
* @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$
*/
public interface ZipExtraField
{

/**
* The Header-ID.
*
* @return The HeaderId value
* @since 1.1
*/
ZipShort getHeaderId();

/**
* Length of the extra field in the local file data - without Header-ID or
* length specifier.
*
* @return The LocalFileDataLength value
* @since 1.1
*/
ZipShort getLocalFileDataLength();

/**
* Length of the extra field in the central directory - without Header-ID or
* length specifier.
*
* @return The CentralDirectoryLength value
* @since 1.1
*/
ZipShort getCentralDirectoryLength();

/**
* The actual data to put into local file data - without Header-ID or length
* specifier.
*
* @return The LocalFileDataData value
* @since 1.1
*/
byte[] getLocalFileDataData();

/**
* The actual data to put central directory - without Header-ID or length
* specifier.
*
* @return The CentralDirectoryData value
* @since 1.1
*/
byte[] getCentralDirectoryData();

/**
* Populate data from this array as if it was in local file data.
*
* @param data Description of Parameter
* @param offset Description of Parameter
* @param length Description of Parameter
* @exception ZipException Description of Exception
* @since 1.1
*/
void parseFromLocalFileData( byte[] data, int offset, int length )
throws ZipException;
}

+ 0
- 113
proposal/myrmidon/src/java/org/apache/aut/zip/ZipLong.java View File

@@ -1,113 +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.aut.zip;

/**
* Utility class that represents a four byte integer with conversion rules for
* the big endian byte order of ZIP files.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$
*/
public class ZipLong implements Cloneable
{

private long value;

/**
* Create instance from a number.
*
* @param value Description of Parameter
* @since 1.1
*/
public ZipLong( long value )
{
this.value = value;
}

/**
* Create instance from bytes.
*
* @param bytes Description of Parameter
* @since 1.1
*/
public ZipLong( byte[] bytes )
{
this( bytes, 0 );
}

/**
* Create instance from the four bytes starting at offset.
*
* @param bytes Description of Parameter
* @param offset Description of Parameter
* @since 1.1
*/
public ZipLong( byte[] bytes, int offset )
{
value = ( bytes[ offset + 3 ] << 24 ) & 0xFF000000l;
value += ( bytes[ offset + 2 ] << 16 ) & 0xFF0000;
value += ( bytes[ offset + 1 ] << 8 ) & 0xFF00;
value += ( bytes[ offset ] & 0xFF );
}

/**
* Get value as two bytes in big endian byte order.
*
* @return The Bytes value
* @since 1.1
*/
public byte[] getBytes()
{
byte[] result = new byte[ 4 ];
result[ 0 ] = (byte)( ( value & 0xFF ) );
result[ 1 ] = (byte)( ( value & 0xFF00 ) >> 8 );
result[ 2 ] = (byte)( ( value & 0xFF0000 ) >> 16 );
result[ 3 ] = (byte)( ( value & 0xFF000000l ) >> 24 );
return result;
}

/**
* Get value as Java int.
*
* @return The Value value
* @since 1.1
*/
public long getValue()
{
return value;
}

/**
* Override to make two instances with same value equal.
*
* @param o Description of Parameter
* @return Description of the Returned Value
* @since 1.1
*/
public boolean equals( Object o )
{
if( o == null || !( o instanceof ZipLong ) )
{
return false;
}
return value == ( (ZipLong)o ).getValue();
}

/**
* Override to make two instances with same value equal.
*
* @return Description of the Returned Value
* @since 1.1
*/
public int hashCode()
{
return (int)value;
}

}// ZipLong

+ 0
- 715
proposal/myrmidon/src/java/org/apache/aut/zip/ZipOutputStream.java View File

@@ -1,715 +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.aut.zip;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.zip.CRC32;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.ZipException;

/**
* Reimplementation of {@link java.util.zip.ZipOutputStream
* java.util.zip.ZipOutputStream} that does handle the extended functionality of
* this package, especially internal/external file attributes and extra fields
* with different layouts for local file data and central directory entries. <p>
*
* This implementation will use a Data Descriptor to store size and CRC
* information for DEFLATED entries, this means, you don't need to calculate
* them yourself. Unfortunately this is not possible for the STORED method, here
* setting the CRC and uncompressed size information is required before {@link
* #putNextEntry putNextEntry} will be called.</p>
*
* @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$
*/
public class ZipOutputStream
extends DeflaterOutputStream
{
/**
* Helper, a 0 as ZipShort.
*
* @since 1.1
*/
private final static byte[] ZERO = {0, 0};

/**
* Helper, a 0 as ZipLong.
*
* @since 1.1
*/
private final static byte[] LZERO = {0, 0, 0, 0};

/**
* Compression method for deflated entries.
*
* @since 1.1
*/
public final static int DEFLATED = ZipEntry.DEFLATED;

/**
* Compression method for deflated entries.
*
* @since 1.1
*/
public final static int STORED = ZipEntry.STORED;

/*
* Various ZIP constants
*/
/**
* local file header signature
*
* @since 1.1
*/
protected final static ZipLong LFH_SIG = new ZipLong( 0X04034B50L );
/**
* data descriptor signature
*
* @since 1.1
*/
protected final static ZipLong DD_SIG = new ZipLong( 0X08074B50L );
/**
* central file header signature
*
* @since 1.1
*/
protected final static ZipLong CFH_SIG = new ZipLong( 0X02014B50L );
/**
* end of central dir signature
*
* @since 1.1
*/
protected final static ZipLong EOCD_SIG = new ZipLong( 0X06054B50L );

/**
* Smallest date/time ZIP can handle.
*
* @since 1.1
*/
private final static ZipLong DOS_TIME_MIN = new ZipLong( 0x00002100L );

/**
* The file comment.
*
* @since 1.1
*/
private String comment = "";

/**
* Compression level for next entry.
*
* @since 1.1
*/
private int level = Deflater.DEFAULT_COMPRESSION;

/**
* Default compression method for next entry.
*
* @since 1.1
*/
private int method = DEFLATED;

/**
* List of ZipEntries written so far.
*
* @since 1.1
*/
private ArrayList entries = new ArrayList();

/**
* CRC instance to avoid parsing DEFLATED data twice.
*
* @since 1.1
*/
private CRC32 crc = new CRC32();

/**
* Count the bytes written to out.
*
* @since 1.1
*/
private long written = 0;

/**
* Data for current entry started here.
*
* @since 1.1
*/
private long dataStart = 0;

/**
* Start of central directory.
*
* @since 1.1
*/
private ZipLong cdOffset = new ZipLong( 0 );

/**
* Length of central directory.
*
* @since 1.1
*/
private ZipLong cdLength = new ZipLong( 0 );

/**
* Holds the offsets of the LFH starts for each entry
*
* @since 1.1
*/
private Hashtable offsets = new Hashtable();

/**
* The encoding to use for filenames and the file comment. <p>
*
* For a list of possible values see <a
* href="http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html">
* http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html
* </a>. Defaults to the platform's default character encoding.</p>
*
* @since 1.3
*/
private String encoding = null;

/**
* Current entry.
*
* @since 1.1
*/
private ZipEntry entry;

/**
* Creates a new ZIP OutputStream filtering the underlying stream.
*
* @param out Description of Parameter
* @since 1.1
*/
public ZipOutputStream( OutputStream out )
{
super( out, new Deflater( Deflater.DEFAULT_COMPRESSION, true ) );
}

/**
* Convert a Date object to a DOS date/time field. <p>
*
* Stolen from InfoZip's <code>fileio.c</code></p>
*
* @param time Description of Parameter
* @return Description of the Returned Value
* @since 1.1
*/
protected static ZipLong toDosTime( Date time )
{
int year = time.getYear() + 1900;
int month = time.getMonth() + 1;
if( year < 1980 )
{
return DOS_TIME_MIN;
}
long value = ( ( year - 1980 ) << 25 )
| ( month << 21 )
| ( time.getDate() << 16 )
| ( time.getHours() << 11 )
| ( time.getMinutes() << 5 )
| ( time.getSeconds() >> 1 );

byte[] result = new byte[ 4 ];
result[ 0 ] = (byte)( ( value & 0xFF ) );
result[ 1 ] = (byte)( ( value & 0xFF00 ) >> 8 );
result[ 2 ] = (byte)( ( value & 0xFF0000 ) >> 16 );
result[ 3 ] = (byte)( ( value & 0xFF000000l ) >> 24 );
return new ZipLong( result );
}

/**
* Set the file comment.
*
* @param comment The new Comment value
* @since 1.1
*/
public void setComment( String comment )
{
this.comment = comment;
}

/**
* The encoding to use for filenames and the file comment. <p>
*
* For a list of possible values see <a
* href="http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html">
* http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html
* </a>. Defaults to the platform's default character encoding.</p>
*
* @param encoding The new Encoding value
* @since 1.3
*/
public void setEncoding( String encoding )
{
this.encoding = encoding;
}

/**
* Sets the compression level for subsequent entries. <p>
*
* Default is Deflater.DEFAULT_COMPRESSION.</p>
*
* @param level The new Level value
* @since 1.1
*/
public void setLevel( int level )
{
this.level = level;
}

/**
* Sets the default compression method for subsequent entries. <p>
*
* Default is DEFLATED.</p>
*
* @param method The new Method value
* @since 1.1
*/
public void setMethod( int method )
{
this.method = method;
}

/**
* The encoding to use for filenames and the file comment.
*
* @return null if using the platform's default character encoding.
* @since 1.3
*/
public String getEncoding()
{
return encoding;
}

/**
* Writes all necessary data for this entry.
*
* @exception IOException Description of Exception
* @since 1.1
*/
public void closeEntry()
throws IOException
{
if( entry == null )
{
return;
}

long realCrc = crc.getValue();
crc.reset();

if( entry.getMethod() == DEFLATED )
{
def.finish();
while( !def.finished() )
{
deflate();
}

entry.setSize( def.getTotalIn() );
entry.setComprSize( def.getTotalOut() );
entry.setCrc( realCrc );

def.reset();

written += entry.getCompressedSize();
}
else
{
if( entry.getCrc() != realCrc )
{
throw new ZipException( "bad CRC checksum for entry "
+ entry.getName() + ": "
+ Long.toHexString( entry.getCrc() )
+ " instead of "
+ Long.toHexString( realCrc ) );
}

if( entry.getSize() != written - dataStart )
{
throw new ZipException( "bad size for entry "
+ entry.getName() + ": "
+ entry.getSize()
+ " instead of "
+ ( written - dataStart ) );
}

}

writeDataDescriptor( entry );
entry = null;
}

/*
* Found out by experiment, that DeflaterOutputStream.close()
* will call finish() - so we don't need to override close
* ourselves.
*/
/**
* Finishs writing the contents and closes this as well as the underlying
* stream.
*
* @exception IOException Description of Exception
* @since 1.1
*/
public void finish()
throws IOException
{
closeEntry();
cdOffset = new ZipLong( written );
final int size = entries.size();
for( int i = 0; i < size; i++ )
{
final ZipEntry entry = (ZipEntry)entries.get( i );
writeCentralFileHeader( entry );
}
cdLength = new ZipLong( written - cdOffset.getValue() );
writeCentralDirectoryEnd();
offsets.clear();
entries.clear();
}

/**
* Begin writing next entry.
*
* @param ze Description of Parameter
* @exception IOException Description of Exception
* @since 1.1
*/
public void putNextEntry( ZipEntry ze )
throws IOException
{
closeEntry();

entry = ze;
entries.add( entry );

if( entry.getMethod() == -1 )
{// not specified
entry.setMethod( method );
}

if( entry.getTime() == -1 )
{// not specified
entry.setTime( System.currentTimeMillis() );
}

if( entry.getMethod() == STORED )
{
if( entry.getSize() == -1 )
{
throw new ZipException( "uncompressed size is required for STORED method" );
}
if( entry.getCrc() == -1 )
{
throw new ZipException( "crc checksum is required for STORED method" );
}
entry.setComprSize( entry.getSize() );
}
else
{
def.setLevel( level );
}
writeLocalFileHeader( entry );
}

/**
* Writes bytes to ZIP entry. <p>
*
* Override is necessary to support STORED entries, as well as calculationg
* CRC automatically for DEFLATED entries.</p>
*
* @param b Description of Parameter
* @param offset Description of Parameter
* @param length Description of Parameter
* @exception IOException Description of Exception
*/
public void write( byte[] b, int offset, int length )
throws IOException
{
if( entry.getMethod() == DEFLATED )
{
super.write( b, offset, length );
}
else
{
out.write( b, offset, length );
written += length;
}
crc.update( b, offset, length );
}

/**
* Retrieve the bytes for the given String in the encoding set for this
* Stream.
*
* @param name Description of Parameter
* @return The Bytes value
* @exception ZipException Description of Exception
* @since 1.3
*/
protected byte[] getBytes( String name )
throws ZipException
{
if( encoding == null )
{
return name.getBytes();
}
else
{
try
{
return name.getBytes( encoding );
}
catch( UnsupportedEncodingException uee )
{
throw new ZipException( uee.getMessage() );
}
}
}

/**
* Writes the &quot;End of central dir record&quot;
*
* @exception IOException Description of Exception
* @since 1.1
*/
protected void writeCentralDirectoryEnd()
throws IOException
{
out.write( EOCD_SIG.getBytes() );

// disk numbers
out.write( ZERO );
out.write( ZERO );

// number of entries
byte[] num = ( new ZipShort( entries.size() ) ).getBytes();
out.write( num );
out.write( num );

// length and location of CD
out.write( cdLength.getBytes() );
out.write( cdOffset.getBytes() );

// ZIP file comment
byte[] data = getBytes( comment );
out.write( ( new ZipShort( data.length ) ).getBytes() );
out.write( data );
}

/**
* Writes the central file header entry
*
* @param ze Description of Parameter
* @exception IOException Description of Exception
* @since 1.1
*/
protected void writeCentralFileHeader( ZipEntry ze )
throws IOException
{
out.write( CFH_SIG.getBytes() );
written += 4;

// version made by
out.write( ( new ZipShort( 20 ) ).getBytes() );
written += 2;

// version needed to extract
// general purpose bit flag
if( ze.getMethod() == DEFLATED )
{
// requires version 2 as we are going to store length info
// in the data descriptor
out.write( ( new ZipShort( 20 ) ).getBytes() );

// bit3 set to signal, we use a data descriptor
out.write( ( new ZipShort( 8 ) ).getBytes() );
}
else
{
out.write( ( new ZipShort( 10 ) ).getBytes() );
out.write( ZERO );
}
written += 4;

// compression method
out.write( ( new ZipShort( ze.getMethod() ) ).getBytes() );
written += 2;

// last mod. time and date
out.write( toDosTime( new Date( ze.getTime() ) ).getBytes() );
written += 4;

// CRC
// compressed length
// uncompressed length
out.write( ( new ZipLong( ze.getCrc() ) ).getBytes() );
out.write( ( new ZipLong( ze.getCompressedSize() ) ).getBytes() );
out.write( ( new ZipLong( ze.getSize() ) ).getBytes() );
written += 12;

// file name length
byte[] name = getBytes( ze.getName() );
out.write( ( new ZipShort( name.length ) ).getBytes() );
written += 2;

// extra field length
byte[] extra = ze.getCentralDirectoryExtra();
out.write( ( new ZipShort( extra.length ) ).getBytes() );
written += 2;

// file comment length
String comm = ze.getComment();
if( comm == null )
{
comm = "";
}
byte[] comment = getBytes( comm );
out.write( ( new ZipShort( comment.length ) ).getBytes() );
written += 2;

// disk number start
out.write( ZERO );
written += 2;

// internal file attributes
out.write( ( new ZipShort( ze.getInternalAttributes() ) ).getBytes() );
written += 2;

// external file attributes
out.write( ( new ZipLong( ze.getExternalAttributes() ) ).getBytes() );
written += 4;

// relative offset of LFH
out.write( ( (ZipLong)offsets.get( ze ) ).getBytes() );
written += 4;

// file name
out.write( name );
written += name.length;

// extra field
out.write( extra );
written += extra.length;

// file comment
out.write( comment );
written += comment.length;
}

/**
* Writes the data descriptor entry
*
* @param ze Description of Parameter
* @exception IOException Description of Exception
* @since 1.1
*/
protected void writeDataDescriptor( ZipEntry ze )
throws IOException
{
if( ze.getMethod() != DEFLATED )
{
return;
}
out.write( DD_SIG.getBytes() );
out.write( ( new ZipLong( entry.getCrc() ) ).getBytes() );
out.write( ( new ZipLong( entry.getCompressedSize() ) ).getBytes() );
out.write( ( new ZipLong( entry.getSize() ) ).getBytes() );
written += 16;
}

/**
* Writes the local file header entry
*
* @param ze Description of Parameter
* @exception IOException Description of Exception
* @since 1.1
*/
protected void writeLocalFileHeader( ZipEntry ze )
throws IOException
{
offsets.put( ze, new ZipLong( written ) );

out.write( LFH_SIG.getBytes() );
written += 4;

// version needed to extract
// general purpose bit flag
if( ze.getMethod() == DEFLATED )
{
// requires version 2 as we are going to store length info
// in the data descriptor
out.write( ( new ZipShort( 20 ) ).getBytes() );

// bit3 set to signal, we use a data descriptor
out.write( ( new ZipShort( 8 ) ).getBytes() );
}
else
{
out.write( ( new ZipShort( 10 ) ).getBytes() );
out.write( ZERO );
}
written += 4;

// compression method
out.write( ( new ZipShort( ze.getMethod() ) ).getBytes() );
written += 2;

// last mod. time and date
out.write( toDosTime( new Date( ze.getTime() ) ).getBytes() );
written += 4;

// CRC
// compressed length
// uncompressed length
if( ze.getMethod() == DEFLATED )
{
out.write( LZERO );
out.write( LZERO );
out.write( LZERO );
}
else
{
out.write( ( new ZipLong( ze.getCrc() ) ).getBytes() );
out.write( ( new ZipLong( ze.getSize() ) ).getBytes() );
out.write( ( new ZipLong( ze.getSize() ) ).getBytes() );
}
written += 12;

// file name length
byte[] name = getBytes( ze.getName() );
out.write( ( new ZipShort( name.length ) ).getBytes() );
written += 2;

// extra field length
byte[] extra = ze.getLocalFileDataExtra();
out.write( ( new ZipShort( extra.length ) ).getBytes() );
written += 2;

// file name
out.write( name );
written += name.length;

// extra field
out.write( extra );
written += extra.length;

dataStart = written;
}

}

+ 0
- 109
proposal/myrmidon/src/java/org/apache/aut/zip/ZipShort.java View File

@@ -1,109 +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.aut.zip;

/**
* Utility class that represents a two byte integer with conversion rules for
* the big endian byte order of ZIP files.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$
*/
public class ZipShort implements Cloneable
{

private int value;

/**
* Create instance from a number.
*
* @param value Description of Parameter
* @since 1.1
*/
public ZipShort( int value )
{
this.value = value;
}

/**
* Create instance from bytes.
*
* @param bytes Description of Parameter
* @since 1.1
*/
public ZipShort( byte[] bytes )
{
this( bytes, 0 );
}

/**
* Create instance from the two bytes starting at offset.
*
* @param bytes Description of Parameter
* @param offset Description of Parameter
* @since 1.1
*/
public ZipShort( byte[] bytes, int offset )
{
value = ( bytes[ offset + 1 ] << 8 ) & 0xFF00;
value += ( bytes[ offset ] & 0xFF );
}

/**
* Get value as two bytes in big endian byte order.
*
* @return The Bytes value
* @since 1.1
*/
public byte[] getBytes()
{
byte[] result = new byte[ 2 ];
result[ 0 ] = (byte)( value & 0xFF );
result[ 1 ] = (byte)( ( value & 0xFF00 ) >> 8 );
return result;
}

/**
* Get value as Java int.
*
* @return The Value value
* @since 1.1
*/
public int getValue()
{
return value;
}

/**
* Override to make two instances with same value equal.
*
* @param o Description of Parameter
* @return Description of the Returned Value
* @since 1.1
*/
public boolean equals( Object o )
{
if( o == null || !( o instanceof ZipShort ) )
{
return false;
}
return value == ( (ZipShort)o ).getValue();
}

/**
* Override to make two instances with same value equal.
*
* @return Description of the Returned Value
* @since 1.1
*/
public int hashCode()
{
return value;
}

}// ZipShort

+ 0
- 167
proposal/myrmidon/src/test/org/apache/aut/zip/test/AsiExtraFieldTestCase.java View File

@@ -1,167 +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.aut.zip.test;

import java.util.zip.ZipException;
import junit.framework.TestCase;
import org.apache.aut.zip.UnixStat;
import org.apache.aut.zip.AsiExtraField;

/**
* JUnit testcases AsiExtraField.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class AsiExtraFieldTestCase
extends TestCase
implements UnixStat
{
public AsiExtraFieldTestCase( final String name )
{
super( name );
}

/**
* Test file mode magic.
*/
public void testModes()
{
final AsiExtraField field = new AsiExtraField();
field.setMode( 0123 );
assertEquals( "plain file", 0100123, field.getMode() );
field.setDirectory( true );
assertEquals( "directory", 040123, field.getMode() );
field.setLinkedFile( "test" );
assertEquals( "symbolic link", 0120123, field.getMode() );
}

private AsiExtraField createField()
{
final AsiExtraField field = new AsiExtraField();
field.setMode( 0123 );
field.setUserId( 5 );
field.setGroupId( 6 );
return field;
}

public void testContent1()
{
final AsiExtraField field = createField();
final byte[] data = field.getLocalFileDataData();

// CRC manually calculated, sorry
final byte[] expect = {(byte)0xC6, 0x02, 0x78, (byte)0xB6, // CRC
0123, (byte)0x80, // mode
0, 0, 0, 0, // link length
5, 0, 6, 0}; // uid, gid
assertEquals( "no link", expect.length, data.length );
for( int i = 0; i < expect.length; i++ )
{
assertEquals( "no link, byte " + i, expect[ i ], data[ i ] );
}

field.setLinkedFile( "test" );
}

public void testContent2()
{
final AsiExtraField field = createField();
field.setLinkedFile( "test" );

final byte[] data = field.getLocalFileDataData();
final byte[] expect = new byte[]{0x75, (byte)0x8E, 0x41, (byte)0xFD, // CRC
0123, (byte)0xA0, // mode
4, 0, 0, 0, // link length
5, 0, 6, 0, // uid, gid
(byte)'t', (byte)'e', (byte)'s', (byte)'t'};
assertEquals( "no link", expect.length, data.length );
for( int i = 0; i < expect.length; i++ )
{
assertEquals( "no link, byte " + i, expect[ i ], data[ i ] );
}

}

public void testReparse1()
throws ZipException
{
// CRC manually calculated, sorry
final byte[] data = {(byte)0xC6, 0x02, 0x78, (byte)0xB6, // CRC
0123, (byte)0x80, // mode
0, 0, 0, 0, // link length
5, 0, 6, 0}; // uid, gid
final AsiExtraField field = new AsiExtraField();
field.parseFromLocalFileData( data, 0, data.length );

assertEquals( "length plain file", data.length,
field.getLocalFileDataLength().getValue() );
assertTrue( "plain file, no link", !field.isLink() );
assertTrue( "plain file, no dir", !field.isDirectory() );
assertEquals( "mode plain file", FILE_FLAG | 0123, field.getMode() );
assertEquals( "uid plain file", 5, field.getUserId() );
assertEquals( "gid plain file", 6, field.getGroupId() );
}

public void testReparse2()
throws ZipException
{
final byte[] data = new byte[]{0x75, (byte)0x8E, 0x41, (byte)0xFD, // CRC
0123, (byte)0xA0, // mode
4, 0, 0, 0, // link length
5, 0, 6, 0, // uid, gid
(byte)'t', (byte)'e', (byte)'s', (byte)'t'};
final AsiExtraField field = new AsiExtraField();
field.parseFromLocalFileData( data, 0, data.length );
assertEquals( "length link", data.length,
field.getLocalFileDataLength().getValue() );
assertTrue( "link, is link", field.isLink() );
assertTrue( "link, no dir", !field.isDirectory() );
assertEquals( "mode link", LINK_FLAG | 0123, field.getMode() );
assertEquals( "uid link", 5, field.getUserId() );
assertEquals( "gid link", 6, field.getGroupId() );
assertEquals( "test", field.getLinkedFile() );
}

public void testReparse3()
throws ZipException
{
final byte[] data = new byte[]{(byte)0x8E, 0x01, (byte)0xBF, (byte)0x0E, // CRC
0123, (byte)0x40, // mode
0, 0, 0, 0, // link
5, 0, 6, 0}; // uid, gid
final AsiExtraField field = new AsiExtraField();
field.parseFromLocalFileData( data, 0, data.length );
assertEquals( "length dir", data.length,
field.getLocalFileDataLength().getValue() );
assertTrue( "dir, no link", !field.isLink() );
assertTrue( "dir, is dir", field.isDirectory() );
assertEquals( "mode dir", DIR_FLAG | 0123, field.getMode() );
assertEquals( "uid dir", 5, field.getUserId() );
assertEquals( "gid dir", 6, field.getGroupId() );
}

public void testReparse4()
throws Exception
{
final byte[] data = new byte[]{0, 0, 0, 0, // bad CRC
0123, (byte)0x40, // mode
0, 0, 0, 0, // link
5, 0, 6, 0}; // uid, gid
final AsiExtraField field = new AsiExtraField();
try
{
field.parseFromLocalFileData( data, 0, data.length );
fail( "should raise bad CRC exception" );
}
catch( Exception e )
{
assertEquals( "bad CRC checksum 0 instead of ebf018e",
e.getMessage() );
}
}
}

+ 0
- 120
proposal/myrmidon/src/test/org/apache/aut/zip/test/ExtraFieldUtilsTestCase.java View File

@@ -1,120 +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.aut.zip.test;

import junit.framework.TestCase;
import org.apache.aut.zip.UnixStat;
import org.apache.aut.zip.AsiExtraField;
import org.apache.aut.zip.UnrecognizedExtraField;
import org.apache.aut.zip.ZipShort;
import org.apache.aut.zip.ZipExtraField;
import org.apache.aut.zip.ExtraFieldUtils;

/**
* JUnit testcases ExtraFieldUtils.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class ExtraFieldUtilsTestCase
extends TestCase
implements UnixStat
{
private AsiExtraField m_field;
private UnrecognizedExtraField m_dummy;
private byte[] m_data;
private byte[] m_local;

public ExtraFieldUtilsTestCase( final String name )
{
super( name );
}

public void setUp()
{
m_field = new AsiExtraField();
m_field.setMode( 0755 );
m_field.setDirectory( true );
m_dummy = new UnrecognizedExtraField();
m_dummy.setHeaderId( new ZipShort( 1 ) );
m_dummy.setLocalFileDataData( new byte[ 0 ] );
m_dummy.setCentralDirectoryData( new byte[]{0} );

m_local = m_field.getLocalFileDataData();
final byte[] dummyLocal = m_dummy.getLocalFileDataData();
m_data = new byte[ 4 + m_local.length + 4 + dummyLocal.length ];
System.arraycopy( m_field.getHeaderId().getBytes(), 0, m_data, 0, 2 );
System.arraycopy( m_field.getLocalFileDataLength().getBytes(), 0, m_data, 2, 2 );
System.arraycopy( m_local, 0, m_data, 4, m_local.length );
System.arraycopy( m_dummy.getHeaderId().getBytes(), 0, m_data,
4 + m_local.length, 2 );
System.arraycopy( m_dummy.getLocalFileDataLength().getBytes(), 0, m_data,
4 + m_local.length + 2, 2 );
System.arraycopy( dummyLocal, 0, m_data,
4 + m_local.length + 4, dummyLocal.length );

}

/**
* test parser.
*/
public void testParse() throws Exception
{
final ZipExtraField[] extraField = ExtraFieldUtils.parse( m_data );
assertEquals( "number of fields", 2, extraField.length );
assertTrue( "type field 1", extraField[ 0 ] instanceof AsiExtraField );
assertEquals( "mode field 1", 040755,
( (AsiExtraField)extraField[ 0 ] ).getMode() );
assertTrue( "type field 2", extraField[ 1 ] instanceof UnrecognizedExtraField );
assertEquals( "data length field 2", 0,
extraField[ 1 ].getLocalFileDataLength().getValue() );

final byte[] data2 = new byte[ m_data.length - 1 ];
System.arraycopy( m_data, 0, data2, 0, data2.length );
try
{
ExtraFieldUtils.parse( data2 );
fail( "data should be invalid" );
}
catch( Exception e )
{
assertEquals( "message",
"data starting at " + ( 4 + m_local.length ) + " is in unknown format",
e.getMessage() );
}
}

/**
* Test merge methods
*/
public void testMerge()
{
final byte[] local =
ExtraFieldUtils.mergeLocalFileDataData( new ZipExtraField[]{m_field, m_dummy} );
assertEquals( "local length", m_data.length, local.length );
for( int i = 0; i < local.length; i++ )
{
assertEquals( "local byte " + i, m_data[ i ], local[ i ] );
}

final byte[] dummyCentral = m_dummy.getCentralDirectoryData();
final byte[] data2 = new byte[ 4 + m_local.length + 4 + dummyCentral.length ];
System.arraycopy( m_data, 0, data2, 0, 4 + m_local.length + 2 );
System.arraycopy( m_dummy.getCentralDirectoryLength().getBytes(), 0,
data2, 4 + m_local.length + 2, 2 );
System.arraycopy( dummyCentral, 0, data2,
4 + m_local.length + 4, dummyCentral.length );

final byte[] central =
ExtraFieldUtils.mergeCentralDirectoryData( new ZipExtraField[]{m_field, m_dummy} );
assertEquals( "central length", data2.length, central.length );
for( int i = 0; i < central.length; i++ )
{
assertEquals( "central byte " + i, data2[ i ], central[ i ] );
}
}
}

+ 0
- 99
proposal/myrmidon/src/test/org/apache/aut/zip/test/ZipEntryTestCase.java View File

@@ -1,99 +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.aut.zip.test;

import java.util.NoSuchElementException;
import junit.framework.TestCase;
import org.apache.aut.zip.AsiExtraField;
import org.apache.aut.zip.UnrecognizedExtraField;
import org.apache.aut.zip.ZipEntry;
import org.apache.aut.zip.ZipExtraField;
import org.apache.aut.zip.ZipShort;

/**
* JUnit testcases ZipEntry.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class ZipEntryTestCase
extends TestCase
{
public ZipEntryTestCase( final String name )
{
super( name );
}

/**
* test handling of extra fields
*/
public void testExtraFields()
{
final AsiExtraField field = createField();
final UnrecognizedExtraField extraField = createExtraField();

final ZipEntry entry = new ZipEntry( "test/" );
entry.setExtraFields( new ZipExtraField[]{field, extraField} );
final byte[] data1 = entry.getExtra();
ZipExtraField[] result = entry.getExtraFields();
assertEquals( "first pass", 2, result.length );
assertSame( field, result[ 0 ] );
assertSame( extraField, result[ 1 ] );

UnrecognizedExtraField u2 = new UnrecognizedExtraField();
u2.setHeaderId( new ZipShort( 1 ) );
u2.setLocalFileDataData( new byte[]{1} );

entry.addExtraField( u2 );
byte[] data2 = entry.getExtra();
result = entry.getExtraFields();
assertEquals( "second pass", 2, result.length );
assertSame( field, result[ 0 ] );
assertSame( u2, result[ 1 ] );
assertEquals( "length second pass", data1.length + 1, data2.length );

UnrecognizedExtraField u3 = new UnrecognizedExtraField();
u3.setHeaderId( new ZipShort( 2 ) );
u3.setLocalFileDataData( new byte[]{1} );
entry.addExtraField( u3 );
result = entry.getExtraFields();
assertEquals( "third pass", 3, result.length );

entry.removeExtraField( new ZipShort( 1 ) );
byte[] data3 = entry.getExtra();
result = entry.getExtraFields();
assertEquals( "fourth pass", 2, result.length );
assertSame( field, result[ 0 ] );
assertSame( u3, result[ 1 ] );
assertEquals( "length fourth pass", data2.length, data3.length );

try
{
entry.removeExtraField( new ZipShort( 1 ) );
fail( "should be no such element" );
}
catch( final NoSuchElementException nse )
{
}
}

private UnrecognizedExtraField createExtraField()
{
UnrecognizedExtraField extraField = new UnrecognizedExtraField();
extraField.setHeaderId( new ZipShort( 1 ) );
extraField.setLocalFileDataData( new byte[ 0 ] );
return extraField;
}

private AsiExtraField createField()
{
final AsiExtraField field = new AsiExtraField();
field.setDirectory( true );
field.setMode( 0755 );
return field;
}
}

+ 0
- 80
proposal/myrmidon/src/test/org/apache/aut/zip/test/ZipLongTestCase.java View File

@@ -1,80 +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.aut.zip.test;

import junit.framework.TestCase;
import org.apache.aut.zip.ZipLong;

/**
* JUnit 3 testcases for org.apache.tools.zip.ZipLong.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class ZipLongTestCase
extends TestCase
{

public ZipLongTestCase( final String name )
{
super( name );
}

/**
* Test conversion to bytes.
*/
public void testToBytes()
{
final ZipLong zipLong = new ZipLong( 0x12345678 );
final byte[] result = zipLong.getBytes();
assertEquals( "length getBytes", 4, result.length );
assertEquals( "first byte getBytes", 0x78, result[ 0 ] );
assertEquals( "second byte getBytes", 0x56, result[ 1 ] );
assertEquals( "third byte getBytes", 0x34, result[ 2 ] );
assertEquals( "fourth byte getBytes", 0x12, result[ 3 ] );
}

/**
* Test conversion from bytes.
*/
public void testFromBytes()
{
final byte[] value = new byte[]{0x78, 0x56, 0x34, 0x12};
final ZipLong zipLong = new ZipLong( value );
assertEquals( "value from bytes", 0x12345678, zipLong.getValue() );
}

/**
* Test the contract of the equals method.
*/
public void testEquals()
{
final ZipLong zipLong1 = new ZipLong( 0x12345678 );
final ZipLong zipLong2 = new ZipLong( 0x12345678 );
final ZipLong zipLong3 = new ZipLong( 0x87654321 );

assertTrue( "reflexive", zipLong1.equals( zipLong1 ) );

assertTrue( "works", zipLong1.equals( zipLong2 ) );
assertTrue( "works, part two", !zipLong1.equals( zipLong3 ) );

assertTrue( "symmetric", zipLong2.equals( zipLong1 ) );

assertTrue( "null handling", !zipLong1.equals( null ) );
assertTrue( "non ZipLong handling", !zipLong1.equals( new Integer( 0x1234 ) ) );
}

/**
* Test sign handling.
*/
public void testSign()
{
final ZipLong zipLong =
new ZipLong( new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF} );
assertEquals( 0x00000000FFFFFFFFl, zipLong.getValue() );
}
}

+ 0
- 76
proposal/myrmidon/src/test/org/apache/aut/zip/test/ZipShortTestCase.java View File

@@ -1,76 +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.aut.zip.test;

import junit.framework.TestCase;
import org.apache.aut.zip.ZipShort;

/**
* JUnit 3 testcases for org.apache.tools.zip.ZipShort.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class ZipShortTestCase
extends TestCase
{
public ZipShortTestCase( String name )
{
super( name );
}

/**
* Test conversion to bytes.
*/
public void testToBytes()
{
final ZipShort zipShort = new ZipShort( 0x1234 );
byte[] result = zipShort.getBytes();
assertEquals( "length getBytes", 2, result.length );
assertEquals( "first byte getBytes", 0x34, result[ 0 ] );
assertEquals( "second byte getBytes", 0x12, result[ 1 ] );
}

/**
* Test conversion from bytes.
*/
public void testFromBytes()
{
byte[] val = new byte[]{0x34, 0x12};
final ZipShort zipShort = new ZipShort( val );
assertEquals( "value from bytes", 0x1234, zipShort.getValue() );
}

/**
* Test the contract of the equals method.
*/
public void testEquals()
{
final ZipShort zipShort = new ZipShort( 0x1234 );
final ZipShort zipShort2 = new ZipShort( 0x1234 );
final ZipShort zipShort3 = new ZipShort( 0x5678 );

assertTrue( "reflexive", zipShort.equals( zipShort ) );

assertTrue( "works", zipShort.equals( zipShort2 ) );
assertTrue( "works, part two", !zipShort.equals( zipShort3 ) );

assertTrue( "symmetric", zipShort2.equals( zipShort ) );

assertTrue( "null handling", !zipShort.equals( null ) );
assertTrue( "non ZipShort handling", !zipShort.equals( new Integer( 0x1234 ) ) );
}

/**
* Test sign handling.
*/
public void testSign()
{
final ZipShort zipShort = new ZipShort( new byte[]{(byte)0xFF, (byte)0xFF} );
assertEquals( 0x0000FFFF, zipShort.getValue() );
}
}

+ 0
- 167
proposal/myrmidon/src/testcases/org/apache/aut/zip/test/AsiExtraFieldTestCase.java View File

@@ -1,167 +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.aut.zip.test;

import java.util.zip.ZipException;
import junit.framework.TestCase;
import org.apache.aut.zip.UnixStat;
import org.apache.aut.zip.AsiExtraField;

/**
* JUnit testcases AsiExtraField.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class AsiExtraFieldTestCase
extends TestCase
implements UnixStat
{
public AsiExtraFieldTestCase( final String name )
{
super( name );
}

/**
* Test file mode magic.
*/
public void testModes()
{
final AsiExtraField field = new AsiExtraField();
field.setMode( 0123 );
assertEquals( "plain file", 0100123, field.getMode() );
field.setDirectory( true );
assertEquals( "directory", 040123, field.getMode() );
field.setLinkedFile( "test" );
assertEquals( "symbolic link", 0120123, field.getMode() );
}

private AsiExtraField createField()
{
final AsiExtraField field = new AsiExtraField();
field.setMode( 0123 );
field.setUserId( 5 );
field.setGroupId( 6 );
return field;
}

public void testContent1()
{
final AsiExtraField field = createField();
final byte[] data = field.getLocalFileDataData();

// CRC manually calculated, sorry
final byte[] expect = {(byte)0xC6, 0x02, 0x78, (byte)0xB6, // CRC
0123, (byte)0x80, // mode
0, 0, 0, 0, // link length
5, 0, 6, 0}; // uid, gid
assertEquals( "no link", expect.length, data.length );
for( int i = 0; i < expect.length; i++ )
{
assertEquals( "no link, byte " + i, expect[ i ], data[ i ] );
}

field.setLinkedFile( "test" );
}

public void testContent2()
{
final AsiExtraField field = createField();
field.setLinkedFile( "test" );

final byte[] data = field.getLocalFileDataData();
final byte[] expect = new byte[]{0x75, (byte)0x8E, 0x41, (byte)0xFD, // CRC
0123, (byte)0xA0, // mode
4, 0, 0, 0, // link length
5, 0, 6, 0, // uid, gid
(byte)'t', (byte)'e', (byte)'s', (byte)'t'};
assertEquals( "no link", expect.length, data.length );
for( int i = 0; i < expect.length; i++ )
{
assertEquals( "no link, byte " + i, expect[ i ], data[ i ] );
}

}

public void testReparse1()
throws ZipException
{
// CRC manually calculated, sorry
final byte[] data = {(byte)0xC6, 0x02, 0x78, (byte)0xB6, // CRC
0123, (byte)0x80, // mode
0, 0, 0, 0, // link length
5, 0, 6, 0}; // uid, gid
final AsiExtraField field = new AsiExtraField();
field.parseFromLocalFileData( data, 0, data.length );

assertEquals( "length plain file", data.length,
field.getLocalFileDataLength().getValue() );
assertTrue( "plain file, no link", !field.isLink() );
assertTrue( "plain file, no dir", !field.isDirectory() );
assertEquals( "mode plain file", FILE_FLAG | 0123, field.getMode() );
assertEquals( "uid plain file", 5, field.getUserId() );
assertEquals( "gid plain file", 6, field.getGroupId() );
}

public void testReparse2()
throws ZipException
{
final byte[] data = new byte[]{0x75, (byte)0x8E, 0x41, (byte)0xFD, // CRC
0123, (byte)0xA0, // mode
4, 0, 0, 0, // link length
5, 0, 6, 0, // uid, gid
(byte)'t', (byte)'e', (byte)'s', (byte)'t'};
final AsiExtraField field = new AsiExtraField();
field.parseFromLocalFileData( data, 0, data.length );
assertEquals( "length link", data.length,
field.getLocalFileDataLength().getValue() );
assertTrue( "link, is link", field.isLink() );
assertTrue( "link, no dir", !field.isDirectory() );
assertEquals( "mode link", LINK_FLAG | 0123, field.getMode() );
assertEquals( "uid link", 5, field.getUserId() );
assertEquals( "gid link", 6, field.getGroupId() );
assertEquals( "test", field.getLinkedFile() );
}

public void testReparse3()
throws ZipException
{
final byte[] data = new byte[]{(byte)0x8E, 0x01, (byte)0xBF, (byte)0x0E, // CRC
0123, (byte)0x40, // mode
0, 0, 0, 0, // link
5, 0, 6, 0}; // uid, gid
final AsiExtraField field = new AsiExtraField();
field.parseFromLocalFileData( data, 0, data.length );
assertEquals( "length dir", data.length,
field.getLocalFileDataLength().getValue() );
assertTrue( "dir, no link", !field.isLink() );
assertTrue( "dir, is dir", field.isDirectory() );
assertEquals( "mode dir", DIR_FLAG | 0123, field.getMode() );
assertEquals( "uid dir", 5, field.getUserId() );
assertEquals( "gid dir", 6, field.getGroupId() );
}

public void testReparse4()
throws Exception
{
final byte[] data = new byte[]{0, 0, 0, 0, // bad CRC
0123, (byte)0x40, // mode
0, 0, 0, 0, // link
5, 0, 6, 0}; // uid, gid
final AsiExtraField field = new AsiExtraField();
try
{
field.parseFromLocalFileData( data, 0, data.length );
fail( "should raise bad CRC exception" );
}
catch( Exception e )
{
assertEquals( "bad CRC checksum 0 instead of ebf018e",
e.getMessage() );
}
}
}

+ 0
- 120
proposal/myrmidon/src/testcases/org/apache/aut/zip/test/ExtraFieldUtilsTestCase.java View File

@@ -1,120 +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.aut.zip.test;

import junit.framework.TestCase;
import org.apache.aut.zip.UnixStat;
import org.apache.aut.zip.AsiExtraField;
import org.apache.aut.zip.UnrecognizedExtraField;
import org.apache.aut.zip.ZipShort;
import org.apache.aut.zip.ZipExtraField;
import org.apache.aut.zip.ExtraFieldUtils;

/**
* JUnit testcases ExtraFieldUtils.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class ExtraFieldUtilsTestCase
extends TestCase
implements UnixStat
{
private AsiExtraField m_field;
private UnrecognizedExtraField m_dummy;
private byte[] m_data;
private byte[] m_local;

public ExtraFieldUtilsTestCase( final String name )
{
super( name );
}

public void setUp()
{
m_field = new AsiExtraField();
m_field.setMode( 0755 );
m_field.setDirectory( true );
m_dummy = new UnrecognizedExtraField();
m_dummy.setHeaderId( new ZipShort( 1 ) );
m_dummy.setLocalFileDataData( new byte[ 0 ] );
m_dummy.setCentralDirectoryData( new byte[]{0} );

m_local = m_field.getLocalFileDataData();
final byte[] dummyLocal = m_dummy.getLocalFileDataData();
m_data = new byte[ 4 + m_local.length + 4 + dummyLocal.length ];
System.arraycopy( m_field.getHeaderId().getBytes(), 0, m_data, 0, 2 );
System.arraycopy( m_field.getLocalFileDataLength().getBytes(), 0, m_data, 2, 2 );
System.arraycopy( m_local, 0, m_data, 4, m_local.length );
System.arraycopy( m_dummy.getHeaderId().getBytes(), 0, m_data,
4 + m_local.length, 2 );
System.arraycopy( m_dummy.getLocalFileDataLength().getBytes(), 0, m_data,
4 + m_local.length + 2, 2 );
System.arraycopy( dummyLocal, 0, m_data,
4 + m_local.length + 4, dummyLocal.length );

}

/**
* test parser.
*/
public void testParse() throws Exception
{
final ZipExtraField[] extraField = ExtraFieldUtils.parse( m_data );
assertEquals( "number of fields", 2, extraField.length );
assertTrue( "type field 1", extraField[ 0 ] instanceof AsiExtraField );
assertEquals( "mode field 1", 040755,
( (AsiExtraField)extraField[ 0 ] ).getMode() );
assertTrue( "type field 2", extraField[ 1 ] instanceof UnrecognizedExtraField );
assertEquals( "data length field 2", 0,
extraField[ 1 ].getLocalFileDataLength().getValue() );

final byte[] data2 = new byte[ m_data.length - 1 ];
System.arraycopy( m_data, 0, data2, 0, data2.length );
try
{
ExtraFieldUtils.parse( data2 );
fail( "data should be invalid" );
}
catch( Exception e )
{
assertEquals( "message",
"data starting at " + ( 4 + m_local.length ) + " is in unknown format",
e.getMessage() );
}
}

/**
* Test merge methods
*/
public void testMerge()
{
final byte[] local =
ExtraFieldUtils.mergeLocalFileDataData( new ZipExtraField[]{m_field, m_dummy} );
assertEquals( "local length", m_data.length, local.length );
for( int i = 0; i < local.length; i++ )
{
assertEquals( "local byte " + i, m_data[ i ], local[ i ] );
}

final byte[] dummyCentral = m_dummy.getCentralDirectoryData();
final byte[] data2 = new byte[ 4 + m_local.length + 4 + dummyCentral.length ];
System.arraycopy( m_data, 0, data2, 0, 4 + m_local.length + 2 );
System.arraycopy( m_dummy.getCentralDirectoryLength().getBytes(), 0,
data2, 4 + m_local.length + 2, 2 );
System.arraycopy( dummyCentral, 0, data2,
4 + m_local.length + 4, dummyCentral.length );

final byte[] central =
ExtraFieldUtils.mergeCentralDirectoryData( new ZipExtraField[]{m_field, m_dummy} );
assertEquals( "central length", data2.length, central.length );
for( int i = 0; i < central.length; i++ )
{
assertEquals( "central byte " + i, data2[ i ], central[ i ] );
}
}
}

+ 0
- 99
proposal/myrmidon/src/testcases/org/apache/aut/zip/test/ZipEntryTestCase.java View File

@@ -1,99 +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.aut.zip.test;

import java.util.NoSuchElementException;
import junit.framework.TestCase;
import org.apache.aut.zip.AsiExtraField;
import org.apache.aut.zip.UnrecognizedExtraField;
import org.apache.aut.zip.ZipEntry;
import org.apache.aut.zip.ZipExtraField;
import org.apache.aut.zip.ZipShort;

/**
* JUnit testcases ZipEntry.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class ZipEntryTestCase
extends TestCase
{
public ZipEntryTestCase( final String name )
{
super( name );
}

/**
* test handling of extra fields
*/
public void testExtraFields()
{
final AsiExtraField field = createField();
final UnrecognizedExtraField extraField = createExtraField();

final ZipEntry entry = new ZipEntry( "test/" );
entry.setExtraFields( new ZipExtraField[]{field, extraField} );
final byte[] data1 = entry.getExtra();
ZipExtraField[] result = entry.getExtraFields();
assertEquals( "first pass", 2, result.length );
assertSame( field, result[ 0 ] );
assertSame( extraField, result[ 1 ] );

UnrecognizedExtraField u2 = new UnrecognizedExtraField();
u2.setHeaderId( new ZipShort( 1 ) );
u2.setLocalFileDataData( new byte[]{1} );

entry.addExtraField( u2 );
byte[] data2 = entry.getExtra();
result = entry.getExtraFields();
assertEquals( "second pass", 2, result.length );
assertSame( field, result[ 0 ] );
assertSame( u2, result[ 1 ] );
assertEquals( "length second pass", data1.length + 1, data2.length );

UnrecognizedExtraField u3 = new UnrecognizedExtraField();
u3.setHeaderId( new ZipShort( 2 ) );
u3.setLocalFileDataData( new byte[]{1} );
entry.addExtraField( u3 );
result = entry.getExtraFields();
assertEquals( "third pass", 3, result.length );

entry.removeExtraField( new ZipShort( 1 ) );
byte[] data3 = entry.getExtra();
result = entry.getExtraFields();
assertEquals( "fourth pass", 2, result.length );
assertSame( field, result[ 0 ] );
assertSame( u3, result[ 1 ] );
assertEquals( "length fourth pass", data2.length, data3.length );

try
{
entry.removeExtraField( new ZipShort( 1 ) );
fail( "should be no such element" );
}
catch( final NoSuchElementException nse )
{
}
}

private UnrecognizedExtraField createExtraField()
{
UnrecognizedExtraField extraField = new UnrecognizedExtraField();
extraField.setHeaderId( new ZipShort( 1 ) );
extraField.setLocalFileDataData( new byte[ 0 ] );
return extraField;
}

private AsiExtraField createField()
{
final AsiExtraField field = new AsiExtraField();
field.setDirectory( true );
field.setMode( 0755 );
return field;
}
}

+ 0
- 80
proposal/myrmidon/src/testcases/org/apache/aut/zip/test/ZipLongTestCase.java View File

@@ -1,80 +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.aut.zip.test;

import junit.framework.TestCase;
import org.apache.aut.zip.ZipLong;

/**
* JUnit 3 testcases for org.apache.tools.zip.ZipLong.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class ZipLongTestCase
extends TestCase
{

public ZipLongTestCase( final String name )
{
super( name );
}

/**
* Test conversion to bytes.
*/
public void testToBytes()
{
final ZipLong zipLong = new ZipLong( 0x12345678 );
final byte[] result = zipLong.getBytes();
assertEquals( "length getBytes", 4, result.length );
assertEquals( "first byte getBytes", 0x78, result[ 0 ] );
assertEquals( "second byte getBytes", 0x56, result[ 1 ] );
assertEquals( "third byte getBytes", 0x34, result[ 2 ] );
assertEquals( "fourth byte getBytes", 0x12, result[ 3 ] );
}

/**
* Test conversion from bytes.
*/
public void testFromBytes()
{
final byte[] value = new byte[]{0x78, 0x56, 0x34, 0x12};
final ZipLong zipLong = new ZipLong( value );
assertEquals( "value from bytes", 0x12345678, zipLong.getValue() );
}

/**
* Test the contract of the equals method.
*/
public void testEquals()
{
final ZipLong zipLong1 = new ZipLong( 0x12345678 );
final ZipLong zipLong2 = new ZipLong( 0x12345678 );
final ZipLong zipLong3 = new ZipLong( 0x87654321 );

assertTrue( "reflexive", zipLong1.equals( zipLong1 ) );

assertTrue( "works", zipLong1.equals( zipLong2 ) );
assertTrue( "works, part two", !zipLong1.equals( zipLong3 ) );

assertTrue( "symmetric", zipLong2.equals( zipLong1 ) );

assertTrue( "null handling", !zipLong1.equals( null ) );
assertTrue( "non ZipLong handling", !zipLong1.equals( new Integer( 0x1234 ) ) );
}

/**
* Test sign handling.
*/
public void testSign()
{
final ZipLong zipLong =
new ZipLong( new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF} );
assertEquals( 0x00000000FFFFFFFFl, zipLong.getValue() );
}
}

+ 0
- 76
proposal/myrmidon/src/testcases/org/apache/aut/zip/test/ZipShortTestCase.java View File

@@ -1,76 +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.aut.zip.test;

import junit.framework.TestCase;
import org.apache.aut.zip.ZipShort;

/**
* JUnit 3 testcases for org.apache.tools.zip.ZipShort.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class ZipShortTestCase
extends TestCase
{
public ZipShortTestCase( String name )
{
super( name );
}

/**
* Test conversion to bytes.
*/
public void testToBytes()
{
final ZipShort zipShort = new ZipShort( 0x1234 );
byte[] result = zipShort.getBytes();
assertEquals( "length getBytes", 2, result.length );
assertEquals( "first byte getBytes", 0x34, result[ 0 ] );
assertEquals( "second byte getBytes", 0x12, result[ 1 ] );
}

/**
* Test conversion from bytes.
*/
public void testFromBytes()
{
byte[] val = new byte[]{0x34, 0x12};
final ZipShort zipShort = new ZipShort( val );
assertEquals( "value from bytes", 0x1234, zipShort.getValue() );
}

/**
* Test the contract of the equals method.
*/
public void testEquals()
{
final ZipShort zipShort = new ZipShort( 0x1234 );
final ZipShort zipShort2 = new ZipShort( 0x1234 );
final ZipShort zipShort3 = new ZipShort( 0x5678 );

assertTrue( "reflexive", zipShort.equals( zipShort ) );

assertTrue( "works", zipShort.equals( zipShort2 ) );
assertTrue( "works, part two", !zipShort.equals( zipShort3 ) );

assertTrue( "symmetric", zipShort2.equals( zipShort ) );

assertTrue( "null handling", !zipShort.equals( null ) );
assertTrue( "non ZipShort handling", !zipShort.equals( new Integer( 0x1234 ) ) );
}

/**
* Test sign handling.
*/
public void testSign()
{
final ZipShort zipShort = new ZipShort( new byte[]{(byte)0xFF, (byte)0xFF} );
assertEquals( 0x0000FFFF, zipShort.getValue() );
}
}

+ 1
- 3
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Ear.java View File

@@ -9,10 +9,8 @@ package org.apache.tools.todo.taskdefs.archive;

import java.io.File;
import java.io.IOException;
import org.apache.aut.zip.ZipOutputStream;
import org.apache.avalon.excalibur.zip.ZipOutputStream;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskContext;

/**
* Creates a EAR archive. Based on WAR task


+ 1
- 3
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Jar.java View File

@@ -19,14 +19,12 @@ import java.io.PrintWriter;
import java.io.Reader;
import java.util.Enumeration;
import java.util.zip.ZipFile;
import org.apache.aut.zip.ZipOutputStream;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskContext;
import org.apache.tools.todo.taskdefs.manifest.Manifest;
import org.apache.tools.todo.taskdefs.manifest.ManifestException;
import org.apache.tools.todo.taskdefs.manifest.ManifestUtil;
import org.apache.tools.todo.types.FileScanner;
import org.apache.avalon.excalibur.zip.ZipOutputStream;

/**
* Creates a JAR archive.


+ 1
- 4
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/War.java View File

@@ -9,11 +9,8 @@ package org.apache.tools.todo.taskdefs.archive;

import java.io.File;
import java.io.IOException;
import org.apache.aut.zip.ZipOutputStream;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskContext;
import org.apache.tools.todo.taskdefs.archive.Jar;
import org.apache.avalon.excalibur.zip.ZipOutputStream;

/**
* Creates a WAR archive.


+ 3
- 6
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Zip.java View File

@@ -20,14 +20,11 @@ import java.util.Hashtable;
import java.util.Stack;
import java.util.zip.CRC32;
import java.util.zip.ZipInputStream;
import org.apache.aut.zip.ZipEntry;
import org.apache.aut.zip.ZipOutputStream;
import org.apache.avalon.excalibur.io.IOUtil;
import org.apache.avalon.excalibur.zip.ZipEntry;
import org.apache.avalon.excalibur.zip.ZipOutputStream;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskContext;
import org.apache.tools.todo.taskdefs.MatchingTask;
import org.apache.tools.todo.taskdefs.archive.WhenEmpty;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.tools.todo.types.FileScanner;
import org.apache.tools.todo.types.FileSet;
@@ -504,7 +501,7 @@ public class Zip
* @param zOut The feature to be added to the Files attribute
* @param prefix The feature to be added to the Files attribute
* @param fullpath The feature to be added to the Files attribute
* @exception java.io.IOException Description of Exception
* @exception IOException Description of Exception
*/
protected void addFiles( FileScanner scanner, ZipOutputStream zOut,
String prefix, String fullpath )


Loading…
Cancel
Save