git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271954 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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" ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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 ); | |||||
| } | |||||
| } | |||||
| @@ -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() ) ); | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| @@ -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 | |||||
| @@ -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 "End of central dir record" | |||||
| * | |||||
| * @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; | |||||
| } | |||||
| } | |||||
| @@ -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 | |||||
| @@ -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() ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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 ] ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| @@ -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() ); | |||||
| } | |||||
| } | |||||
| @@ -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,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() ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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 ] ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| @@ -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() ); | |||||
| } | |||||
| } | |||||
| @@ -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() ); | |||||
| } | |||||
| } | |||||
| @@ -9,10 +9,8 @@ package org.apache.tools.todo.taskdefs.archive; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.IOException; | 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.TaskException; | ||||
| import org.apache.myrmidon.api.AbstractTask; | |||||
| import org.apache.myrmidon.api.TaskContext; | |||||
| /** | /** | ||||
| * Creates a EAR archive. Based on WAR task | * Creates a EAR archive. Based on WAR task | ||||
| @@ -19,14 +19,12 @@ import java.io.PrintWriter; | |||||
| import java.io.Reader; | import java.io.Reader; | ||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.zip.ZipFile; | import java.util.zip.ZipFile; | ||||
| import org.apache.aut.zip.ZipOutputStream; | |||||
| import org.apache.myrmidon.api.TaskException; | 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.Manifest; | ||||
| import org.apache.tools.todo.taskdefs.manifest.ManifestException; | import org.apache.tools.todo.taskdefs.manifest.ManifestException; | ||||
| import org.apache.tools.todo.taskdefs.manifest.ManifestUtil; | import org.apache.tools.todo.taskdefs.manifest.ManifestUtil; | ||||
| import org.apache.tools.todo.types.FileScanner; | import org.apache.tools.todo.types.FileScanner; | ||||
| import org.apache.avalon.excalibur.zip.ZipOutputStream; | |||||
| /** | /** | ||||
| * Creates a JAR archive. | * Creates a JAR archive. | ||||
| @@ -9,11 +9,8 @@ package org.apache.tools.todo.taskdefs.archive; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import org.apache.aut.zip.ZipOutputStream; | |||||
| import org.apache.myrmidon.api.TaskException; | 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. | * Creates a WAR archive. | ||||
| @@ -20,14 +20,11 @@ import java.util.Hashtable; | |||||
| import java.util.Stack; | import java.util.Stack; | ||||
| import java.util.zip.CRC32; | import java.util.zip.CRC32; | ||||
| import java.util.zip.ZipInputStream; | 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.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.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.MatchingTask; | ||||
| import org.apache.tools.todo.taskdefs.archive.WhenEmpty; | |||||
| import org.apache.tools.todo.types.DirectoryScanner; | import org.apache.tools.todo.types.DirectoryScanner; | ||||
| import org.apache.tools.todo.types.FileScanner; | import org.apache.tools.todo.types.FileScanner; | ||||
| import org.apache.tools.todo.types.FileSet; | 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 zOut The feature to be added to the Files attribute | ||||
| * @param prefix 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 | * @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, | protected void addFiles( FileScanner scanner, ZipOutputStream zOut, | ||||
| String prefix, String fullpath ) | String prefix, String fullpath ) | ||||