pax_global_header 0000666 0000000 0000000 00000000064 12026402656 0014515 g ustar 00root root 0000000 0000000 52 comment=450d32090077c51efd34d87f6ddc88e407a9afed
plexus-archiver-plexus-archiver-2.2/ 0000775 0000000 0000000 00000000000 12026402656 0017620 5 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/.gitignore 0000664 0000000 0000000 00000000106 12026402656 0021605 0 ustar 00root root 0000000 0000000 target/
.project
.classpath
.settings/
bin
*.ipr
*.iml
*.iws
.idea
plexus-archiver-plexus-archiver-2.2/pom.xml 0000664 0000000 0000000 00000006215 12026402656 0021141 0 ustar 00root root 0000000 0000000
* Returns, whether recreating the archive is forced (default). Setting this option to false means, that the * archiver should compare the timestamps of included files with the timestamp of the target archive and rebuild the * archive only, if the latter timestamp precedes the former timestamps. Checking for timestamps will typically * offer a performance gain (in particular, if the following steps in a build can be suppressed, if an archive isn't * recrated) on the cost that you get inaccurate results from time to time. In particular, removal of source files * won't be detected. *
** An archiver doesn't necessarily support checks for uptodate. If so, setting this option to true will simply be * ignored. The method {@link #isSupportingForced()} may be called to check whether an archiver does support * uptodate checks. *
* * @return True, if the target archive should always be created; false otherwise * @see #setForced(boolean) * @see #isSupportingForced() */ boolean isForced(); /** ** Sets, whether recreating the archive is forced (default). Setting this option to false means, that the archiver * should compare the timestamps of included files with the timestamp of the target archive and rebuild the archive * only, if the latter timestamp precedes the former timestamps. Checking for timestamps will typically offer a * performance gain (in particular, if the following steps in a build can be suppressed, if an archive isn't * recrated) on the cost that you get inaccurate results from time to time. In particular, removal of source files * won't be detected. *
** An archiver doesn't necessarily support checks for uptodate. If so, setting this option to true will simply be * ignored. The method {@link #isSupportingForced()} may be called to check whether an archiver does support * uptodate checks. *
* * @param forced * True, if the target archive should always be created; false otherwise * @see #isForced() * @see #isSupportingForced() */ void setForced( boolean forced ); /** * Returns, whether the archive supports uptodate checks. If so, you may set {@link #setForced(boolean)} to true. * * @return True, if the archiver does support uptodate checks, false otherwise * @see #setForced(boolean) * @see #isForced() */ boolean isSupportingForced(); /** * Returns the behavior of this archiver when duplicate files are detected. */ String getDuplicateBehavior(); /** * Set the behavior of this archiver when duplicate files are detected. One of:If this jar has a classpath attribute in its manifest, we * can assume that it will only require an index of jars listed * there. try to find which classpath entry is most likely the * one the given file name points to.
* *In the absence of a classpath attribute, assume the other * files will be placed inside the same directory as this jar and * use their basename.
* *if there is a classpath and the given file doesn't match any * of its entries, return null.
* * @param fileName . * @param classpath . * @return The guessed name */ protected static String findJarName( String fileName, String[] classpath ) { if ( classpath == null ) { return new File( fileName ).getName(); } fileName = fileName.replace( File.separatorChar, '/' ); SortedMapfalse
.
*
* @param preserveLeadingSlashes the leading slashes flag.
*/
public void setPreserveLeadingSlashes( boolean preserveLeadingSlashes )
{
this.preserveLeadingSlashes = preserveLeadingSlashes;
}
}
/**
* Valid Modes for Compression attribute to Tar Task
*/
public static final class TarCompressionMethod
extends EnumeratedAttribute
{
// permissible values for compression attribute
/**
* No compression
*/
private static final String NONE = "none";
/**
* GZIP compression
*/
private static final String GZIP = "gzip";
/**
* BZIP2 compression
*/
private static final String BZIP2 = "bzip2";
/**
* Default constructor
*/
public TarCompressionMethod()
{
super();
try
{
setValue( NONE );
}
catch ( ArchiverException ae )
{
//Do nothing
}
}
/**
* Get valid enumeration values.
*
* @return valid enumeration values
*/
public String[] getValues()
{
return new String[]{NONE, GZIP, BZIP2};
}
/**
* This method wraps the output stream with the
* corresponding compression method
*
* @param ostream output stream
* @return output stream with on-the-fly compression
* @throws IOException thrown if file is not writable
*/
private OutputStream compress( final OutputStream ostream )
throws IOException
{
final String value = getValue();
if ( GZIP.equals( value ) )
{
return new GZIPOutputStream( ostream );
}
else if ( BZIP2.equals( value ) )
{
ostream.write( 'B' );
ostream.write( 'Z' );
return new CBZip2OutputStream( ostream );
}
return ostream;
}
}
public boolean isSupportingForced()
{
return true;
}
protected void cleanUp()
{
super.cleanUp();
tOut = null;
}
protected void close()
throws IOException
{
IOUtil.close( tOut );
}
protected String getArchiveType()
{
return "TAR";
}
}
TarBZip2UnArchiver.java 0000664 0000000 0000000 00000002471 12026402656 0034723 0 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/tar package org.codehaus.plexus.archiver.tar;
/**
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.File;
/**
* Extract files in tar with bzip2 compression
* @author Dan Tran
* @version $Revision: $
*/
public class TarBZip2UnArchiver
extends TarUnArchiver
{
public TarBZip2UnArchiver()
{
this.setupCompressionMethod();
}
public TarBZip2UnArchiver( File sourceFile )
{
super( sourceFile );
this.setupCompressionMethod();
}
private void setupCompressionMethod()
{
UntarCompressionMethod untarCompressionMethod = new UntarCompressionMethod( UntarCompressionMethod.BZIP2 );
this.setCompression( untarCompressionMethod );
}
}
plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/tar/TarBuffer.java 0000664 0000000 0000000 00000031252 12026402656 0033275 0 ustar 00root root 0000000 0000000 package org.codehaus.plexus.archiver.tar;
/*
* Copyright 2000,2002,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* This package is based on the work done by Timothy Gerard Endres
* (time@ice.com) to whom the Ant project is very grateful for his great code.
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
/**
* The TarBuffer class implements the tar archive concept
* of a buffered input stream. This concept goes back to the
* days of blocked tape drives and special io devices. In the
* Java universe, the only real function that this class
* performs is to ensure that files have the correct "block"
* size, or other tars will complain.
*
* You should never have a need to access this class directly.
* TarBuffers are created by Tar IO Streams.
*
* @version $Revision$ $Date$
* from org.apache.ant.tools.tar.TarBuffer v1.12
*/
public class TarBuffer
{
public static final int DEFAULT_RCDSIZE = ( 512 );
public static final int DEFAULT_BLKSIZE = ( DEFAULT_RCDSIZE * 20 );
private InputStream inStream;
private OutputStream outStream;
private byte[] blockBuffer;
private int currBlkIdx;
private int currRecIdx;
private int blockSize;
private int recordSize;
private int recsPerBlock;
private boolean debug;
public TarBuffer( InputStream inStream )
{
this( inStream, TarBuffer.DEFAULT_BLKSIZE );
}
public TarBuffer( InputStream inStream, int blockSize )
{
this( inStream, blockSize, TarBuffer.DEFAULT_RCDSIZE );
}
public TarBuffer( InputStream inStream, int blockSize, int recordSize )
{
this.inStream = inStream;
this.outStream = null;
this.initialize( blockSize, recordSize );
}
public TarBuffer( OutputStream outStream )
{
this( outStream, TarBuffer.DEFAULT_BLKSIZE );
}
public TarBuffer( OutputStream outStream, int blockSize )
{
this( outStream, blockSize, TarBuffer.DEFAULT_RCDSIZE );
}
public TarBuffer( OutputStream outStream, int blockSize, int recordSize )
{
this.inStream = null;
this.outStream = outStream;
this.initialize( blockSize, recordSize );
}
/**
* Initialization common to all constructors.
*/
private void initialize( int blockSize, int recordSize )
{
this.debug = false;
this.blockSize = blockSize;
this.recordSize = recordSize;
this.recsPerBlock = ( this.blockSize / this.recordSize );
this.blockBuffer = new byte[this.blockSize];
if ( this.inStream != null )
{
this.currBlkIdx = -1;
this.currRecIdx = this.recsPerBlock;
}
else
{
this.currBlkIdx = 0;
this.currRecIdx = 0;
}
}
/**
* Get the TAR Buffer's block size. Blocks consist of multiple records.
*/
public int getBlockSize()
{
return this.blockSize;
}
/**
* Get the TAR Buffer's record size.
*/
public int getRecordSize()
{
return this.recordSize;
}
/**
* Set the debugging flag for the buffer.
*
* @param debug If true, print debugging output.
*/
public void setDebug( boolean debug )
{
this.debug = debug;
}
/**
* Determine if an archive record indicate End of Archive. End of
* archive is indicated by a record that consists entirely of null bytes.
*
* @param record The record data to check.
*/
public boolean isEOFRecord( byte[] record )
{
for ( int i = 0, sz = this.getRecordSize(); i < sz; ++i )
{
if ( record[ i ] != 0 )
{
return false;
}
}
return true;
}
/**
* Skip over a record on the input stream.
*/
public void skipRecord()
throws IOException
{
if ( this.debug )
{
System.err.println( "SkipRecord: recIdx = " + this.currRecIdx
+ " blkIdx = " + this.currBlkIdx );
}
if ( this.inStream == null )
{
throw new IOException( "reading (via skip) from an output buffer" );
}
if ( this.currRecIdx >= this.recsPerBlock )
{
if ( !this.readBlock() )
{
return; // UNDONE
}
}
this.currRecIdx++;
}
/**
* Read a record from the input stream and return the data.
*
* @return The record data.
*/
public byte[] readRecord()
throws IOException
{
if ( this.debug )
{
System.err.println( "ReadRecord: recIdx = " + this.currRecIdx + " blkIdx = " + this.currBlkIdx );
}
if ( this.inStream == null )
{
throw new IOException( "reading from an output buffer" );
}
if ( this.currRecIdx >= this.recsPerBlock )
{
if ( !this.readBlock() )
{
return null;
}
}
byte[] result = new byte[this.recordSize];
System.arraycopy( this.blockBuffer, ( this.currRecIdx * this.recordSize ), result, 0, this.recordSize );
this.currRecIdx++;
return result;
}
/**
* @return false if End-Of-File, else true
*/
private boolean readBlock()
throws IOException
{
if ( this.debug )
{
System.err.println( "ReadBlock: blkIdx = " + this.currBlkIdx );
}
if ( this.inStream == null )
{
throw new IOException( "reading from an output buffer" );
}
this.currRecIdx = 0;
int offset = 0;
int bytesNeeded = this.blockSize;
while ( bytesNeeded > 0 )
{
long numBytes = this.inStream.read( this.blockBuffer, offset, bytesNeeded );
//
// NOTE
// We have fit EOF, and the block is not full!
//
// This is a broken archive. It does not follow the standard
// blocking algorithm. However, because we are generous, and
// it requires little effort, we will simply ignore the error
// and continue as if the entire block were read. This does
// not appear to break anything upstream. We used to return
// false in this case.
//
// Thanks to 'Yohann.Roussel@alcatel.fr' for this fix.
//
if ( numBytes == -1 )
{
if (offset == 0) {
// Ensure that we do not read gigabytes of zeros
// for a corrupt tar file.
// See http://issues.apache.org/bugzilla/show_bug.cgi?id=39924
return false;
}
// However, just leaving the unread portion of the buffer dirty does
// cause problems in some cases. This problem is described in
// http://issues.apache.org/bugzilla/show_bug.cgi?id=29877
//
// The solution is to fill the unused portion of the buffer with zeros.
Arrays.fill(blockBuffer, offset, offset + bytesNeeded, (byte) 0);
break;
}
offset += numBytes;
bytesNeeded -= numBytes;
if ( numBytes != this.blockSize )
{
if ( this.debug )
{
System.err.println( "ReadBlock: INCOMPLETE READ " + numBytes + " of " + this.blockSize
+ " bytes read." );
}
}
}
this.currBlkIdx++;
return true;
}
/**
* Get the current block number, zero based.
*
* @return The current zero based block number.
*/
public int getCurrentBlockNum()
{
return this.currBlkIdx;
}
/**
* Get the current record number, within the current block, zero based.
* Thus, current offset = (currentBlockNum * recsPerBlk) + currentRecNum.
*
* @return The current zero based record number.
*/
public int getCurrentRecordNum()
{
return this.currRecIdx - 1;
}
/**
* Write an archive record to the archive.
*
* @param record The record data to write to the archive.
*/
public void writeRecord( byte[] record )
throws IOException
{
if ( this.debug )
{
System.err.println( "WriteRecord: recIdx = " + this.currRecIdx + " blkIdx = " + this.currBlkIdx );
}
if ( this.outStream == null )
{
throw new IOException( "writing to an input buffer" );
}
if ( record.length != this.recordSize )
{
throw new IOException( "record to write has length '" + record.length
+ "' which is not the record size of '" + this.recordSize + "'" );
}
if ( this.currRecIdx >= this.recsPerBlock )
{
this.writeBlock();
}
System.arraycopy( record, 0, this.blockBuffer, ( this.currRecIdx * this.recordSize ), this.recordSize );
this.currRecIdx++;
}
/**
* Write an archive record to the archive, where the record may be
* inside of a larger array buffer. The buffer must be "offset plus
* record size" long.
*
* @param buf The buffer containing the record data to write.
* @param offset The offset of the record data within buf.
*/
public void writeRecord( byte[] buf, int offset )
throws IOException
{
if ( this.debug )
{
System.err.println( "WriteRecord: recIdx = " + this.currRecIdx + " blkIdx = " + this.currBlkIdx );
}
if ( this.outStream == null )
{
throw new IOException( "writing to an input buffer" );
}
if ( ( offset + this.recordSize ) > buf.length )
{
throw new IOException( "record has length '" + buf.length + "' with offset '" + offset
+ "' which is less than the record size of '" + this.recordSize + "'" );
}
if ( this.currRecIdx >= this.recsPerBlock )
{
this.writeBlock();
}
System.arraycopy( buf, offset, this.blockBuffer, ( this.currRecIdx * this.recordSize ), this.recordSize );
this.currRecIdx++;
}
/**
* Write a TarBuffer block to the archive.
*/
private void writeBlock()
throws IOException
{
if ( this.debug )
{
System.err.println( "WriteBlock: blkIdx = " + this.currBlkIdx );
}
if ( this.outStream == null )
{
throw new IOException( "writing to an input buffer" );
}
this.outStream.write( this.blockBuffer, 0, this.blockSize );
this.outStream.flush();
this.currRecIdx = 0;
this.currBlkIdx++;
Arrays.fill(blockBuffer, (byte) 0);
}
/**
* Flush the current data block if it has any data in it.
*/
private void flushBlock()
throws IOException
{
if ( this.debug )
{
System.err.println( "TarBuffer.flushBlock() called." );
}
if ( this.outStream == null )
{
throw new IOException( "writing to an input buffer" );
}
if ( this.currRecIdx > 0 )
{
this.writeBlock();
}
}
/**
* Close the TarBuffer. If this is an output buffer, also flush the
* current block before closing.
*/
public void close()
throws IOException
{
if ( this.debug )
{
System.err.println( "TarBuffer.closeBuffer()." );
}
if ( this.outStream != null )
{
this.flushBlock();
if ( this.outStream != System.out && this.outStream != System.err )
{
this.outStream.close();
this.outStream = null;
}
}
else if ( this.inStream != null )
{
if ( this.inStream != System.in )
{
this.inStream.close();
this.inStream = null;
}
}
}
}
TarCompressionMethod.java 0000664 0000000 0000000 00000003110 12026402656 0035437 0 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/tar package org.codehaus.plexus.archiver.tar;
/*
* Copyright 2000-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.util.EnumeratedAttribute;
/**
* Valid Modes for Compression attribute to Tar Task
*/
public final class TarCompressionMethod
extends EnumeratedAttribute
{
// permissible values for compression attribute
/**
* No compression
*/
private static final String NONE = "none";
/**
* GZIP compression
*/
private static final String GZIP = "gzip";
/**
* BZIP2 compression
*/
private static final String BZIP2 = "bzip2";
/**
* Default constructor
*/
public TarCompressionMethod()
throws ArchiverException
{
super();
setValue( NONE );
}
/**
* Get valid enumeration values.
*
* @return valid enumeration values
*/
public String[] getValues()
{
return new String[]{NONE, GZIP, BZIP2};
}
}
plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/tar/TarConstants.java0000664 0000000 0000000 00000006511 12026402656 0034040 0 ustar 00root root 0000000 0000000 package org.codehaus.plexus.archiver.tar;
/*
* Copyright 2000-2002,2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* This package is based on the work done by Timothy Gerard Endres
* (time@ice.com) to whom the Ant project is very grateful for his great code.
*/
/**
* This interface contains all the definitions used in the package.
*
* @version $Revision$ $Date$
* from org.apache.ant.tools.tar.TarConstants v1.13
*/
public interface TarConstants
{
/**
* The length of the name field in a header buffer.
*/
int NAMELEN = 100;
/**
* The length of the mode field in a header buffer.
*/
int MODELEN = 8;
/**
* The length of the user id field in a header buffer.
*/
int UIDLEN = 8;
/**
* The length of the group id field in a header buffer.
*/
int GIDLEN = 8;
/**
* The length of the checksum field in a header buffer.
*/
int CHKSUMLEN = 8;
/**
* The length of the size field in a header buffer.
*/
int SIZELEN = 12;
/**
* The length of the magic field in a header buffer.
*/
int MAGICLEN = 8;
/**
* The length of the modification time field in a header buffer.
*/
int MODTIMELEN = 12;
/**
* The length of the user name field in a header buffer.
*/
int UNAMELEN = 32;
/**
* The length of the group name field in a header buffer.
*/
int GNAMELEN = 32;
/**
* The length of the devices field in a header buffer.
*/
int DEVLEN = 8;
/**
* LF_ constants represent the "link flag" of an entry, or more commonly,
* the "entry type". This is the "old way" of indicating a normal file.
*/
byte LF_OLDNORM = 0;
/**
* Normal file type.
*/
byte LF_NORMAL = (byte) '0';
/**
* Link file type.
*/
byte LF_LINK = (byte) '1';
/**
* Symbolic link file type.
*/
byte LF_SYMLINK = (byte) '2';
/**
* Character device file type.
*/
byte LF_CHR = (byte) '3';
/**
* Block device file type.
*/
byte LF_BLK = (byte) '4';
/**
* Directory file type.
*/
byte LF_DIR = (byte) '5';
/**
* FIFO (pipe) file type.
*/
byte LF_FIFO = (byte) '6';
/**
* Contiguous file type.
*/
byte LF_CONTIG = (byte) '7';
/**
* The magic tag representing a POSIX tar archive.
*/
String TMAGIC = "ustar";
/**
* The magic tag representing a GNU tar archive.
*/
String GNU_TMAGIC = "ustar ";
/**
* The namr of the GNU tar entry which contains a long name.
*/
String GNU_LONGLINK = "././@LongLink";
/**
* Identifies the *next* file on the tape as having a long name.
*/
byte LF_GNUTYPE_LONGNAME = (byte) 'L';
}
plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/tar/TarEntry.java 0000664 0000000 0000000 00000045471 12026402656 0033175 0 ustar 00root root 0000000 0000000 package org.codehaus.plexus.archiver.tar;
/*
* Copyright 2000-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* This package is based on the work done by Timothy Gerard Endres
* (time@ice.com) to whom the Ant project is very grateful for his great code.
*/
import java.io.File;
import java.util.Date;
import java.util.Locale;
import org.codehaus.plexus.archiver.ArchiveFile;
/**
* This class represents an entry in a Tar archive. It consists
* of the entry's header, as well as the entry's File. Entries
* can be instantiated in one of three ways, depending on how
* they are to be used.
*
* TarEntries that are created from the header bytes read from
* an archive are instantiated with the TarEntry( byte[] )
* constructor. These entries will be used when extracting from
* or listing the contents of an archive. These entries have their
* header filled in using the header bytes. They also set the File
* to null, since they reference an archive entry not a file.
*
* TarEntries that are created from Files that are to be written
* into an archive are instantiated with the TarEntry( File )
* constructor. These entries have their header filled in using
* the File's information. They also keep a reference to the File
* for convenience when writing entries.
*
* Finally, TarEntries can be constructed from nothing but a name.
* This allows the programmer to construct the entry by hand, for
* instance when only an InputStream is available for writing to
* the archive, and the header information is constructed from
* other information. In this case the header fields are set to
* defaults and the File is set to null.
*
*
* The C structure for a Tar Entry's header is:
* * struct header { * char name[NAMSIZ]; * char mode[8]; * char uid[8]; * char gid[8]; * char size[12]; * char mtime[12]; * char chksum[8]; * char linkflag; * char linkname[NAMSIZ]; * char magic[8]; * char uname[TUNMLEN]; * char gname[TGNMLEN]; * char devmajor[8]; * char devminor[8]; * } header; ** * @version $Revision$ $Date$ * from org.apache.ant.tools.tar.TarEntry v1.22 */ public class TarEntry implements TarConstants, ArchiveFile.Entry { /** * The entry's name. */ private StringBuffer name; /** * The entry's permission mode. */ private int mode; /** * The entry's user id. */ private int userId; /** * The entry's group id. */ private int groupId; /** * The entry's size. */ private long size; /** * The entry's modification time. */ private long modTime; /** * The entry's checksum. */ private int checkSum; /** * The entry's link flag. */ private byte linkFlag; /** * The entry's link name. */ private StringBuffer linkName; /** * The entry's magic tag. */ private StringBuffer magic; /** * The entry's user name. */ private StringBuffer userName; /** * The entry's group name. */ private StringBuffer groupName; /** * The entry's major device number. */ private int devMajor; /** * The entry's minor device number. */ private int devMinor; /** * The entry's file reference */ private File file; /** * Maximum length of a user's name in the tar file */ public static final int MAX_NAMELEN = 31; /** * Default permissions bits for directories */ public static final int DEFAULT_DIR_MODE = 040755; /** * Default permissions bits for files */ public static final int DEFAULT_FILE_MODE = 0100644; /** * Convert millis to seconds */ public static final int MILLIS_PER_SECOND = 1000; /** * Construct an empty entry and prepares the header values. */ private TarEntry() { this.magic = new StringBuffer( TMAGIC ); this.name = new StringBuffer(); this.linkName = new StringBuffer(); String user = System.getProperty( "user.name", "" ); if ( user.length() > MAX_NAMELEN ) { user = user.substring( 0, MAX_NAMELEN ); } this.userId = 0; this.groupId = 0; this.userName = new StringBuffer( user ); this.groupName = new StringBuffer( "" ); this.file = null; } /** * Construct an entry with only a name. This allows the programmer * to construct the entry's header "by hand". File is set to null. * * @param name the entry name */ public TarEntry( String name ) { this(); boolean isDir = name.endsWith( "/" ); this.devMajor = 0; this.devMinor = 0; this.name = new StringBuffer( name ); this.mode = isDir ? DEFAULT_DIR_MODE : DEFAULT_FILE_MODE; this.linkFlag = isDir ? LF_DIR : LF_NORMAL; this.userId = 0; this.groupId = 0; this.size = 0; this.modTime = ( new Date() ).getTime() / MILLIS_PER_SECOND; this.linkName = new StringBuffer( "" ); this.userName = new StringBuffer( "" ); this.groupName = new StringBuffer( "" ); this.devMajor = 0; this.devMinor = 0; } /** * Construct an entry with a name an a link flag. * * @param name the entry name * @param linkFlag the entry link flag. */ public TarEntry( String name, byte linkFlag ) { this( name ); this.linkFlag = linkFlag; } /** * Construct an entry for a file. File is set to file, and the * header is constructed from information from the file. * * @param file The file that the entry represents. */ public TarEntry( File file ) { this(); this.file = file; String name = file.getPath(); String osname = System.getProperty( "os.name" ).toLowerCase( Locale.US ); if ( osname != null ) { // Strip off drive letters! // REVIEW Would a better check be "(File.separator == '\')"? if ( osname.startsWith( "windows" ) ) { if ( name.length() > 2 ) { char ch1 = name.charAt( 0 ); char ch2 = name.charAt( 1 ); if ( ch2 == ':' && ( ( ch1 >= 'a' && ch1 <= 'z' ) || ( ch1 >= 'A' && ch1 <= 'Z' ) ) ) { name = name.substring( 2 ); } } } else if ( osname.indexOf( "netware" ) > -1 ) { int colon = name.indexOf( ':' ); if ( colon != -1 ) { name = name.substring( colon + 1 ); } } } name = name.replace( File.separatorChar, '/' ); // No absolute pathnames // Windows (and Posix?) paths can start with "\\NetworkDrive\", // so we loop on starting /'s. while ( name.startsWith( "/" ) ) { name = name.substring( 1 ); } this.linkName = new StringBuffer( "" ); this.name = new StringBuffer( name ); if ( file.isDirectory() ) { this.mode = DEFAULT_DIR_MODE; this.linkFlag = LF_DIR; if ( this.name.charAt( this.name.length() - 1 ) != '/' ) { this.name.append( "/" ); } } else { this.mode = DEFAULT_FILE_MODE; this.linkFlag = LF_NORMAL; } this.size = file.length(); this.modTime = file.lastModified() / MILLIS_PER_SECOND; this.devMajor = 0; this.devMinor = 0; } /** * Construct an entry from an archive's header bytes. File is set * to null. * * @param headerBuf The header bytes from a tar archive entry. */ public TarEntry( byte[] headerBuf ) { this(); this.parseTarHeader( headerBuf ); } /** * Determine if the two entries are equal. Equality is determined * by the header names being equal. * * @param it Entry to be checked for equality. * @return True if the entries are equal. */ public boolean equals( TarEntry it ) { return this.getName().equals( it.getName() ); } /** * Determine if the two entries are equal. Equality is determined * by the header names being equal. * * @param it Entry to be checked for equality. * @return True if the entries are equal. */ public boolean equals( Object it ) { if ( it == null || getClass() != it.getClass() ) { return false; } return equals( (TarEntry) it ); } /** * Hashcodes are based on entry names. * * @return the entry hashcode */ public int hashCode() { return getName().hashCode(); } /** * Determine if the given entry is a descendant of this entry. * Descendancy is determined by the name of the descendant * starting with this entry's name. * * @param desc Entry to be checked as a descendant of this. * @return True if entry is a descendant of this. */ public boolean isDescendent( TarEntry desc ) { return desc.getName().startsWith( this.getName() ); } /** * Get this entry's name. * * @return This entry's name. */ public String getName() { return this.name.toString(); } /** * Set this entry's name. * * @param name This entry's new name. */ public void setName( String name ) { this.name = new StringBuffer( name ); } /** * Set the mode for this entry * * @param mode the mode for this entry */ public void setMode( int mode ) { this.mode = mode; } /** * Get this entry's link name. * * @return This entry's link name. */ public String getLinkName() { return this.linkName.toString(); } /** * Get this entry's user id. * * @return This entry's user id. */ public int getUserId() { return this.userId; } /** * Set this entry's user id. * * @param userId This entry's new user id. */ public void setUserId( int userId ) { this.userId = userId; } /** * Get this entry's group id. * * @return This entry's group id. */ public int getGroupId() { return this.groupId; } /** * Set this entry's group id. * * @param groupId This entry's new group id. */ public void setGroupId( int groupId ) { this.groupId = groupId; } /** * Get this entry's user name. * * @return This entry's user name. */ public String getUserName() { return this.userName.toString(); } /** * Set this entry's user name. * * @param userName This entry's new user name. */ public void setUserName( String userName ) { this.userName = new StringBuffer( userName ); } /** * Get this entry's group name. * * @return This entry's group name. */ public String getGroupName() { return this.groupName.toString(); } /** * Set this entry's group name. * * @param groupName This entry's new group name. */ public void setGroupName( String groupName ) { this.groupName = new StringBuffer( groupName ); } /** * Convenience method to set this entry's group and user ids. * * @param userId This entry's new user id. * @param groupId This entry's new group id. */ public void setIds( int userId, int groupId ) { this.setUserId( userId ); this.setGroupId( groupId ); } /** * Convenience method to set this entry's group and user names. * * @param userName This entry's new user name. * @param groupName This entry's new group name. */ public void setNames( String userName, String groupName ) { this.setUserName( userName ); this.setGroupName( groupName ); } /** * Set this entry's modification time. The parameter passed * to this method is in "Java time". * * @param time This entry's new modification time. */ public void setModTime( long time ) { this.modTime = time / MILLIS_PER_SECOND; } /** * Set this entry's modification time. * * @param time This entry's new modification time. */ public void setModTime( Date time ) { this.modTime = time.getTime() / MILLIS_PER_SECOND; } /** * Get this entry's modification time. * * @return time This entry's new modification time. */ public Date getModTime() { return new Date( this.modTime * MILLIS_PER_SECOND ); } /** * Get this entry's checksum time. * * @return time This entry's new modification time. */ public int getChecksum() { return checkSum; } /** * Get this entry's file. * * @return This entry's file. */ public File getFile() { return this.file; } /** * Get this entry's mode. * * @return This entry's mode. */ public int getMode() { return this.mode; } /** * Get this entry's file size. * * @return This entry's file size. */ public long getSize() { return this.size; } /** * Set this entry's file size. * * @param size This entry's new file size. */ public void setSize( long size ) { this.size = size; } /** * Indicate if this entry is a GNU long name block * * @return true if this is a long name extension provided by GNU tar */ public boolean isGNULongNameEntry() { return linkFlag == LF_GNUTYPE_LONGNAME && name.toString().equals( GNU_LONGLINK ); } /** * Return whether or not this entry represents a directory. * * @return True if this entry is a directory. */ public boolean isDirectory() { if ( this.file != null ) { return this.file.isDirectory(); } return ( this.linkFlag == LF_DIR ) || this.getName().endsWith( "/" ); } /** * If this entry represents a file, and the file is a directory, return * an array of TarEntries for this entry's children. * * @return An array of TarEntry's for this entry's children. */ public TarEntry[] getDirectoryEntries() { if ( this.file == null || !this.file.isDirectory() ) { return new TarEntry[0]; } String[] list = this.file.list(); TarEntry[] result = new TarEntry[list.length]; for ( int i = 0; i < list.length; ++i ) { result[ i ] = new TarEntry( new File( this.file, list[ i ] ) ); } return result; } /** * Write an entry's header information to a header buffer. * * @param outbuf The tar entry header buffer to fill in. */ public void writeEntryHeader( byte[] outbuf ) { int offset = 0; offset = TarUtils.getNameBytes( this.name, outbuf, offset, NAMELEN ); offset = TarUtils.getOctalBytes( this.mode, outbuf, offset, MODELEN ); offset = TarUtils.getOctalBytes( this.userId, outbuf, offset, UIDLEN ); offset = TarUtils.getOctalBytes( this.groupId, outbuf, offset, GIDLEN ); offset = TarUtils.getLongOctalBytes( this.size, outbuf, offset, SIZELEN ); offset = TarUtils.getLongOctalBytes( this.modTime, outbuf, offset, MODTIMELEN ); int csOffset = offset; for ( int c = 0; c < CHKSUMLEN; ++c ) { outbuf[ offset++ ] = (byte) ' '; } outbuf[ offset++ ] = this.linkFlag; offset = TarUtils.getNameBytes( this.linkName, outbuf, offset, NAMELEN ); offset = TarUtils.getNameBytes( this.magic, outbuf, offset, MAGICLEN ); offset = TarUtils.getNameBytes( this.userName, outbuf, offset, UNAMELEN ); offset = TarUtils.getNameBytes( this.groupName, outbuf, offset, GNAMELEN ); offset = TarUtils.getOctalBytes( this.devMajor, outbuf, offset, DEVLEN ); offset = TarUtils.getOctalBytes( this.devMinor, outbuf, offset, DEVLEN ); while ( offset < outbuf.length ) { outbuf[ offset++ ] = 0; } long checkSum = TarUtils.computeCheckSum( outbuf ); TarUtils.getCheckSumOctalBytes( checkSum, outbuf, csOffset, CHKSUMLEN ); } /** * Parse an entry's header information from a header buffer. * * @param header The tar entry header buffer to get information from. */ public void parseTarHeader( byte[] header ) { int offset = 0; this.name = TarUtils.parseName( header, offset, NAMELEN ); offset += NAMELEN; this.mode = (int) TarUtils.parseOctal( header, offset, MODELEN ); offset += MODELEN; this.userId = (int) TarUtils.parseOctal( header, offset, UIDLEN ); offset += UIDLEN; this.groupId = (int) TarUtils.parseOctal( header, offset, GIDLEN ); offset += GIDLEN; this.size = TarUtils.parseOctal( header, offset, SIZELEN ); offset += SIZELEN; this.modTime = TarUtils.parseOctal( header, offset, MODTIMELEN ); offset += MODTIMELEN; this.checkSum = (int) TarUtils.parseOctal( header, offset, CHKSUMLEN ); offset += CHKSUMLEN; this.linkFlag = header[ offset++ ]; this.linkName = TarUtils.parseName( header, offset, NAMELEN ); offset += NAMELEN; this.magic = TarUtils.parseName( header, offset, MAGICLEN ); offset += MAGICLEN; this.userName = TarUtils.parseName( header, offset, UNAMELEN ); offset += UNAMELEN; this.groupName = TarUtils.parseName( header, offset, GNAMELEN ); offset += GNAMELEN; this.devMajor = (int) TarUtils.parseOctal( header, offset, DEVLEN ); offset += DEVLEN; this.devMinor = (int) TarUtils.parseOctal( header, offset, DEVLEN ); } public long getLastModificationTime() { return modTime == 0 ? -1 : ( modTime * MILLIS_PER_SECOND ); } } plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/tar/TarFile.java 0000664 0000000 0000000 00000013420 12026402656 0032740 0 ustar 00root root 0000000 0000000 package org.codehaus.plexus.archiver.tar; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.FilterInputStream; import java.lang.reflect.UndeclaredThrowableException; import java.util.Enumeration; import java.util.NoSuchElementException; import org.codehaus.plexus.archiver.ArchiveFile; /** *
Implementation of {@link ArchiveFile} for tar files.
*Compared to * {@link ZipFile}, this one should be used with some care, due to the * nature of a tar file: While a zip file contains a catalog, a tar * file does not. In other words, the only way to read a tar file in * a performant manner is by iterating over it from the beginning to * the end. If you try to open another entry than the "next" entry, * then you force to skip entries, until the requested entry is found. * This may require to reread the entire file!
*In other words, the recommended use of this class is to use * {@link #getEntries()} and invoke {@link #getInputStream(TarEntry)} * only for the current entry. Basically, this is to handle it like * {@link TarInputStream}.
*The advantage of this class is that you may write code for the * {@link ArchiveFile}, which is valid for both tar files and zip files.
*/ public class TarFile implements ArchiveFile { private final java.io.File file; private TarInputStream inputStream; private TarEntry currentEntry; /** * Creates a new instance with the given file. */ public TarFile( File file ) { this.file = file; } /** * Implementation of {@link ArchiveFile#getEntries()}. Note, that there is * an interaction between this method and {@link #getInputStream(TarEntry)}, * or {@link #getInputStream(org.codehaus.plexus.archiver.ArchiveFile.Entry)}: * If an input stream is opened for any other entry than the enumerations * current entry, then entries may be skipped. */ public Enumeration getEntries() throws IOException { if ( inputStream != null ) { close(); } open(); return new Enumeration() { boolean currentEntryValid; public boolean hasMoreElements() { if ( !currentEntryValid ) { try { currentEntry = inputStream.getNextEntry(); } catch ( IOException e ) { throw new UndeclaredThrowableException( e ); } } return currentEntry != null; } public Object nextElement() { if ( currentEntry == null ) { throw new NoSuchElementException(); } currentEntryValid = false; return currentEntry; } }; } public void close() throws IOException { if ( inputStream != null ) { inputStream.close(); inputStream = null; } } public InputStream getInputStream( Entry entry ) throws IOException { return getInputStream( (TarEntry) entry ); } /** * Returns an {@link InputStream} with the given entries * contents. This {@link InputStream} may be closed: Nothing * happens in that case, because an actual close would invalidate * the underlying {@link TarInputStream}. */ public InputStream getInputStream( TarEntry entry ) throws IOException { if ( entry.equals( (Object) currentEntry ) && inputStream != null ) { return new FilterInputStream( inputStream ) { public void close() throws IOException { // Does nothing. } }; } return getInputStream( entry, currentEntry ); } protected InputStream getInputStream( File file ) throws IOException { return new FileInputStream( file ); } private InputStream getInputStream( TarEntry entry, TarEntry currentEntry ) throws IOException { if ( currentEntry == null || inputStream == null ) { // Search for the entry from the beginning of the file to the end. if ( inputStream != null ) { close(); } open(); if ( !findEntry( entry, null ) ) { throw new IOException( "Unknown entry: " + entry.getName() ); } } else { // Search for the entry from the current position to the end of the file. if ( findEntry( entry, null ) ) { return getInputStream( entry ); } close(); open(); if ( !findEntry( entry, currentEntry ) ) { throw new IOException( "No such entry: " + entry.getName() ); } } return getInputStream( entry ); } private void open() throws IOException { inputStream = new TarInputStream( getInputStream( file ) ); } private boolean findEntry( TarEntry entry, TarEntry currentEntry) throws IOException { for (;;) { this.currentEntry = inputStream.getNextEntry(); if ( this.currentEntry == null || (currentEntry != null && this.currentEntry.equals( currentEntry ) ) ) { return false; } if ( this.currentEntry.equals( entry ) ) { return true; } } } } TarGZipUnArchiver.java 0000664 0000000 0000000 00000002464 12026402656 0034650 0 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/tar package org.codehaus.plexus.archiver.tar; /** * * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.io.File; /** * Extract files in tar with gzip compression * @author Dan Tran * @version $Revision: $ */ public class TarGZipUnArchiver extends TarUnArchiver { public TarGZipUnArchiver() { this.setupCompressionMethod(); } public TarGZipUnArchiver( File sourceFile ) { super( sourceFile ); this.setupCompressionMethod(); } private void setupCompressionMethod() { UntarCompressionMethod untarCompressionMethod = new UntarCompressionMethod( UntarCompressionMethod.GZIP ); this.setCompression( untarCompressionMethod ); } } TarInputStream.java 0000664 0000000 0000000 00000026526 12026402656 0034270 0 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/tar package org.codehaus.plexus.archiver.tar; /* * Copyright 2000-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* * This package is based on the work done by Timothy Gerard Endres * (time@ice.com) to whom the Ant project is very grateful for his great code. */ import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * The TarInputStream reads a UNIX tar archive as an InputStream. * methods are provided to position at each successive entry in * the archive, and the read each entry as a normal input stream * using read(). * * @version $Revision$ $Date$ * from org.apache.ant.tools.tar.TarInputStream v1.16 */ public class TarInputStream extends FilterInputStream { protected boolean debug; protected boolean hasHitEOF; protected int entrySize; protected int entryOffset; protected byte[] oneBuf; protected byte[] readBuf; protected TarBuffer buffer; protected TarEntry currEntry; public TarInputStream( InputStream is ) { this( is, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE ); } public TarInputStream( InputStream is, int blockSize ) { this( is, blockSize, TarBuffer.DEFAULT_RCDSIZE ); } public TarInputStream( InputStream is, int blockSize, int recordSize ) { super( is ); this.buffer = new TarBuffer( is, blockSize, recordSize ); this.readBuf = null; this.oneBuf = new byte[1]; this.debug = false; this.hasHitEOF = false; } /** * Sets the debugging flag. * * @param debug True to turn on debugging. */ public void setDebug( boolean debug ) { this.debug = debug; this.buffer.setDebug( debug ); } /** * Closes this stream. Calls the TarBuffer's close() method. */ public void close() throws IOException { this.buffer.close(); } /** * Get the record size being used by this stream's TarBuffer. * * @return The TarBuffer record size. */ public int getRecordSize() { return this.buffer.getRecordSize(); } /** * Get the available data that can be read from the current * entry in the archive. This does not indicate how much data * is left in the entire archive, only in the current entry. * This value is determined from the entry's size header field * and the amount of data already read from the current entry. * * @return The number of available bytes for the current entry. */ public int available() throws IOException { return this.entrySize - this.entryOffset; } /** * Skip bytes in the input buffer. This skips bytes in the * current entry's data, not the entire archive, and will * stop at the end of the current entry's data if the number * to skip extends beyond that point. * * @param numToSkip The number of bytes to skip. */ public long skip( long numToSkip ) throws IOException { // REVIEW // This is horribly inefficient, but it ensures that we // properly skip over bytes via the TarBuffer... // byte[] skipBuf = new byte[8 * 1024]; long skip = numToSkip; while ( skip > 0 ) { int realSkip = (int) ( skip > skipBuf.length ? skipBuf.length : skip ); int numRead = this.read( skipBuf, 0, realSkip ); if ( numRead == -1 ) { break; } skip -= numRead; } return ( numToSkip - skip ); } /** * Since we do not support marking just yet, we return false. * * @return False. */ public boolean markSupported() { return false; } /** * Since we do not support marking just yet, we do nothing. * * @param markLimit The limit to mark. */ public void mark( int markLimit ) { } /** * Since we do not support marking just yet, we do nothing. */ public void reset() { } /** * Get the next entry in this tar archive. This will skip * over any remaining data in the current entry, if there * is one, and place the input stream at the header of the * next entry, and read the header and instantiate a new * TarEntry from the header bytes and return that entry. * If there are no more entries in the archive, null will * be returned to indicate that the end of the archive has * been reached. * * @return The next TarEntry in the archive, or null. */ public TarEntry getNextEntry() throws IOException { if ( this.hasHitEOF ) { return null; } if ( this.currEntry != null ) { int numToSkip = this.entrySize - this.entryOffset; if ( this.debug ) { System.err.println( "TarInputStream: SKIP currENTRY '" + this.currEntry.getName() + "' SZ " + this.entrySize + " OFF " + this.entryOffset + " skipping " + numToSkip + " bytes" ); } if ( numToSkip > 0 ) { this.skip( numToSkip ); } this.readBuf = null; } byte[] headerBuf = this.buffer.readRecord(); if ( headerBuf == null ) { if ( this.debug ) { System.err.println( "READ NULL RECORD" ); } this.hasHitEOF = true; } else if ( this.buffer.isEOFRecord( headerBuf ) ) { if ( this.debug ) { System.err.println( "READ EOF RECORD" ); } this.hasHitEOF = true; } if ( this.hasHitEOF ) { this.currEntry = null; } else { this.currEntry = new TarEntry( headerBuf ); if ( this.debug ) { System.err.println( "TarInputStream: SET CURRENTRY '" + this.currEntry.getName() + "' size = " + this.currEntry.getSize() ); } this.entryOffset = 0; // REVIEW How do we resolve this discrepancy?! this.entrySize = (int) this.currEntry.getSize(); } if ( this.currEntry != null && this.currEntry.isGNULongNameEntry() ) { // read in the name StringBuffer longName = new StringBuffer(); byte[] buffer = new byte[256]; int length; while ( ( length = read( buffer ) ) >= 0 ) { longName.append( new String( buffer, 0, length ) ); } getNextEntry(); // remove trailing null terminator if ( longName.length() > 0 && longName.charAt( longName.length() - 1 ) == 0 ) { longName.deleteCharAt( longName.length() - 1 ); } this.currEntry.setName( longName.toString() ); } return this.currEntry; } /** * Reads a byte from the current tar archive entry. * * This method simply calls read( byte[], int, int ). * * @return The byte read, or -1 at EOF. */ public int read() throws IOException { int num = this.read( this.oneBuf, 0, 1 ); if ( num == -1 ) { return num; } else { return (int) this.oneBuf[ 0 ]; } } /** * Reads bytes from the current tar archive entry. * * This method simply calls read( byte[], int, int ). * * @param buf The buffer into which to place bytes read. * @return The number of bytes read, or -1 at EOF. */ public int read( byte[] buf ) throws IOException { return this.read( buf, 0, buf.length ); } /** * Reads bytes from the current tar archive entry. * * This method is aware of the boundaries of the current * entry in the archive and will deal with them as if they * were this stream's start and EOF. * * @param buf The buffer into which to place bytes read. * @param offset The offset at which to place bytes read. * @param numToRead The number of bytes to read. * @return The number of bytes read, or -1 at EOF. */ public int read( byte[] buf, int offset, int numToRead ) throws IOException { int totalRead = 0; if ( this.entryOffset >= this.entrySize ) { return -1; } if ( ( numToRead + this.entryOffset ) > this.entrySize ) { numToRead = ( this.entrySize - this.entryOffset ); } if ( this.readBuf != null ) { int sz = ( numToRead > this.readBuf.length ) ? this.readBuf.length : numToRead; System.arraycopy( this.readBuf, 0, buf, offset, sz ); if ( sz >= this.readBuf.length ) { this.readBuf = null; } else { int newLen = this.readBuf.length - sz; byte[] newBuf = new byte[newLen]; System.arraycopy( this.readBuf, sz, newBuf, 0, newLen ); this.readBuf = newBuf; } totalRead += sz; numToRead -= sz; offset += sz; } while ( numToRead > 0 ) { byte[] rec = this.buffer.readRecord(); if ( rec == null ) { // Unexpected EOF! throw new IOException( "unexpected EOF with " + numToRead + " bytes unread" ); } int sz = numToRead; int recLen = rec.length; if ( recLen > sz ) { System.arraycopy( rec, 0, buf, offset, sz ); this.readBuf = new byte[recLen - sz]; System.arraycopy( rec, sz, this.readBuf, 0, recLen - sz ); } else { sz = recLen; System.arraycopy( rec, 0, buf, offset, recLen ); } totalRead += sz; numToRead -= sz; offset += sz; } this.entryOffset += totalRead; return totalRead; } /** * Copies the contents of the current tar archive entry directly into * an output stream. * * @param out The OutputStream into which to write the entry's data. */ public void copyEntryContents( OutputStream out ) throws IOException { byte[] buf = new byte[32 * 1024]; while ( true ) { int numRead = this.read( buf, 0, buf.length ); if ( numRead == -1 ) { break; } out.write( buf, 0, numRead ); } } } TarLongFileMode.java 0000664 0000000 0000000 00000004536 12026402656 0034316 0 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/tar package org.codehaus.plexus.archiver.tar; /* * Copyright 2000-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import org.codehaus.plexus.archiver.ArchiverException; import org.codehaus.plexus.archiver.util.EnumeratedAttribute; /** * Set of options for long file handling in the task. */ public class TarLongFileMode extends EnumeratedAttribute { /** * permissible values for longfile attribute */ public static final String WARN = "warn", FAIL = "fail", TRUNCATE = "truncate", GNU = "gnu", OMIT = "omit"; private final String[] validModes = {WARN, FAIL, TRUNCATE, GNU, OMIT}; /** * Constructor, defaults to "warn" */ public TarLongFileMode() { super(); try { setValue( WARN ); } catch ( ArchiverException ae ) { //Do nothing } } /** * @return the possible values for this enumerated type. */ public String[] getValues() { return validModes; } /** * @return true if value is "truncate". */ public boolean isTruncateMode() { return TRUNCATE.equalsIgnoreCase( getValue() ); } /** * @return true if value is "warn". */ public boolean isWarnMode() { return WARN.equalsIgnoreCase( getValue() ); } /** * @return true if value is "gnu". */ public boolean isGnuMode() { return GNU.equalsIgnoreCase( getValue() ); } /** * @return true if value is "fail". */ public boolean isFailMode() { return FAIL.equalsIgnoreCase( getValue() ); } /** * @return true if value is "omit". */ public boolean isOmitMode() { return OMIT.equalsIgnoreCase( getValue() ); } } TarOutputStream.java 0000664 0000000 0000000 00000025051 12026402656 0034461 0 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/tar package org.codehaus.plexus.archiver.tar; /* * Copyright 2000-2002,2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* * This package is based on the work done by Timothy Gerard Endres * (time@ice.com) to whom the Ant project is very grateful for his great code. */ import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; /** * The TarOutputStream writes a UNIX tar archive as an OutputStream. * Methods are provided to put entries, and then write their contents * by writing to this stream using write(). * * @version $Revision$ $Date$ * from org.apache.ant.tools.tar.TarOutputStream v1.16 */ public class TarOutputStream extends FilterOutputStream { /** * Fail if a long file name is required in the archive. */ public static final int LONGFILE_ERROR = 0; /** * Long paths will be truncated in the archive. */ public static final int LONGFILE_TRUNCATE = 1; /** * GNU tar extensions are used to store long file names in the archive. */ public static final int LONGFILE_GNU = 2; protected boolean debug; protected int currSize; protected int currBytes; protected byte[] oneBuf; protected byte[] recordBuf; protected int assemLen; protected byte[] assemBuf; protected TarBuffer buffer; protected int longFileMode = LONGFILE_ERROR; public TarOutputStream( OutputStream os ) { this( os, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE ); } public TarOutputStream( OutputStream os, int blockSize ) { this( os, blockSize, TarBuffer.DEFAULT_RCDSIZE ); } public TarOutputStream( OutputStream os, int blockSize, int recordSize ) { super( os ); this.buffer = new TarBuffer( os, blockSize, recordSize ); this.debug = false; this.assemLen = 0; this.assemBuf = new byte[recordSize]; this.recordBuf = new byte[recordSize]; this.oneBuf = new byte[1]; } public void setLongFileMode( int longFileMode ) { this.longFileMode = longFileMode; } /** * Sets the debugging flag. * * @param debugF True to turn on debugging. */ public void setDebug( boolean debugF ) { this.debug = debugF; } /** * Sets the debugging flag in this stream's TarBuffer. * * @param debug True to turn on debugging. */ public void setBufferDebug( boolean debug ) { this.buffer.setDebug( debug ); } /** * Ends the TAR archive without closing the underlying OutputStream. * The result is that two EOF record of nulls are written. */ public void finish() throws IOException { this.writeEOFRecord(); this.writeEOFRecord(); } /** * Ends the TAR archive and closes the underlying OutputStream. * This means that finish() is called followed by calling the * TarBuffer's close(). */ public void close() throws IOException { this.finish(); this.buffer.close(); } /** * Get the record size being used by this stream's TarBuffer. * * @return The TarBuffer record size. */ public int getRecordSize() { return this.buffer.getRecordSize(); } /** * Put an entry on the output stream. This writes the entry's * header record and positions the output stream for writing * the contents of the entry. Once this method is called, the * stream is ready for calls to write() to write the entry's * contents. Once the contents are written, closeEntry() * MUST be called to ensure that all buffered data * is completely written to the output stream. * * @param entry The TarEntry to be written to the archive. */ public void putNextEntry( TarEntry entry ) throws IOException { byte[] entryName = entry.getName().getBytes(); if ( entryName.length >= TarConstants.NAMELEN ) { if ( longFileMode == LONGFILE_GNU ) { // create a TarEntry for the LongLink, the contents // of which are the entry's name TarEntry longLinkEntry = new TarEntry( TarConstants.GNU_LONGLINK, TarConstants.LF_GNUTYPE_LONGNAME ); longLinkEntry.setSize( entryName.length + 1 ); putNextEntry( longLinkEntry ); write( entryName); write( 0 ); closeEntry(); } else if ( longFileMode != LONGFILE_TRUNCATE ) { throw new RuntimeException( "file name '" + entry.getName() + "' is too long ( > " + TarConstants.NAMELEN + " bytes)" ); } } entry.writeEntryHeader( this.recordBuf ); this.buffer.writeRecord( this.recordBuf ); this.currBytes = 0; if ( entry.isDirectory() ) { this.currSize = 0; } else { this.currSize = (int) entry.getSize(); } } /** * Close an entry. This method MUST be called for all file * entries that contain data. The reason is that we must * buffer data written to the stream in order to satisfy * the buffer's record based writes. Thus, there may be * data fragments still being assembled that must be written * to the output stream before this entry is closed and the * next entry written. */ public void closeEntry() throws IOException { if ( this.assemLen > 0 ) { for ( int i = this.assemLen; i < this.assemBuf.length; ++i ) { this.assemBuf[ i ] = 0; } this.buffer.writeRecord( this.assemBuf ); this.currBytes += this.assemLen; this.assemLen = 0; } if ( this.currBytes < this.currSize ) { throw new IOException( "entry closed at '" + this.currBytes + "' before the '" + this.currSize + "' bytes specified in the header were written" ); } } /** * Writes a byte to the current tar archive entry. * * This method simply calls read( byte[], int, int ). * * @param b The byte written. */ public void write( int b ) throws IOException { this.oneBuf[ 0 ] = (byte) b; this.write( this.oneBuf, 0, 1 ); } /** * Writes bytes to the current tar archive entry. * * This method simply calls write( byte[], int, int ). * * @param wBuf The buffer to write to the archive. */ public void write( byte[] wBuf ) throws IOException { this.write( wBuf, 0, wBuf.length ); } /** * Writes bytes to the current tar archive entry. This method * is aware of the current entry and will throw an exception if * you attempt to write bytes past the length specified for the * current entry. The method is also (painfully) aware of the * record buffering required by TarBuffer, and manages buffers * that are not a multiple of recordsize in length, including * assembling records from small buffers. * * @param wBuf The buffer to write to the archive. * @param wOffset The offset in the buffer from which to get bytes. * @param numToWrite The number of bytes to write. */ public void write( byte[] wBuf, int wOffset, int numToWrite ) throws IOException { if ( ( this.currBytes + numToWrite ) > this.currSize ) { throw new IOException( "request to write '" + numToWrite + "' bytes exceeds size in header of '" + this.currSize + "' bytes" ); // // We have to deal with assembly!!! // The programmer can be writing little 32 byte chunks for all // we know, and we must assemble complete records for writing. // REVIEW Maybe this should be in TarBuffer? Could that help to // eliminate some of the buffer copying. // } if ( this.assemLen > 0 ) { if ( ( this.assemLen + numToWrite ) >= this.recordBuf.length ) { int aLen = this.recordBuf.length - this.assemLen; System.arraycopy( this.assemBuf, 0, this.recordBuf, 0, this.assemLen ); System.arraycopy( wBuf, wOffset, this.recordBuf, this.assemLen, aLen ); this.buffer.writeRecord( this.recordBuf ); this.currBytes += this.recordBuf.length; wOffset += aLen; numToWrite -= aLen; this.assemLen = 0; } else { System.arraycopy( wBuf, wOffset, this.assemBuf, this.assemLen, numToWrite ); wOffset += numToWrite; this.assemLen += numToWrite; numToWrite -= numToWrite; } } // // When we get here we have EITHER: // o An empty "assemble" buffer. // o No bytes to write (numToWrite == 0) // while ( numToWrite > 0 ) { if ( numToWrite < this.recordBuf.length ) { System.arraycopy( wBuf, wOffset, this.assemBuf, this.assemLen, numToWrite ); this.assemLen += numToWrite; break; } this.buffer.writeRecord( wBuf, wOffset ); int num = this.recordBuf.length; this.currBytes += num; numToWrite -= num; wOffset += num; } } /** * Write an EOF (end of archive) record to the tar archive. * An EOF record consists of a record of all zeros. */ private void writeEOFRecord() throws IOException { for ( int i = 0; i < this.recordBuf.length; ++i ) { this.recordBuf[ i ] = 0; } this.buffer.writeRecord( this.recordBuf ); } } plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/tar/TarResource.java 0000664 0000000 0000000 00000004101 12026402656 0033644 0 ustar 00root root 0000000 0000000 package org.codehaus.plexus.archiver.tar; import java.io.IOException; import java.io.InputStream; import java.net.URL; import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes; import org.codehaus.plexus.components.io.attributes.SimpleResourceAttributes; import org.codehaus.plexus.components.io.resources.AbstractPlexusIoResource; import org.codehaus.plexus.components.io.resources.PlexusIoResource; import org.codehaus.plexus.components.io.resources.PlexusIoResourceWithAttributes; public class TarResource extends AbstractPlexusIoResource implements PlexusIoResourceWithAttributes { private final TarFile tarFile; private final TarEntry entry; private PlexusIoResourceAttributes attributes; public TarResource( TarFile tarFile, TarEntry entry ) { this.tarFile = tarFile; this.entry = entry; final boolean dir = entry.isDirectory(); setName( entry.getName() ); setDirectory( dir ); setExisting( true ); setFile( !dir ); long l = entry.getLastModificationTime(); setLastModified( l == -1 ? PlexusIoResource.UNKNOWN_MODIFICATION_DATE : l ); setSize( dir ? PlexusIoResource.UNKNOWN_RESOURCE_SIZE : entry.getSize() ); } public synchronized PlexusIoResourceAttributes getAttributes() { if ( attributes == null ) { attributes = new SimpleResourceAttributes(); attributes.setUserId( entry.getUserId() ); attributes.setUserName( entry.getUserName() ); attributes.setGroupId( entry.getGroupId() ); attributes.setGroupName( entry.getGroupName() ); attributes.setOctalMode( entry.getMode() ); } return attributes; } public synchronized void setAttributes( PlexusIoResourceAttributes attributes ) { this.attributes = attributes; } public URL getURL() throws IOException { return null; } public InputStream getContents() throws IOException { return tarFile.getInputStream( entry ); } } TarUnArchiver.java 0000664 0000000 0000000 00000013352 12026402656 0034054 0 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/tar package org.codehaus.plexus.archiver.tar; /** * * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.codehaus.plexus.archiver.ArchiverException; import org.codehaus.plexus.archiver.bzip2.CBZip2InputStream; import org.codehaus.plexus.archiver.util.EnumeratedAttribute; import org.codehaus.plexus.archiver.zip.AbstractZipUnArchiver; import org.codehaus.plexus.util.IOUtil; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.GZIPInputStream; /** * @author Emmanuel Venisse * @version $Revision$ $Date$ */ public class TarUnArchiver extends AbstractZipUnArchiver { public TarUnArchiver() { } public TarUnArchiver( File sourceFile ) { super( sourceFile ); } /** * compression method */ private UntarCompressionMethod compression = new UntarCompressionMethod(); /** * Set decompression algorithm to use; default=none. * * Allowable values are *useJvmChmod
set to true
*
* @param file
* @param mode
* @param logger
* @throws ArchiverException
*/
public static void chmod( final File file, final int mode, final Logger logger )
throws ArchiverException
{
chmod( file, mode, logger, Boolean.getBoolean( "useJvmChmod" ) && jvmFilePermAvailable );
}
private static void applyPermissionsWithJvm( final File file, final String mode, final Logger logger )
throws ArchiverException
{
final FilePermission filePermission = FilePermissionUtils.getFilePermissionFromMode( mode, logger );
Method method;
try
{
method = File.class.getMethod( "setReadable", new Class[] { Boolean.TYPE, Boolean.TYPE } );
method.invoke( file,
new Object[] { Boolean.valueOf( filePermission.isReadable() ),
Boolean.valueOf( filePermission.isOwnerOnlyReadable() ) } );
method = File.class.getMethod( "setExecutable", new Class[] { Boolean.TYPE, Boolean.TYPE } );
method.invoke( file,
new Object[] { Boolean.valueOf( filePermission.isExecutable() ),
Boolean.valueOf( filePermission.isOwnerOnlyExecutable() ) } );
method = File.class.getMethod( "setWritable", new Class[] { Boolean.TYPE, Boolean.TYPE } );
method.invoke( file,
new Object[] { Boolean.valueOf( filePermission.isWritable() ),
Boolean.valueOf( filePermission.isOwnerOnlyWritable() ) } );
}
catch ( final Exception e )
{
logger.error( "error calling dynamically file permissons with jvm " + e.getMessage(), e );
throw new ArchiverException( "error calling dynamically file permissons with jvm " + e.getMessage(), e );
}
}
}
plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/util/Compressor.java 0000664 0000000 0000000 00000013431 12026402656 0033737 0 ustar 00root root 0000000 0000000 package org.codehaus.plexus.archiver.util;
/**
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.components.io.resources.PlexusIoFileResource;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.IOUtil;
/**
* @version $Revision$ $Date$
*/
public abstract class Compressor
extends AbstractLogEnabled
{
private File destFile;
private PlexusIoResource source;
/**
* the required destination file.
*
* @param compressFile
*/
public void setDestFile( File compressFile )
{
this.destFile = compressFile;
}
public File getDestFile()
{
return destFile;
}
/**
* The resource to compress; required.
*/
public void setSource( PlexusIoResource source )
{
this.source = source;
}
/**
* The resource to compress; required.
*/
public PlexusIoResource getSource()
{
return source;
}
/**
* the file to compress; required.
* @deprecated Use {@link #getSource()}.
*/
public void setSourceFile( File srcFile )
{
final PlexusIoFileResource res = new PlexusIoFileResource( srcFile );
setSource( res );
}
/**
* @deprecated Use {@link #getSource()}.
*/
public File getSourceFile()
{
final PlexusIoResource res = getSource();
if ( res instanceof PlexusIoFileResource )
{
return ( (PlexusIoFileResource) res ).getFile();
}
return null;
}
/**
* validation routine
*
* @throws ArchiverException if anything is invalid
*/
private void validate()
throws ArchiverException
{
if ( destFile == null )
{
throw new ArchiverException( "Destination file attribute is required" );
}
if ( destFile.isDirectory() )
{
throw new ArchiverException( "Destination file attribute must not represent a directory!" );
}
if ( source == null )
{
throw new ArchiverException( "Source file attribute is required" );
}
if ( source.isDirectory() )
{
throw new ArchiverException( "Source file attribute must not represent a directory!" );
}
}
/**
* validate, then hand off to the subclass
*
* @throws BuildException
*/
public void execute()
throws ArchiverException
{
validate();
try
{
if ( !source.isExisting() )
{
// getLogger().info( "Nothing to do: " + sourceFile.getAbsolutePath()
// + " doesn't exist." );
}
else
{
final long l = source.getLastModified();
if ( l == PlexusIoResource.UNKNOWN_MODIFICATION_DATE || destFile.lastModified() == 0
|| destFile.lastModified() < l )
{
compress();
}
else
{
// getLogger().info( "Nothing to do: " + destFile.getAbsolutePath()
// + " is up to date." );
}
}
}
finally
{
close();
}
}
/**
* compress a stream to an output stream
*
* @param in
* @param zOut
* @throws IOException
*/
private void compressFile( InputStream in, OutputStream zOut )
throws IOException
{
byte[] buffer = new byte[8 * 1024];
int count = 0;
do
{
zOut.write( buffer, 0, count );
count = in.read( buffer, 0, buffer.length );
}
while ( count != -1 );
}
/**
* compress a file to an output stream
* @deprecated Use {@link #compress(PlexusIoResource, OutputStream)}.
*/
protected void compressFile( File file, OutputStream zOut )
throws IOException
{
InputStream in = new FileInputStream( file );
try
{
compressFile( in, zOut );
}
finally
{
IOUtil.close( in );
}
}
/**
* compress a resource to an output stream
*/
protected void compress( PlexusIoResource resource, OutputStream zOut )
throws IOException
{
InputStream in = resource.getContents();
try
{
compressFile( in, zOut );
}
finally
{
IOUtil.close( in );
}
}
/**
* subclasses must implement this method to do their compression
*
* this is public so the process of compression and closing can be dealt with separately.
*/
public abstract void compress()
throws ArchiverException;
/**
* subclasses must implement this method to cleanup after compression
*
* this is public so the process of compression and closing can be dealt with separately.
*/
public abstract void close();
}
DefaultArchivedFileSet.java 0000664 0000000 0000000 00000001027 12026402656 0036030 0 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/util package org.codehaus.plexus.archiver.util;
import java.io.File;
import org.codehaus.plexus.archiver.ArchivedFileSet;
/**
* Default implementation of {@link ArchivedFileSet}.
* @since 1.0-alpha-9
*/
public class DefaultArchivedFileSet
extends AbstractFileSet
implements ArchivedFileSet
{
private File archive;
/**
* Sets the file sets archive.
*/
public void setArchive( File archive )
{
this.archive = archive;
}
public File getArchive()
{
return archive;
}
}
DefaultFileSet.java 0000664 0000000 0000000 00000001014 12026402656 0034356 0 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/util package org.codehaus.plexus.archiver.util;
import java.io.File;
import org.codehaus.plexus.archiver.FileSet;
/**
* Default implementation of {@link FileSet}.
* @since 1.0-alpha-9
*/
public class DefaultFileSet
extends AbstractFileSet
implements FileSet
{
private File directory;
/**
* Sets the file sets base directory.
*/
public void setDirectory( File directory )
{
this.directory = directory;
}
public File getDirectory()
{
return directory;
}
}
EnumeratedAttribute.java 0000664 0000000 0000000 00000006367 12026402656 0035513 0 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/util package org.codehaus.plexus.archiver.util;
/**
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.codehaus.plexus.archiver.ArchiverException;
/**
* Helper class for attributes that can only take one of a fixed list
* of values.
*
* See {@link org.apache.tools.ant.taskdefs.FixCRLF FixCRLF} for an
* example.
*/
public abstract class EnumeratedAttribute
{
/**
* The selected value in this enumeration.
*/
protected String value;
/**
* the index of the selected value in the array.
*/
private int index = -1;
/**
* This is the only method a subclass needs to implement.
*
* @return an array holding all possible values of the enumeration.
* The order of elements must be fixed so that indexOfValue(String)
* always return the same index for the same value.
*/
public abstract String[] getValues();
/**
* bean constructor
*/
protected EnumeratedAttribute()
{
}
/**
* Invoked by {@link org.apache.tools.ant.IntrospectionHelper IntrospectionHelper}.
*/
public final void setValue( String value )
throws ArchiverException
{
int index = indexOfValue( value );
if ( index == -1 )
{
throw new ArchiverException( value + " is not a legal value for this attribute" );
}
this.index = index;
this.value = value;
}
/**
* Is this value included in the enumeration?
*/
public final boolean containsValue( String value )
{
return ( indexOfValue( value ) != -1 );
}
/**
* get the index of a value in this enumeration.
*
* @param value the string value to look for.
* @return the index of the value in the array of strings
* or -1 if it cannot be found.
* @see #getValues()
*/
public final int indexOfValue( String value )
{
String[] values = getValues();
if ( values == null || value == null )
{
return -1;
}
for ( int i = 0; i < values.length; i++ )
{
if ( value.equals( values[ i ] ) )
{
return i;
}
}
return -1;
}
/**
* @return the selected value.
*/
public final String getValue()
{
return value;
}
/**
* @return the index of the selected value in the array.
* @see #getValues()
*/
public final int getIndex()
{
return index;
}
/**
* Convert the value to its string form.
*
* @return the string form of the value.
*/
public String toString()
{
return getValue();
}
}
FilePermission.java 0000664 0000000 0000000 00000006121 12026402656 0034452 0 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/util package org.codehaus.plexus.archiver.util;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* @author Olivier Lamy
* @since 1.1
*
*/
public class FilePermission
{
private boolean executable;
private boolean ownerOnlyExecutable;
private boolean ownerOnlyReadable;
private boolean readable;
private boolean ownerOnlyWritable;
private boolean writable;
public FilePermission( boolean executable, boolean ownerOnlyExecutable, boolean ownerOnlyReadable,
boolean readable, boolean ownerOnlyWritable, boolean writable )
{
this.executable = executable;
this.ownerOnlyExecutable = ownerOnlyExecutable;
this.ownerOnlyReadable = ownerOnlyReadable;
this.readable = readable;
this.ownerOnlyWritable = ownerOnlyWritable;
this.writable = writable;
}
public boolean isExecutable()
{
return executable;
}
public void setExecutable( boolean executable )
{
this.executable = executable;
}
public boolean isOwnerOnlyExecutable()
{
return ownerOnlyExecutable;
}
public void setOwnerOnlyExecutable( boolean ownerOnlyExecutable )
{
this.ownerOnlyExecutable = ownerOnlyExecutable;
}
public boolean isOwnerOnlyReadable()
{
return ownerOnlyReadable;
}
public void setOwnerOnlyReadable( boolean ownerOnlyReadable )
{
this.ownerOnlyReadable = ownerOnlyReadable;
}
public boolean isReadable()
{
return readable;
}
public void setReadable( boolean readable )
{
this.readable = readable;
}
public boolean isOwnerOnlyWritable()
{
return ownerOnlyWritable;
}
public void setOwnerOnlyWritable( boolean ownerOnlyWritable )
{
this.ownerOnlyWritable = ownerOnlyWritable;
}
public boolean isWritable()
{
return writable;
}
public void setWritable( boolean writable )
{
this.writable = writable;
}
public String toString()
{
return "FilePermission [executable=" + executable + ", ownerOnlyExecutable=" + ownerOnlyExecutable
+ ", ownerOnlyReadable=" + ownerOnlyReadable + ", readable=" + readable + ", ownerOnlyWritable="
+ ownerOnlyWritable + ", writable=" + writable + "]";
}
}
FilePermissionUtils.java 0000664 0000000 0000000 00000013150 12026402656 0035473 0 ustar 00root root 0000000 0000000 plexus-archiver-plexus-archiver-2.2/src/main/java/org/codehaus/plexus/archiver/util package org.codehaus.plexus.archiver.util;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.util.ArrayList;
import java.util.List;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.StringUtils;
/**
* @author Olivier Lamy
* @since 1.0.1
*
*/
public class FilePermissionUtils
{
private FilePermissionUtils()
{
// no op
}
/**
* @param mode file mode "a la" unix ie 664, 440, etc
* @return FilePermission associated to the mode (group permission are ignored here)
*/
public static FilePermission getFilePermissionFromMode( String mode, Logger logger )
{
if ( StringUtils.isBlank( mode ) )
{
throw new IllegalArgumentException( " file mode cannot be empty" );
}
// 4 characters works on some unix (ie solaris)
if ( mode.length() != 3 && mode.length() != 4 )
{
throw new IllegalArgumentException( " file mode must be 3 or 4 characters" );
}
List modes = new ArrayList(mode.length());
for (int i = 0,size = mode.length();i