+**
+** This package is free software.
+**
+** You may redistribute it and/or modify it under the terms of the GNU
+** General Public License as published by the Free Software Foundation.
+** Version 2 of the license should be included with this distribution in
+** the file LICENSE, as well as License.html. If the license is not
+** included with this distribution, you may find a copy at the FSF web
+** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
+** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
+**
+** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
+** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
+** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
+** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
+** REDISTRIBUTION OF THIS SOFTWARE.
+**
+*/
+
+package com.ice.tar;
+
+import java.io.*;
+
+
+/**
+ * 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 TarArchives, which in turn provide
+ * several methods to allow you access to the buffer.
+ *
+ * @version $Revision$
+ * @author Timothy Gerard Endres,
+ * time@ice.com.
+ * @see TarArchive
+ */
+
+public class
+TarBuffer extends Object
+ {
+ public static final int DEFAULT_BLKSIZE = ( 512 * 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( TarArchive archive, InputStream inStream )
+ {
+ this( archive, inStream, TarBuffer.DEFAULT_BLKSIZE );
+ }
+
+ public
+ TarBuffer( TarArchive archive, InputStream inStream, int blockSize )
+ {
+ this.inStream = inStream;
+ this.outStream = null;
+ this.initialize( archive, blockSize );
+ }
+
+ public
+ TarBuffer( TarArchive archive, OutputStream outStream )
+ {
+ this( archive, outStream, TarBuffer.DEFAULT_BLKSIZE );
+ }
+
+ public
+ TarBuffer( TarArchive archive, OutputStream outStream, int blockSize )
+ {
+ this.inStream = null;
+ this.outStream = outStream;
+ this.initialize( archive, blockSize );
+ }
+
+ public void
+ initialize( TarArchive archive, int blockSize )
+ {
+ this.debug = false;
+ this.blockSize = blockSize;
+ this.recordSize = archive.getRecordSize();
+ this.recsPerBlock = ( this.blockSize / this.recordSize );
+ this.blockBuffer = new byte[ this.blockSize ];
+
+ if ( inStream != null )
+ {
+ this.currBlkIdx = -1;
+ this.currRecIdx = this.recsPerBlock;
+ }
+ else
+ {
+ this.currBlkIdx = 0;
+ this.currRecIdx = 0;
+ }
+ }
+
+ public void
+ setDebug( boolean debug )
+ {
+ this.debug = debug;
+ }
+
+ public void
+ skipBytes( int bytes )
+ {
+ for ( int num = bytes ; num > 0 ; )
+ {
+ try { this.skipRecord(); }
+ catch ( IOException ex )
+ {
+ break;
+ }
+ num -= this.recordSize;
+ }
+ }
+
+ public void
+ skipRecord()
+ throws IOException
+ {
+ if ( this.debug )
+ {
+ System.err.println
+ ( "SkipRecord: recIdx = " + this.currRecIdx
+ + " blkIdx = " + this.currBlkIdx );
+ }
+
+ if ( this.currRecIdx >= this.recsPerBlock )
+ {
+ if ( ! this.readBlock() )
+ return; // UNDONE
+ }
+
+ this.currRecIdx++;
+ }
+
+ public byte[]
+ readRecord()
+ throws IOException
+ {
+ if ( this.debug )
+ {
+ System.err.println
+ ( "ReadRecord: recIdx = " + this.currRecIdx
+ + " blkIdx = " + this.currBlkIdx );
+ }
+
+ 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
+ */
+
+ public boolean
+ readBlock()
+ throws IOException
+ {
+ if ( this.debug )
+ {
+ System.err.println
+ ( "ReadBlock: blkIdx = " + this.currBlkIdx );
+ }
+
+ if ( this.inStream == null )
+ throw new IOException( "input stream is null" );
+
+ this.currRecIdx = 0;
+
+ int offset = 0;
+ int bytesNeeded = this.blockSize;
+ for ( ; bytesNeeded > 0 ; )
+ {
+ long numBytes =
+ this.inStream.read
+ ( this.blockBuffer, offset, bytesNeeded );
+
+ if ( numBytes == -1 )
+ return false;
+
+ 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;
+ }
+
+ public int
+ getCurrentBlockNum()
+ {
+ return this.currBlkIdx;
+ }
+
+ public int
+ getCurrentRecordNum()
+ {
+ return this.currRecIdx - 1;
+ }
+
+ public void
+ writeRecord( byte[] record )
+ throws IOException
+ {
+ if ( this.debug )
+ {
+ System.err.println
+ ( "WriteRecord: recIdx = " + this.currRecIdx
+ + " blkIdx = " + this.currBlkIdx );
+ }
+
+ if ( this.currRecIdx >= this.recsPerBlock )
+ {
+ this.writeBlock();
+ }
+
+ System.arraycopy(
+ record, 0,
+ this.blockBuffer, (this.currRecIdx * this.recordSize),
+ this.recordSize );
+
+ this.currRecIdx++;
+ }
+
+ public void
+ writeBlock()
+ throws IOException
+ {
+ if ( this.debug )
+ {
+ System.err.println
+ ( "WriteBlock: blkIdx = " + this.currBlkIdx );
+ }
+
+ if ( this.outStream == null )
+ throw new IOException( "output stream is null" );
+
+ this.outStream.write( this.blockBuffer, 0, this.blockSize );
+
+ this.currRecIdx = 0;
+ this.currBlkIdx++;
+ }
+
+ public void
+ flushBlock()
+ throws IOException
+ {
+ if ( this.debug )
+ {
+ System.err.println( "TarBuffer.flushBlock() called." );
+ }
+
+ if ( this.outStream != null )
+ {
+ if ( this.currRecIdx > 0 )
+ {
+ this.writeBlock();
+ }
+ }
+ }
+
+ public void
+ closeBuffer()
+ throws IOException
+ {
+ if ( this.debug )
+ {
+ System.err.println( "TarBuffer.closeBuffer()." );
+ }
+
+ if ( this.outStream != null )
+ {
+ 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;
+ }
+ }
+ }
+
+ }
+
diff --git a/src/main/com/ice/tar/TarEntry.java b/src/main/com/ice/tar/TarEntry.java
new file mode 100644
index 000000000..ff5c25168
--- /dev/null
+++ b/src/main/com/ice/tar/TarEntry.java
@@ -0,0 +1,411 @@
+/*
+** Copyright (c) 1998 by Timothy Gerard Endres
+**
+**
+** This package is free software.
+**
+** You may redistribute it and/or modify it under the terms of the GNU
+** General Public License as published by the Free Software Foundation.
+** Version 2 of the license should be included with this distribution in
+** the file LICENSE, as well as License.html. If the license is not
+** included with this distribution, you may find a copy at the FSF web
+** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
+** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
+**
+** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
+** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
+** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
+** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
+** REDISTRIBUTION OF THIS SOFTWARE.
+**
+*/
+
+package com.ice.tar;
+
+import java.io.*;
+
+
+/**
+ *
+ *
+ * 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;
+ *
+ */
+
+public class
+TarEntry extends Object
+ {
+ protected TarArchive archive;
+ protected TarHeader header;
+ protected File file;
+
+
+ public
+ TarEntry( TarArchive archive, File file )
+ {
+ this.archive = archive;
+ this.file = file;
+ this.header = this.getFileTarHeader( file );
+ }
+
+ public
+ TarEntry( TarArchive archive, byte[] headerBuf )
+ throws InvalidHeaderException
+ {
+ this.archive = archive;
+ this.file = null;
+ this.header = this.parseTarHeader( headerBuf );
+ }
+
+ public TarArchive
+ getArchive()
+ {
+ return this.archive;
+ }
+
+ public File
+ getFile()
+ {
+ return this.file;
+ }
+
+ public TarHeader
+ getHeader()
+ {
+ return this.header;
+ }
+
+ public String
+ getName()
+ {
+ return this.header.name.toString();
+ }
+
+ public long
+ getSize()
+ {
+ return this.header.size;
+ }
+
+ public TarHeader
+ getFileTarHeader( File file )
+ {
+ TarHeader hdr = new TarHeader();
+
+ String name = file.getPath();
+ String osname = System.getProperty( "os.name" );
+
+ if ( osname != null )
+ {
+ if ( osname.startsWith( "macos" ) )
+ {
+ // UNDONE
+ }
+ else if ( osname.startsWith( "Windows" ) )
+ {
+ if ( name.length() > 2 )
+ {
+ char ch1 = name.charAt(0);
+ char ch2 = name.charAt(1);
+ if ( ch2 == File.separatorChar
+ && ( (ch1 >= 'a' && ch1 <= 'z')
+ || (ch1 >= 'a' && ch1 <= 'z') ) )
+ {
+ name = name.substring( 2 );
+ }
+ }
+ }
+ }
+
+ hdr.name =
+ new StringBuffer
+ ( name.replace( File.separatorChar, '/' ) );
+
+ if ( file.isDirectory() )
+ {
+ hdr.mode = 040755;
+ hdr.linkFlag = TarHeader.LF_DIR;
+ hdr.name.append( "/" );
+ }
+ else
+ {
+ hdr.mode = 0100644;
+ hdr.linkFlag = TarHeader.LF_NORMAL;
+ }
+
+ hdr.userId = this.archive.getUserId();
+ hdr.groupId = this.archive.getGroupId();
+ hdr.size = file.length();
+ hdr.modTime = file.lastModified() / 1000;
+ hdr.checkSum = 0;
+
+ hdr.linkName = new StringBuffer( "" );
+
+ hdr.magic = new StringBuffer( TarHeader.TMAGIC );
+
+ String userName = this.archive.getUserName();
+
+ if ( userName == null )
+ userName = System.getProperty( "user.name", "" );
+
+ if ( userName.length() > 31 )
+ userName = userName.substring( 0, 32 );
+
+ hdr.userName = new StringBuffer( userName );
+
+ String grpName = this.archive.getGroupName();
+
+ if ( grpName == null )
+ grpName = "";
+
+ if ( grpName.length() > 31 )
+ grpName = grpName.substring( 0, 32 );
+
+ hdr.groupName = new StringBuffer( grpName );
+
+ hdr.devMajor = 0;
+ hdr.devMinor = 0;
+
+ return hdr;
+ }
+
+ public boolean
+ isDirectory()
+ {
+ if ( this.file != null )
+ return this.file.isDirectory();
+
+ if ( this.header != null )
+ {
+ if ( this.header.linkFlag == TarHeader.LF_DIR )
+ return true;
+
+ if ( this.header.name.toString().endsWith( "/" ) )
+ return true;
+ }
+
+ return false;
+ }
+
+ 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
+ ( this.archive,
+ new File( this.file, list[i] ) );
+ }
+
+ return result;
+ }
+
+ public long
+ computeCheckSum( byte[] buf )
+ {
+ long sum = 0;
+
+ for ( int i = 0 ; i < buf.length ; ++i )
+ {
+ sum += 255 & buf[ i ];
+ }
+
+ return sum;
+ }
+
+ public void
+ writeEntryHeader( byte[] outbuf )
+ {
+ int offset = 0;
+
+ offset = TarHeader.getNameBytes
+ ( this.header.name, outbuf, offset, TarHeader.NAMELEN );
+
+ offset = TarHeader.getOctalBytes
+ ( this.header.mode, outbuf, offset, TarHeader.MODELEN );
+
+ offset = TarHeader.getOctalBytes
+ ( this.header.userId, outbuf, offset, TarHeader.UIDLEN );
+
+ offset = TarHeader.getOctalBytes
+ ( this.header.groupId, outbuf, offset, TarHeader.GIDLEN );
+
+ offset = TarHeader.getLongOctalBytes
+ ( this.header.size, outbuf, offset, TarHeader.SIZELEN );
+
+ offset = TarHeader.getLongOctalBytes
+ ( this.header.modTime, outbuf, offset, TarHeader.MODTIMELEN );
+
+ int csOffset = offset;
+ for ( int c = 0 ; c < TarHeader.CHKSUMLEN ; ++c )
+ outbuf[ offset++ ] = new Byte(" ").byteValue();
+
+ outbuf[ offset++ ] = this.header.linkFlag;
+
+ offset = TarHeader.getNameBytes
+ ( this.header.linkName, outbuf, offset, TarHeader.NAMELEN );
+
+ offset = TarHeader.getNameBytes
+ ( this.header.magic, outbuf, offset, TarHeader.MAGICLEN );
+
+ offset = TarHeader.getNameBytes
+ ( this.header.userName, outbuf, offset, TarHeader.UNAMELEN );
+
+ offset = TarHeader.getNameBytes
+ ( this.header.groupName, outbuf, offset, TarHeader.GNAMELEN );
+
+ offset = TarHeader.getOctalBytes
+ ( this.header.devMajor, outbuf, offset, TarHeader.DEVLEN );
+
+ offset = TarHeader.getOctalBytes
+ ( this.header.devMinor, outbuf, offset, TarHeader.DEVLEN );
+
+ long checkSum = this.computeCheckSum( outbuf );
+
+ TarHeader.getCheckSumOctalBytes
+ ( checkSum, outbuf, csOffset, TarHeader.CHKSUMLEN );
+ }
+
+ public void
+ writeEntryContents( TarBuffer buffer )
+ throws IOException
+ {
+ if ( this.file == null )
+ throw new IOException( "file is null" );
+
+ if ( ! this.file.exists() )
+ throw new IOException
+ ( "file '" + this.file.getPath()
+ + "' does not exist" );
+
+ // UNDONE - handle ASCII line termination translation!!!!
+
+ FileInputStream in =
+ new FileInputStream( this.file );
+
+ int recSize = this.archive.getRecordSize();
+
+ byte[] recbuf = new byte[ recSize ];
+
+ for ( ; ; )
+ {
+ int num = in.read( recbuf, 0, recSize );
+ if ( num == -1 )
+ break;
+
+ if ( num < recSize )
+ {
+ for ( int j = num ; j < recSize ; ++j )
+ recbuf[j] = 0;
+ }
+
+ buffer.writeRecord( recbuf );
+ }
+
+ in.close();
+ }
+
+ public TarHeader
+ parseTarHeader( byte[] header )
+ throws InvalidHeaderException
+ {
+ TarHeader hdr = new TarHeader();
+
+ int offset = 0;
+
+ hdr.name =
+ TarHeader.parseName( header, offset, TarHeader.NAMELEN );
+
+ offset += TarHeader.NAMELEN;
+
+ hdr.mode = (int)
+ TarHeader.parseOctal( header, offset, TarHeader.MODELEN );
+
+ offset += TarHeader.MODELEN;
+
+ hdr.userId = (int)
+ TarHeader.parseOctal( header, offset, TarHeader.UIDLEN );
+
+ offset += TarHeader.UIDLEN;
+
+ hdr.groupId = (int)
+ TarHeader.parseOctal( header, offset, TarHeader.GIDLEN );
+
+ offset += TarHeader.GIDLEN;
+
+ hdr.size =
+ TarHeader.parseOctal( header, offset, TarHeader.SIZELEN );
+
+ offset += TarHeader.SIZELEN;
+
+ hdr.modTime =
+ TarHeader.parseOctal( header, offset, TarHeader.MODTIMELEN );
+
+ offset += TarHeader.MODTIMELEN;
+
+ hdr.checkSum = (int)
+ TarHeader.parseOctal( header, offset, TarHeader.CHKSUMLEN );
+
+ offset += TarHeader.CHKSUMLEN;
+
+ hdr.linkFlag = header[ offset++ ];
+
+ hdr.linkName =
+ TarHeader.parseName( header, offset, TarHeader.NAMELEN );
+
+ offset += TarHeader.NAMELEN;
+
+ hdr.magic =
+ TarHeader.parseName( header, offset, TarHeader.MAGICLEN );
+
+ offset += TarHeader.MAGICLEN;
+
+ hdr.userName =
+ TarHeader.parseName( header, offset, TarHeader.UNAMELEN );
+
+ offset += TarHeader.UNAMELEN;
+
+ hdr.groupName =
+ TarHeader.parseName( header, offset, TarHeader.GNAMELEN );
+
+ offset += TarHeader.GNAMELEN;
+
+ hdr.devMajor = (int)
+ TarHeader.parseOctal( header, offset, TarHeader.DEVLEN );
+
+ offset += TarHeader.DEVLEN;
+
+ hdr.devMinor = (int)
+ TarHeader.parseOctal( header, offset, TarHeader.DEVLEN );
+
+ return hdr;
+ }
+
+ }
+
diff --git a/src/main/com/ice/tar/TarHeader.java b/src/main/com/ice/tar/TarHeader.java
new file mode 100644
index 000000000..7c474c23e
--- /dev/null
+++ b/src/main/com/ice/tar/TarHeader.java
@@ -0,0 +1,200 @@
+/*
+** Copyright (c) 1998 by Timothy Gerard Endres
+**
+**
+** This package is free software.
+**
+** You may redistribute it and/or modify it under the terms of the GNU
+** General Public License as published by the Free Software Foundation.
+** Version 2 of the license should be included with this distribution in
+** the file LICENSE, as well as License.html. If the license is not
+** included with this distribution, you may find a copy at the FSF web
+** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
+** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
+**
+** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
+** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
+** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
+** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
+** REDISTRIBUTION OF THIS SOFTWARE.
+**
+*/
+
+package com.ice.tar;
+
+
+public class
+TarHeader extends Object
+ {
+ public static final int NAMELEN = 100;
+ public static final int MODELEN = 8;
+ public static final int UIDLEN = 8;
+ public static final int GIDLEN = 8;
+ public static final int CHKSUMLEN = 8;
+ public static final int SIZELEN = 12;
+ public static final int MAGICLEN = 8;
+ public static final int MODTIMELEN = 12;
+ public static final int UNAMELEN = 32;
+ public static final int GNAMELEN = 32;
+ public static final int DEVLEN = 8;
+
+ public static final byte LF_OLDNORM = 0;
+ public static final byte LF_NORMAL = new Byte("0").byteValue();
+ public static final byte LF_LINK = new Byte("1").byteValue();
+ public static final byte LF_SYMLINK = new Byte("2").byteValue();
+ public static final byte LF_CHR = new Byte("3").byteValue();
+ public static final byte LF_BLK = new Byte("4").byteValue();
+ public static final byte LF_DIR = new Byte("5").byteValue();
+ public static final byte LF_FIFO = new Byte("6").byteValue();
+ public static final byte LF_CONTIG = new Byte("7").byteValue();
+
+ public static final String TMAGIC = "ustar ";
+
+ public StringBuffer name;
+ public int mode;
+ public int userId;
+ public int groupId;
+ public long size;
+ public long modTime;
+ public int checkSum;
+ public byte linkFlag;
+ public StringBuffer linkName;
+ public StringBuffer magic;
+ public StringBuffer userName;
+ public StringBuffer groupName;
+ public int devMajor;
+ public int devMinor;
+
+ public
+ TarHeader()
+ {
+ }
+
+ public static long
+ parseOctal( byte[] header, int offset, int length )
+ throws InvalidHeaderException
+ {
+ long result = 0;
+ boolean stillPadding = true;
+
+ int end = offset + length;
+ for ( int i = offset ; i < end ; ++i )
+ {
+ if ( header[i] == 0 )
+ break;
+
+ if ( header[i] == ' ' || header[i] == '0' )
+ {
+ if ( stillPadding )
+ continue;
+
+ if ( header[i] == ' ' )
+ break;
+ }
+
+ stillPadding = false;
+
+ result =
+ (result << 3)
+ + (header[i] - '0');
+ }
+
+ return result;
+ }
+
+ public static StringBuffer
+ parseName( byte[] header, int offset, int length )
+ throws InvalidHeaderException
+ {
+ StringBuffer result = new StringBuffer( length );
+
+ int end = offset + length;
+ for ( int i = offset ; i < end ; ++i )
+ {
+ if ( header[i] == 0 )
+ break;
+ result.append( (char)header[i] );
+ }
+
+ return result;
+ }
+
+ public static int
+ getNameBytes( StringBuffer name, byte[] buf, int offset, int length )
+ {
+ int i;
+
+ for ( i = 0 ; i < length && i < name.length() ; ++i )
+ {
+ buf[ offset + i ] = (byte)name.charAt( i );
+ }
+
+ for ( ; i < length ; ++i )
+ {
+ buf[ offset + i ] = 0;
+ }
+
+ return offset + length;
+ }
+
+ public static int
+ getOctalBytes( long value, byte[] buf, int offset, int length )
+ {
+ byte[] result = new byte[ length ];
+
+ int idx = length - 1;
+
+ buf[ offset + idx ] = 0;
+ --idx;
+ buf[ offset + idx ] = new Byte(" ").byteValue();
+ --idx;
+
+ if ( value == 0 )
+ {
+ buf[ offset + idx ] = new Byte("0").byteValue();
+ --idx;
+ }
+ else
+ {
+ for ( long val = value ; idx >= 0 && val > 0 ; --idx )
+ {
+ buf[ offset + idx ] =
+ (byte) ( '0' + (val & 7) );
+ val = val >> 3;
+ }
+ }
+
+ for ( ; idx >= 0 ; --idx )
+ {
+ buf[ offset + idx ] = new Byte(" ").byteValue();
+ }
+
+ return offset + length;
+ }
+
+ public static int
+ getLongOctalBytes( long value, byte[] buf, int offset, int length )
+ {
+ byte[] temp = new byte[ length + 1 ];
+ TarHeader.getOctalBytes( value, temp, 0, length + 1 );
+ System.arraycopy( temp, 0, buf, offset, length );
+ return offset + length;
+ }
+
+ public static int
+ getCheckSumOctalBytes( long value, byte[] buf, int offset, int length )
+ {
+ TarHeader.getOctalBytes( value, buf, offset, length );
+ buf[ offset + length - 1 ] = new Byte(" ").byteValue();
+ buf[ offset + length - 2 ] = 0;
+ return offset + length;
+ }
+
+ public String
+ getName()
+ {
+ return this.name.toString();
+ }
+
+ }
+
diff --git a/src/main/com/ice/tar/TarProgressDisplay.java b/src/main/com/ice/tar/TarProgressDisplay.java
new file mode 100644
index 000000000..83ac11c5e
--- /dev/null
+++ b/src/main/com/ice/tar/TarProgressDisplay.java
@@ -0,0 +1,32 @@
+/*
+** Copyright (c) 1998 by Timothy Gerard Endres
+**
+**
+** This package is free software.
+**
+** You may redistribute it and/or modify it under the terms of the GNU
+** General Public License as published by the Free Software Foundation.
+** Version 2 of the license should be included with this distribution in
+** the file LICENSE, as well as License.html. If the license is not
+** included with this distribution, you may find a copy at the FSF web
+** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
+** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
+**
+** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
+** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
+** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
+** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
+** REDISTRIBUTION OF THIS SOFTWARE.
+**
+*/
+
+package com.ice.tar;
+
+
+public interface
+TarProgressDisplay
+ {
+ public void
+ showTarProgressMessage( String msg );
+ }
+
diff --git a/src/main/org/apache/tools/ant/AntSecurityManager.java b/src/main/org/apache/tools/ant/AntSecurityManager.java
new file mode 100644
index 000000000..f7897aac6
--- /dev/null
+++ b/src/main/org/apache/tools/ant/AntSecurityManager.java
@@ -0,0 +1,211 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant;
+
+import java.security.*;
+import java.io.*;
+import java.net.*;
+
+/**
+ * The "almost" security manager that allows everything but exit();
+ *
+ * @author stefano@apache.org
+ */
+
+public class AntSecurityManager extends SecurityManager {
+
+ private boolean exit = false;
+
+ public AntSecurityManager() {
+ super();
+ }
+
+ public void setExit(boolean allowExit) {
+ this.exit = allowExit;
+ }
+
+ public void checkExit(int status) {
+ if (!exit) {
+ throw new SecurityException("Not Allowed.");
+ }
+ }
+
+ // everything else should be allowed
+/*
+Removed the following interfaces as they won't compile with JDK 1.1,
+and the defaults for JDK 1.2 appear to be sufficient. If you have
+a problem, let me know. Sam Ruby - rubys@us.ibm.com
+
+ public void checkPermission(Permission perm) {
+ // allowed
+ }
+
+ public void checkPermission(Permission perm, Object context) {
+ // allowed
+ }
+*/
+
+ public void checkCreateClassLoader() {
+ // allowed
+ }
+
+ public void checkAccess(Thread t) {
+ // allowed
+ }
+
+ public void checkAccess(ThreadGroup g) {
+ // allowed
+ }
+
+ public void checkExec(String cmd) {
+ // allowed
+ }
+
+ public void checkLink(String lib) {
+ // allowed
+ }
+
+ public void checkRead(FileDescriptor fd) {
+ // allowed
+ }
+
+ public void checkRead(String file) {
+ // allowed
+ }
+
+ public void checkRead(String file, Object context) {
+ // allowed
+ }
+
+ public void checkWrite(FileDescriptor fd) {
+ // allowed
+ }
+
+ public void checkWrite(String file) {
+ // allowed
+ }
+
+ public void checkDelete(String file) {
+ // allowed
+ }
+
+ public void checkConnect(String host, int port) {
+ // allowed
+ }
+
+ public void checkConnect(String host, int port, Object context) {
+ // allowed
+ }
+
+ public void checkListen(int port) {
+ // allowed
+ }
+
+ public void checkAccept(String host, int port) {
+ // allowed
+ }
+
+ public void checkMulticast(InetAddress maddr) {
+ // allowed
+ }
+
+ public void checkMulticast(InetAddress maddr, byte ttl) {
+ // allowed
+ }
+
+ public void checkPropertiesAccess() {
+ // allowed
+ }
+
+ public void checkPropertyAccess(String key) {
+ // allowed
+ }
+
+ public void checkPrintJobAccess() {
+ // allowed
+ }
+
+ public void checkSystemClipboardAccess() {
+ // allowed
+ }
+
+ public void checkAwtEventQueueAccess() {
+ // allowed
+ }
+
+ public void checkPackageAccess(String pkg) {
+ // allowed
+ }
+
+ public void checkPackageDefinition(String pkg) {
+ // allowed
+ }
+
+ public void checkSetFactory() {
+ // allowed
+ }
+
+ public void checkMemberAccess(Class clazz, int which) {
+ // allowed
+ }
+
+ public void checkSecurityAccess(String target) {
+ // allowed
+ }
+
+ public boolean checkTopLevelWindow(Object window) {
+ return true;
+ }
+}
diff --git a/src/main/org/apache/tools/ant/ApacheParser.java b/src/main/org/apache/tools/ant/ApacheParser.java
new file mode 100644
index 000000000..39d0dc67c
--- /dev/null
+++ b/src/main/org/apache/tools/ant/ApacheParser.java
@@ -0,0 +1,98 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.lang.reflect.Method;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Implementation of Parser using Apache Xerces-J.
+ *
+ * @author pier@apache.org
+ */
+public class ApacheParser extends Parser {
+
+ Class DOMParser = null;
+ Method parse;
+ Method getDocument;
+
+ /**
+ * Parse the specified file and return a DOM Document.
+ */
+ public Document parse(File buildFile)
+ throws SAXException, IOException {
+ try {
+ if (DOMParser == null) {
+ DOMParser = Class.forName("org.apache.xerces.parsers.DOMParser");
+ parse = DOMParser.getMethod("parse", new Class[]{String.class});
+ getDocument = DOMParser.getMethod("getDocument", new Class[]{});
+ }
+
+ Object p=DOMParser.newInstance();
+ URL url=new URL("file","",buildFile.getAbsolutePath());
+ parse.invoke(p, new Object[]{url.toExternalForm()});
+ return(org.w3c.dom.Document)getDocument.invoke(p, new Object[]{});
+ } catch (Exception e) {
+ if (e instanceof IOException) throw (IOException)e;
+ if (e instanceof SAXException) throw (SAXException)e;
+ throw new IOException(e.toString());
+ }
+ }
+}
diff --git a/src/main/org/apache/tools/ant/BuildException.java b/src/main/org/apache/tools/ant/BuildException.java
new file mode 100644
index 000000000..f437d4810
--- /dev/null
+++ b/src/main/org/apache/tools/ant/BuildException.java
@@ -0,0 +1,102 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant;
+
+/**
+ * Signals an error condition.
+ *
+ * @author James Duncan Davidson
+ */
+
+public class BuildException extends RuntimeException {
+
+ /** Exception that might have caused this one */
+ private Exception cause;
+
+ /**
+ * Constructs an exception with no information.
+ */
+
+ public BuildException() {
+ super();
+ }
+
+ /**
+ * Constructs an exception with the given message.
+ */
+
+ public BuildException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Constructs an exception with the given message and exception as
+ * a root cause.
+ */
+
+ public BuildException(String msg, Exception cause) {
+ super(msg);
+ this.cause = cause;
+ }
+
+ /**
+ * Constructs an exception with the given exception as a root cause.
+ */
+
+ public BuildException(Exception cause) {
+ super();
+ this.cause = cause;
+ }
+}
\ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/DesirableFilter.java b/src/main/org/apache/tools/ant/DesirableFilter.java
new file mode 100644
index 000000000..0bd564125
--- /dev/null
+++ b/src/main/org/apache/tools/ant/DesirableFilter.java
@@ -0,0 +1,118 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.FilenameFilter;
+
+/**
+ * Filters filenames to determine whether or not the file is desirable.
+ *
+ * @author Jason Hunter [jhunter@servlets.com]
+ * @author james@x180.com
+ */
+
+public class DesirableFilter implements FilenameFilter {
+
+ /**
+ * Test the given filename to determine whether or not it's desirable.
+ * This helps tasks filter temp files and files used by CVS.
+ */
+
+ public boolean accept(File dir, String name) {
+
+ // emacs save file
+ if (name.endsWith("~")) {
+ return false;
+ }
+
+ // emacs autosave file
+ if (name.startsWith("#") && name.endsWith("#")) {
+ return false;
+ }
+
+ // openwindows text editor does this I think
+ if (name.startsWith("%") && name.endsWith("%")) {
+ return false;
+ }
+
+ /* CVS stuff -- hopefully there won't be a case with
+ * an all cap file/dir named "CVS" that somebody wants
+ * to keep around...
+ */
+
+ if (name.equals("CVS")) {
+ return false;
+ }
+
+ /* If we are going to ignore CVS might as well ignore
+ * this one as well...
+ */
+ if (name.equals(".cvsignore")){
+ return false;
+ }
+
+ // default
+ return true;
+ }
+}
+
+
+
+
+
+
+
diff --git a/src/main/org/apache/tools/ant/Main.java b/src/main/org/apache/tools/ant/Main.java
new file mode 100644
index 000000000..a0d157b62
--- /dev/null
+++ b/src/main/org/apache/tools/ant/Main.java
@@ -0,0 +1,275 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.util.Properties;
+import java.util.Enumeration;
+
+/**
+ * Command line entry point into Ant. This class is entered via the
+ * cannonical `public static void main` entry point and reads the
+ * command line arguments. It then assembles and executes an Ant
+ * project.
+ *
+ * If you integrating Ant into some other tool, this is not the class
+ * to use as an entry point. Please see the source code of this
+ * class to see how it manipulates the Ant project classes.
+ *
+ * @author duncan@x180.com
+ */
+
+public class Main {
+
+ /** Our current message output status. Follows Project.MSG_XXX */
+ private static int msgOutputLevel = Project.MSG_INFO;
+
+ /** File that we are using for configuration */
+ private static File buildFile = new File("build.xml");
+
+ // XXX
+ // Change the targets to use a vector or something. I'm not keen
+ // on the idea of having an artificial limit, even if it isn't
+ // likely that somebody will want to build more than 20 targets.
+
+ private static String targets[] = new String[20];
+ private static int targetCount=0;
+
+ /** Set of properties that can be used by tasks */
+ private static Properties definedProps = new Properties();
+
+ /** The Ant security manager */
+ private static AntSecurityManager securityManager;
+
+ /**
+ * Command line entry point. This method kicks off the building
+ * of a project object and executes a build using either a given
+ * target or the default target.
+ *
+ * @param args Command line args.
+ */
+
+ public static void main(String[] args) {
+
+ // cycle through given args
+
+ for (int i = 0; i < args.length; i++) {
+ String arg = args[i];
+
+ if (arg.equals("-help") || arg.equals("help")) {
+ printUsage();
+ return;
+ } else if (arg.equals("-quiet") || arg.equals("-q") ||
+ arg.equals("q")) {
+ msgOutputLevel = Project.MSG_WARN;
+ } else if (arg.equals("-verbose") || arg.equals("-v") ||
+ arg.equals("v")) {
+ msgOutputLevel = Project.MSG_VERBOSE;
+ } else if (arg.equals("-buildfile") || arg.equals("-file") || arg.equals("-f")) {
+ try {
+ buildFile = new File(args[i+1]);
+ i++;
+ } catch (ArrayIndexOutOfBoundsException aioobe) {
+ String msg = "You must specify a buildfile when " +
+ "using the -buildfile argument";
+ System.out.println(msg);
+ return;
+ }
+ } else if (arg.startsWith("-D")) {
+
+ /* Interestingly enough, we get to here when a user
+ * uses -Dname=value. However, the JDK goes ahead
+ * and parses this out to args {"-Dname", "value"}
+ * so instead of parsing on "=", we just make the "-D"
+ * characters go away and skip one argument forward.
+ */
+
+ String name = arg.substring(2, arg.length());
+ String value = args[++i];
+ definedProps.put(name, value);
+ } else if (arg.startsWith("-")) {
+ // we don't have any more args to recognize!
+ String msg = "Unknown arg: " + arg;
+ System.out.println(msg);
+ printUsage();
+ return;
+ } else {
+ // if it's no other arg, it may be the target
+ targets[targetCount]=arg;
+ targetCount++;
+ }
+ }
+
+ // make sure buildfile exists
+
+ if (!buildFile.exists()) {
+ System.out.println("Buildfile: " + buildFile + " does not exist!");
+ return;
+ }
+
+ // make sure it's not a directory (this falls into the ultra
+ // paranoid lets check everything catagory
+
+ if (buildFile.isDirectory()) {
+ System.out.println("What? Buildfile: " + buildFile + " is a dir!");
+ return;
+ }
+
+ // ok, so if we've made it here, let's run the damn build allready
+ runBuild();
+
+ // se should force the exit() to allow everything to cleanup since
+ // there could be leftover threads running around (some stupid AWT code
+ // used for image generation does this! grrrr)
+ exit(0);
+ }
+
+ /**
+ * Executes the build.
+ */
+
+ private static void runBuild() {
+
+ // track when we started
+
+ long startTime = System.currentTimeMillis();
+ if (msgOutputLevel >= Project.MSG_INFO) {
+ System.out.println("Buildfile: " + buildFile);
+ }
+
+ Project project = new Project();
+ project.setOutputLevel(msgOutputLevel);
+
+ // set user-define properties
+ Enumeration e = definedProps.keys();
+ while (e.hasMoreElements()) {
+ String arg = (String)e.nextElement();
+ String value = (String)definedProps.get(arg);
+ project.setUserProperty(arg, value);
+ }
+
+ // first use the ProjectHelper to create the project object
+ // from the given build file.
+
+ try {
+ ProjectHelper.configureProject(project, buildFile);
+ } catch (BuildException be) {
+ String msg = "BUILD CONFIG ERROR: ";
+ System.out.println(msg + be.getMessage());
+ be.printStackTrace();
+ exit(1);
+ }
+
+ // make sure that we have a target to execute
+
+ if (targetCount == 0) {
+ String target = project.getDefaultTarget();
+ targets[0]=target;
+ targetCount=1;
+ }
+
+ // set the security manager
+ securityManager = new AntSecurityManager();
+ System.setSecurityManager(securityManager);
+
+ // actually do some work
+ try {
+ for(int i=0; i< targetCount; i++)
+ project.executeTarget(targets[i]);
+ } catch (BuildException be) {
+ String msg = "BUILD FATAL ERROR: ";
+ System.out.println(msg + be.getMessage());
+ if (msgOutputLevel > Project.MSG_INFO) {
+ be.printStackTrace();
+ }
+ exit(1);
+ }
+
+ // track our stop time and let the user know how long things
+ // took.
+
+ long finishTime = System.currentTimeMillis();
+ long elapsedTime = finishTime - startTime;
+ if (msgOutputLevel >= Project.MSG_INFO) {
+ System.out.println("Completed in " + (elapsedTime/1000)
+ + " seconds");
+ }
+ }
+
+ /**
+ * Prints the usage of how to use this class to System.out
+ */
+
+ private static void printUsage() {
+ String lSep = System.getProperty("line.separator");
+ StringBuffer msg = new StringBuffer();
+ msg.append("ant [options] [target]" + lSep);
+ msg.append("Options: " + lSep);
+ msg.append(" -help print this message" + lSep);
+ msg.append(" -quiet be extra quiet" + lSep);
+ msg.append(" -verbose be extra verbose" + lSep);
+ msg.append(" -buildfile use given buildfile" + lSep);
+ msg.append(" -D= use value for given property"
+ + lSep);
+ System.out.println(msg.toString());
+ }
+
+ private static void exit(int code) {
+ securityManager.setExit(true);
+ System.exit(code);
+ }
+}
diff --git a/src/main/org/apache/tools/ant/Map.java b/src/main/org/apache/tools/ant/Map.java
new file mode 100644
index 000000000..74907ce2a
--- /dev/null
+++ b/src/main/org/apache/tools/ant/Map.java
@@ -0,0 +1,62 @@
+
+
+package org.apache.tools.ant;
+import java.util.*;
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+public interface Map {
+
+ public Object get( Object key );
+}
diff --git a/src/main/org/apache/tools/ant/Parser.java b/src/main/org/apache/tools/ant/Parser.java
new file mode 100644
index 000000000..b25fbcd48
--- /dev/null
+++ b/src/main/org/apache/tools/ant/Parser.java
@@ -0,0 +1,111 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.Properties;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * Dummy parser abstraction class for ANT to be used until the Java API for
+ * XML Parsing are released.
+ *
+ * @author pier@apache.org
+ */
+public abstract class Parser {
+ // The properties file to be loaded
+ private static String properties="org/apache/tools/ant/parser.properties";
+
+ /**
+ * Create a working instance of a parser
+ */
+ public static Parser getParser(Project project)
+ throws BuildException {
+ InputStream in=project.getClass().getResourceAsStream("parser.properties");
+ if (in==null) throw new BuildException("Cannot find properties file");
+
+ String name;
+ try {
+ Properties prop=new Properties();
+ prop.load(in);
+ name=prop.getProperty("parser");
+ if (name==null) throw new BuildException("Parser name not found");
+ } catch(IOException e) {
+ throw new BuildException("Cannot load properties file");
+ }
+ try {
+ return((Parser)Class.forName(name).newInstance());
+ } catch (ClassNotFoundException e) {
+ throw new BuildException("Class "+name+" cannot be found");
+ } catch (InstantiationException e) {
+ throw new BuildException("Class "+name+" cannot be instantiated");
+ } catch (IllegalAccessException e) {
+ throw new BuildException("Class "+name+" cannot be accessed");
+ } catch (ClassCastException e) {
+ throw new BuildException("Class "+name+" doesn't extend Parser");
+ }
+ }
+
+ /**
+ * Parse the specified file and return a DOM Document.
+ */
+ public abstract Document parse(File f)
+ throws SAXException, IOException;
+}
+
+
diff --git a/src/main/org/apache/tools/ant/Project.java b/src/main/org/apache/tools/ant/Project.java
new file mode 100644
index 000000000..daecab6f9
--- /dev/null
+++ b/src/main/org/apache/tools/ant/Project.java
@@ -0,0 +1,601 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.Stack;
+import java.text.StringCharacterIterator;
+import java.text.CharacterIterator;
+
+/**
+ * Central representation of an Ant project. This class defines a
+ * Ant project with all of it's targets and tasks. It also provides
+ * the mechanism to kick off a build using a particular target name.
+ *
+ * This class also encapsulates methods which allow Files to be refered
+ * to using abstract path names which are translated to native system
+ * file paths at runtime as well as defining various project properties.
+ *
+ * @author duncan@x180.com
+ */
+
+public class Project {
+
+ public static final int MSG_ERR = 0;
+ public static final int MSG_WARN = 1;
+ public static final int MSG_INFO = 2;
+ public static final int MSG_VERBOSE = 3;
+
+ private static String javaVersion;
+ // private set of constants to represent the state
+ // of a DFS of the Target dependencies
+ private static final String VISITING = "VISITING";
+ private static final String VISITED = "VISITED";
+
+ private String name;
+ private PrintStream out = System.out;
+ private int msgOutputLevel = MSG_INFO;
+
+ private Hashtable properties = new Hashtable();
+ private Hashtable userProperties = new Hashtable();
+ private String defaultTarget;
+ private Hashtable taskClassDefinitions = new Hashtable();
+ private Hashtable targets = new Hashtable();
+ private File baseDir;
+
+ public Project() {
+ detectJavaVersion();
+ String defs = "/org/apache/tools/ant/taskdefs/defaults.properties";
+ try {
+ Properties props = new Properties();
+ InputStream in = this.getClass()
+ .getResourceAsStream(defs);
+ props.load(in);
+ in.close();
+ Enumeration enum = props.propertyNames();
+ while (enum.hasMoreElements()) {
+ String key = (String)enum.nextElement();
+ String value = props.getProperty(key);
+ try {
+ Class taskClass = Class.forName(value);
+ addTaskDefinition(key, taskClass);
+ } catch (ClassNotFoundException cnfe) {
+ // ignore...
+ }
+ }
+
+ Properties systemP=System.getProperties();
+ Enumeration e=systemP.keys();
+ while( e.hasMoreElements() ) {
+ String n=(String) e.nextElement();
+ properties.put( n, systemP.get(n));
+ }
+ } catch (IOException ioe) {
+ String msg = "Can't load default task list";
+ System.out.println(msg);
+ System.exit(1);
+ }
+ }
+
+ public void setOutput(PrintStream out) {
+ this.out = out;
+ }
+
+ public void setOutputLevel(int msgOutputLevel) {
+ this.msgOutputLevel = msgOutputLevel;
+ }
+ public int getOutputLevel() {
+ return this.msgOutputLevel;
+ }
+
+ public void log(String msg) {
+ log(msg, MSG_INFO);
+ }
+
+ public void log(String msg, int msgLevel) {
+ if (msgLevel <= msgOutputLevel) {
+ out.println(msg);
+ }
+ }
+
+ public void log(String msg, String tag, int msgLevel) {
+ if (msgLevel <= msgOutputLevel) {
+ out.println("[" + tag + "]" + msg);
+ }
+ }
+
+ public void setProperty(String name, String value) {
+ // command line properties take precedence
+ if( null!= userProperties.get(name))
+ return;
+ log("Setting project property: " + name + " to " +
+ value, MSG_VERBOSE);
+ properties.put(name, value);
+ }
+
+ public void setUserProperty(String name, String value) {
+ log("Setting project property: " + name + " to " +
+ value, MSG_VERBOSE);
+ userProperties.put(name, value);
+ properties.put( name,value);
+ }
+
+ public String getProperty(String name) {
+ String property = (String)properties.get(name);
+ return property;
+ }
+
+ public Hashtable getProperties() {
+ return properties;
+ }
+
+ public void setDefaultTarget(String defaultTarget) {
+ this.defaultTarget = defaultTarget;
+ }
+
+ // deprecated, use setDefault
+ public String getDefaultTarget() {
+ return defaultTarget;
+ }
+
+ // match the attribute name
+ public void setDefault(String defaultTarget) {
+ this.defaultTarget = defaultTarget;
+ }
+
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ // match basedir attribute in xml
+ public void setBasedir( String baseD ) throws BuildException {
+ try {
+ setBaseDir(new File( new File(baseD).getCanonicalPath()));
+ } catch (IOException ioe) {
+ String msg = "Can't set basedir " + baseDir + " due to " +
+ ioe.getMessage();
+ throw new BuildException(msg);
+ }
+ }
+
+ public void setBaseDir(File baseDir) {
+ this.baseDir = baseDir;
+ String msg = "Project base dir set to: " + baseDir;
+ log(msg, MSG_INFO);
+ }
+
+ public File getBaseDir() {
+ if(baseDir==null) {
+ try {
+ setBasedir(".");
+ } catch(BuildException ex) {ex.printStackTrace();}
+ }
+ return baseDir;
+ }
+
+
+ public static String getJavaVersion() {
+ return javaVersion;
+ }
+
+ private void detectJavaVersion() {
+
+ // Determine the Java version by looking at available classes
+ // java.lang.StrictMath was introduced in JDK 1.3
+ // java.lang.ThreadLocal was introduced in JDK 1.2
+ // java.lang.Void was introduced in JDK 1.1
+ // Count up version until a NoClassDefFoundError ends the try
+
+ try {
+ javaVersion = "1.0";
+ Class.forName("java.lang.Void");
+ javaVersion = "1.1";
+ Class.forName("java.lang.ThreadLocal");
+ javaVersion = "1.2";
+ Class.forName("java.lang.StrictMath");
+ javaVersion = "1.3";
+ setProperty("ant.java.version", javaVersion);
+ }
+ catch (ClassNotFoundException cnfe) {
+ // swallow as we've hit the max class version that
+ // we have
+ }
+ log("Detected Java Version: " + javaVersion);
+ }
+
+ public void addTaskDefinition(String taskName, Class taskClass) {
+ String msg = " +User task: " + taskName + " " + taskClass.getName();
+ log(msg, MSG_VERBOSE);
+ taskClassDefinitions.put(taskName, taskClass);
+ }
+
+ /**
+ * This call expects to add a new Target.
+ * @param target is the Target to be added to the current
+ * Project.
+ * @exception BuildException if the Target already exists
+ * in the project.
+ * @see Project#addOrReplaceTarget to replace existing Targets.
+ */
+ public void addTarget(Target target) {
+ String name = target.getName();
+ if (targets.get(name) != null) {
+ throw new BuildException("Duplicate target: `"+name+"'");
+ }
+ addOrReplaceTarget(name, target);
+ }
+
+ /**
+ * This call expects to add a new Target.
+ * @param target is the Target to be added to the current
+ * Project.
+ * @param targetName is the name to use for the Target
+ * @exception BuildException if the Target already exists
+ * in the project.
+ * @see Project#addOrReplaceTarget to replace existing Targets.
+ */
+ public void addTarget(String targetName, Target target)
+ throws BuildException {
+ if (targets.get(targetName) != null) {
+ throw new BuildException("Duplicate target: `"+targetName+"'");
+ }
+ addOrReplaceTarget(targetName, target);
+ }
+
+ /**
+ * @param target is the Target to be added or replaced in
+ * the current Project.
+ */
+ public void addOrReplaceTarget(Target target) {
+ addOrReplaceTarget(target.getName(), target);
+ }
+
+ /**
+ * @param target is the Target to be added/replaced in
+ * the current Project.
+ * @param targetName is the name to use for the Target
+ */
+ public void addOrReplaceTarget(String targetName, Target target) {
+ String msg = " +Target: " + targetName;
+ log(msg, MSG_VERBOSE);
+ targets.put(targetName, target);
+ }
+
+ public Task createTask(String taskType) throws BuildException {
+ Class c = (Class)taskClassDefinitions.get(taskType);
+
+ // XXX
+ // check for nulls, other sanity
+
+ try {
+ Task task = (Task)c.newInstance();
+ task.setProject(this);
+ String msg = " +Task: " + taskType;
+ log (msg, MSG_VERBOSE);
+ return task;
+ } catch (Exception e) {
+ String msg = "Could not create task of type: "
+ + taskType + " due to " + e;
+ throw new BuildException(msg);
+ }
+ }
+
+ public void executeTarget(String targetName) throws BuildException {
+
+ // sanity check ourselves, if we've been asked to build nothing
+ // then we should complain
+
+ if (targetName == null) {
+ String msg = "No target specified";
+ throw new BuildException(msg);
+ }
+
+ // Sort the dependency tree, and run everything from the
+ // beginning until we hit our targetName.
+ // Sorting checks if all the targets (and dependencies)
+ // exist, and if there is any cycle in the dependency
+ // graph.
+ Vector sortedTargets = topoSort(targetName, targets);
+
+ int curidx = 0;
+ String curtarget;
+
+ do {
+ curtarget = (String) sortedTargets.elementAt(curidx++);
+ runTarget(curtarget, targets);
+ } while (!curtarget.equals(targetName));
+ }
+
+ public File resolveFile(String fileName) {
+ // deal with absolute files
+ if (fileName.startsWith("/")) return new File( fileName );
+
+ // Eliminate consecutive slashes after the drive spec
+ if (fileName.length() >= 2 &&
+ Character.isLetter(fileName.charAt(0)) &&
+ fileName.charAt(1) == ':') {
+ char[] ca = fileName.replace('/', '\\').toCharArray();
+ char c;
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < ca.length; i++) {
+ if ((ca[i] != '\\') ||
+ (ca[i] == '\\' &&
+ i > 0 &&
+ ca[i - 1] != '\\')) {
+ if (i == 0 &&
+ Character.isLetter(ca[i]) &&
+ i < ca.length - 1 &&
+ ca[i + 1] == ':') {
+ c = Character.toUpperCase(ca[i]);
+ } else {
+ c = ca[i];
+ }
+
+ sb.append(c);
+ }
+ }
+
+ return new File(sb.toString());
+ }
+
+ File file = new File(baseDir.getAbsolutePath());
+ StringTokenizer tok = new StringTokenizer(fileName, "/", false);
+ while (tok.hasMoreTokens()) {
+ String part = tok.nextToken();
+ if (part.equals("..")) {
+ file = new File(file.getParent());
+ } else if (part.equals(".")) {
+ // Do nothing here
+ } else {
+ file = new File(file, part);
+ }
+ }
+
+ try {
+ return new File(file.getCanonicalPath());
+ }
+ catch (IOException e) {
+ log("IOException getting canonical path for " + file + ": " +
+ e.getMessage(), MSG_ERR);
+ return new File(file.getAbsolutePath());
+ }
+ }
+
+ /**
+ Translate a path into its native (platform specific)
+ path. This should be extremely fast, code is
+ borrowed from ECS project.
+
+ All it does is translate the : into ; and / into \
+ if needed. In other words, it isn't perfect.
+
+ @returns translated string or empty string if to_process is null or empty
+ @author Jon S. Stevens jon@clearink.com
+ */
+ public static String translatePath(String to_process) {
+ if ( to_process == null || to_process.length() == 0 )
+ return "";
+
+ StringBuffer bs = new StringBuffer(to_process.length() + 50);
+ StringCharacterIterator sci = new StringCharacterIterator(to_process);
+ String path = System.getProperty("path.separator");
+ String file = System.getProperty("file.separator");
+ String tmp = null;
+ for (char c = sci.first(); c != CharacterIterator.DONE; c = sci.next()) {
+ tmp = String.valueOf(c);
+
+ if (tmp.equals(":")) {
+ // could be a DOS drive or a Unix path separator...
+ // if followed by a backslash, assume it is a drive
+ c = sci.next();
+ tmp = String.valueOf(c);
+ bs.append( tmp.equals("\\") ? ":" : path );
+ if (c == CharacterIterator.DONE) break;
+ }
+
+ if (tmp.equals(":") || tmp.equals(";"))
+ tmp = path;
+ else if (tmp.equals("/") || tmp.equals ("\\"))
+ tmp = file;
+ bs.append(tmp);
+ }
+ return(bs.toString());
+ }
+
+ // Given a string defining a target name, and a Hashtable
+ // containing the "name to Target" mapping, pick out the
+ // Target and execute it.
+ private final void runTarget(String target, Hashtable targets)
+ throws BuildException {
+ Target t = (Target)targets.get(target);
+ if (t == null) {
+ throw new RuntimeException("Unexpected missing target `"+target+
+ "' in this project.");
+ }
+ log("Executing Target: "+target, MSG_INFO);
+ t.execute();
+ }
+
+
+ /**
+ * Topologically sort a set of Targets.
+ * @param root is the (String) name of the root Target. The sort is
+ * created in such a way that the sequence of Targets uptil the root
+ * target is the minimum possible such sequence.
+ * @param targets is a Hashtable representing a "name to Target" mapping
+ * @return a Vector of Strings with the names of the targets in
+ * sorted order.
+ * @exception BuildException if there is a cyclic dependency among the
+ * Targets, or if a Target does not exist.
+ */
+ private final Vector topoSort(String root, Hashtable targets)
+ throws BuildException {
+ Vector ret = new Vector();
+ Hashtable state = new Hashtable();
+ Stack visiting = new Stack();
+
+ // We first run a DFS based sort using the root as the starting node.
+ // This creates the minimum sequence of Targets to the root node.
+ // We then do a sort on any remaining unVISITED targets.
+ // This is unnecessary for doing our build, but it catches
+ // circular dependencies or missing Targets on the entire
+ // dependency tree, not just on the Targets that depend on the
+ // build Target.
+
+ tsort(root, targets, state, visiting, ret);
+ log("Build sequence for target `"+root+"' is "+ret, MSG_VERBOSE);
+ for (Enumeration en=targets.keys(); en.hasMoreElements();) {
+ String curTarget = (String)(en.nextElement());
+ String st = (String) state.get(curTarget);
+ if (st == null) {
+ tsort(curTarget, targets, state, visiting, ret);
+ }
+ else if (st == VISITING) {
+ throw new RuntimeException("Unexpected node in visiting state: "+curTarget);
+ }
+ }
+ log("Complete build sequence is "+ret, MSG_VERBOSE);
+ return ret;
+ }
+
+ // one step in a recursive DFS traversal of the Target dependency tree.
+ // - The Hashtable "state" contains the state (VISITED or VISITING or null)
+ // of all the target names.
+ // - The Stack "visiting" contains a stack of target names that are
+ // currently on the DFS stack. (NB: the target names in "visiting" are
+ // exactly the target names in "state" that are in the VISITING state.)
+ // 1. Set the current target to the VISITING state, and push it onto
+ // the "visiting" stack.
+ // 2. Throw a BuildException if any child of the current node is
+ // in the VISITING state (implies there is a cycle.) It uses the
+ // "visiting" Stack to construct the cycle.
+ // 3. If any children have not been VISITED, tsort() the child.
+ // 4. Add the current target to the Vector "ret" after the children
+ // have been visited. Move the current target to the VISITED state.
+ // "ret" now contains the sorted sequence of Targets upto the current
+ // Target.
+
+ private final void tsort(String root, Hashtable targets,
+ Hashtable state, Stack visiting,
+ Vector ret)
+ throws BuildException {
+ state.put(root, VISITING);
+ visiting.push(root);
+
+ Target target = (Target)(targets.get(root));
+
+ // Make sure we exist
+ if (target == null) {
+ StringBuffer sb = new StringBuffer("Target `");
+ sb.append(root);
+ sb.append("' does not exist in this project. ");
+ visiting.pop();
+ if (!visiting.empty()) {
+ String parent = (String)visiting.peek();
+ sb.append("It is used from target `");
+ sb.append(parent);
+ sb.append("'.");
+ }
+
+ throw new BuildException(new String(sb));
+ }
+
+ for (Enumeration en=target.getDependencies(); en.hasMoreElements();) {
+ String cur = (String) en.nextElement();
+ String m=(String)state.get(cur);
+ if (m == null) {
+ // Not been visited
+ tsort(cur, targets, state, visiting, ret);
+ }
+ else if (m == VISITING) {
+ // Currently visiting this node, so have a cycle
+ throw makeCircularException(cur, visiting);
+ }
+ }
+
+ String p = (String) visiting.pop();
+ if (root != p) {
+ throw new RuntimeException("Unexpected internal error: expected to pop "+root+" but got "+p);
+ }
+ state.put(root, VISITED);
+ ret.addElement(root);
+ }
+
+ private static BuildException makeCircularException(String end, Stack stk) {
+ StringBuffer sb = new StringBuffer("Circular dependency: ");
+ sb.append(end);
+ String c;
+ do {
+ c = (String)stk.pop();
+ sb.append(" <- ");
+ sb.append(c);
+ } while(!c.equals(end));
+ return new BuildException(new String(sb));
+ }
+}
diff --git a/src/main/org/apache/tools/ant/ProjectHelper.java b/src/main/org/apache/tools/ant/ProjectHelper.java
new file mode 100644
index 000000000..6f4d43574
--- /dev/null
+++ b/src/main/org/apache/tools/ant/ProjectHelper.java
@@ -0,0 +1,356 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant;
+
+import java.beans.*;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.*;
+import java.util.*;
+import org.xml.sax.SAXException;
+import org.w3c.dom.*;
+
+/**
+ * Configures a Project (complete with Targets and Tasks) based on
+ * a XML build file.
+ *
+ * @author duncan@x180.com
+ */
+
+public class ProjectHelper {
+
+ public static void configureProject(Project project, File buildFile)
+ throws BuildException
+ {
+
+ // XXX
+ // need to get rid of the DOM layer and use SAX
+
+ Document doc;
+
+ try {
+ doc=Parser.getParser(project).parse(buildFile);
+ } catch (IOException ioe) {
+ String msg = "Can't open config file: " + buildFile +
+ " due to: " + ioe;
+ throw new BuildException(msg);
+ } catch (SAXException se) {
+ String msg = "Can't open config file: " + buildFile +
+ " due to: " + se;
+ throw new BuildException(msg);
+ }
+
+ Element root = doc.getDocumentElement();
+
+ // sanity check, make sure that we have the right element
+ // as we aren't validating the input
+
+ if (!root.getTagName().equals("project")) {
+ String msg = "Config file is not of expected XML type";
+ throw new BuildException(msg);
+ }
+
+ project.setName(root.getAttribute("name"));
+ project.setDefaultTarget(root.getAttribute("default"));
+
+ String baseDir = project.getProperty("basedir");
+ if (baseDir == null) {
+ baseDir = root.getAttribute("basedir");
+ if (baseDir.equals("")) {
+ // Using clunky JDK1.1 methods here
+ baseDir = new File(buildFile.getAbsolutePath()).getParent();
+ }
+ }
+ project.setBasedir(baseDir);
+
+ // set up any properties that may be in the config file
+
+ // configureProperties(project, root);
+
+ // set up any task defs that may be in the config file
+
+ // configureTaskDefs(project, root);
+
+ // set up the targets into the project
+ init(project, root );
+ configureTargets(project, root);
+ }
+
+ /** Read and execute init - all other targets will be loaded after ( to
+ * make sure all properties are set ).
+ *
+ */
+ private static void init(Project project, Element root)
+ throws BuildException
+ {
+ // Hack - all tasks outside init target will be added to init
+ // ( will be removed when / if build.xml will start using init )
+ Target initTarget = new Target();
+ initTarget.setProject(project);
+ initTarget.setName( "init" );
+ project.addTarget( "init", initTarget );
+ configureTasks( project, initTarget, root );
+
+ NodeList list = root.getElementsByTagName("target");
+ for (int i = 0; i < list.getLength(); i++) {
+ Element element = (Element)list.item(i);
+ String targetName = element.getAttribute("name");
+
+ if( targetName.equals("init") )
+ configureTasks(project, initTarget, element);
+ }
+ initTarget.execute();
+ }
+
+ private static void configureTargets(Project project, Element root)
+ throws BuildException
+ {
+ // configure targets
+ NodeList list = root.getElementsByTagName("target");
+ for (int i = 0; i < list.getLength(); i++) {
+ Element element = (Element)list.item(i);
+ String targetName = element.getAttribute("name");
+ String targetDep = element.getAttribute("depends");
+
+ // all targets must have a name
+ if (targetName.equals("")) {
+ String msg = "target element appears without a name attribute";
+ throw new BuildException(msg);
+ }
+
+ // init is done already
+ if( targetName.equals("init") )
+ continue;
+
+ Target target = new Target();
+ target.setName(targetName);
+ project.addTarget(targetName, target);
+
+ // take care of dependencies
+
+ if (targetDep.length() > 0) {
+ StringTokenizer tok =
+ new StringTokenizer(targetDep, ",", false);
+ while (tok.hasMoreTokens()) {
+ target.addDependency(tok.nextToken().trim());
+ }
+ }
+
+ // populate target with tasks
+
+ configureTasks(project, target, element);
+ }
+ }
+
+ private static void configureTasks(Project project,
+ Target target,
+ Element targetElement)
+ throws BuildException
+ {
+ NodeList list = targetElement.getChildNodes();
+ for (int i = 0; i < list.getLength(); i++) {
+ Node node = list.item(i);
+
+ // right now, all we are interested in is element nodes
+ // not quite sure what to do with others except drop 'em
+
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ Element element = (Element)node;
+ String taskType = element.getTagName();
+
+ // special case - no target in a target.
+ // hack to allow this method to set "init" target
+ // using root element
+ if( ! taskType.equals( "target" ) ) {
+ // XXX
+ // put in some sanity checking
+
+ Task task = project.createTask(taskType);
+
+ // get the attributes of this element and reflect them
+ // into the task
+
+ NamedNodeMap nodeMap = element.getAttributes();
+ configureTask(project, task, nodeMap);
+ target.addTask(task);
+ }
+ }
+ }
+ }
+
+ private static void configureTask(Project project,
+ Task task,
+ NamedNodeMap nodeMap)
+ throws BuildException
+ {
+ // XXX
+ // instead of doing this introspection each time around, I
+ // should have a helper class to keep this info around for
+ // each kind of class
+
+ Hashtable propertySetters = new Hashtable();
+ BeanInfo beanInfo;
+ try {
+ beanInfo = Introspector.getBeanInfo(task.getClass());
+ } catch (IntrospectionException ie) {
+ String msg = "Can't introspect task class: " + task.getClass();
+ throw new BuildException(msg);
+ }
+
+ PropertyDescriptor[] pda = beanInfo.getPropertyDescriptors();
+ for (int i = 0; i < pda.length; i++) {
+ PropertyDescriptor pd = pda[i];
+ String property = pd.getName();
+ Method setMethod = pd.getWriteMethod();
+ if (setMethod != null) {
+
+ // make sure that there's only 1 param and that it
+ // takes a String object, all other setMethods need
+ // to get screened out
+
+ Class[] ma =setMethod.getParameterTypes();
+ if (ma.length == 1) {
+ Class c = ma[0];
+ if (c.getName().equals("java.lang.String")) {
+ propertySetters.put(property, setMethod);
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < nodeMap.getLength(); i++) {
+ Node node = nodeMap.item(i);
+
+ // these should only be attribs, we won't see anything
+ // else here.
+
+ if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+ Attr attr = (Attr)node;
+
+ // reflect these into the task
+
+ Method setMethod = (Method)propertySetters.get(attr.getName());
+ if (setMethod == null) {
+ String msg = "Configuration property \"" + attr.getName() +
+ "\" does not have a setMethod in " + task.getClass();
+ throw new BuildException(msg);
+ }
+
+ String value=replaceProperties( attr.getValue(), project.getProperties() );
+ try {
+ setMethod.invoke(task, new String[] {value});
+ } catch (IllegalAccessException iae) {
+ String msg = "Error setting value for attrib: " +
+ attr.getName();
+ iae.printStackTrace();
+ throw new BuildException(msg);
+ } catch (InvocationTargetException ie) {
+ String msg = "Error setting value for attrib: " +
+ attr.getName() + " in " + task.getClass().getName();
+ ie.printStackTrace();
+ ie.getTargetException().printStackTrace();
+ throw new BuildException(msg);
+ }
+ }
+ }
+ }
+
+ /** Replace ${NAME} with the property value
+ */
+ public static String replaceProperties( String value, Hashtable keys )
+ throws BuildException
+ {
+ // XXX use Map instead of proj, it's too heavy
+
+ // XXX need to replace this code with something better.
+ StringBuffer sb=new StringBuffer();
+ int i=0;
+ int prev=0;
+ // assert value!=nil
+ int pos;
+ while( (pos=value.indexOf( "$", prev )) >= 0 ) {
+ if(pos>0)
+ sb.append( value.substring( prev, pos ) );
+ if( value.charAt( pos + 1 ) != '{' ) {
+ sb.append( value.charAt( pos + 1 ) );
+ prev=pos+2; // XXX
+ } else {
+ int endName=value.indexOf( '}', pos );
+ if( endName < 0 ) {
+ throw new BuildException("Syntax error in prop: " +
+ value );
+ }
+ String n=value.substring( pos+2, endName );
+ String v=(String) keys.get( n );
+ //System.out.println("N: " + n + " " + " V:" + v);
+ sb.append( v );
+ prev=endName+1;
+ }
+ }
+ if( prev < value.length() ) sb.append( value.substring( prev ) );
+ // System.out.println("After replace: " + sb.toString());
+ // System.out.println("Before replace: " + value);
+ return sb.toString();
+ }
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/main/org/apache/tools/ant/SunParser.java b/src/main/org/apache/tools/ant/SunParser.java
new file mode 100644
index 000000000..2c68d1ade
--- /dev/null
+++ b/src/main/org/apache/tools/ant/SunParser.java
@@ -0,0 +1,81 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.IOException;
+import com.sun.xml.parser.Resolver;
+import com.sun.xml.tree.XmlDocument;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Implementation of Parser using Sun ProjectX.
+ *
+ * @author pier@apache.org
+ */
+public class SunParser extends Parser {
+ /**
+ * Parse the specified file and return a DOM Document.
+ */
+ public Document parse(File buildFile)
+ throws SAXException, IOException {
+ InputSource input = Resolver.createInputSource(buildFile);
+ return XmlDocument.createXmlDocument(input, false);
+ }
+}
+
+
\ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/Target.java b/src/main/org/apache/tools/ant/Target.java
new file mode 100644
index 000000000..23266e88e
--- /dev/null
+++ b/src/main/org/apache/tools/ant/Target.java
@@ -0,0 +1,126 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant;
+
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.StringTokenizer;
+
+/**
+ *
+ *
+ * @author duncan@x180.com
+ */
+
+public class Target {
+
+ private String name;
+ private Vector dependencies = new Vector();
+ private Vector tasks = new Vector();
+ Project project;
+
+ public void setProject( Project project) {
+ this.project=project;
+ }
+
+ public Project getProject() {
+ return project;
+ }
+
+ public void setDepends( String depS ) {
+ if (depS.length() > 0) {
+ StringTokenizer tok =
+ new StringTokenizer(depS, ",", false);
+ while (tok.hasMoreTokens()) {
+ addDependency(tok.nextToken().trim());
+ }
+ }
+ }
+
+ public void setAttribute(String name, Object value) {
+ // XXX
+ if( value instanceof Task)
+ addTask( (Task)value);
+
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void addTask(Task task) {
+ tasks.addElement(task);
+ }
+
+ public void addDependency(String dependency) {
+ dependencies.addElement(dependency);
+ }
+
+ public Enumeration getDependencies() {
+ return dependencies.elements();
+ }
+
+ public void execute() throws BuildException {
+ Enumeration enum = tasks.elements();
+ while (enum.hasMoreElements()) {
+ Task task = (Task)enum.nextElement();
+ task.execute();
+ }
+ }
+}
diff --git a/src/main/org/apache/tools/ant/Task.java b/src/main/org/apache/tools/ant/Task.java
new file mode 100644
index 000000000..daee18085
--- /dev/null
+++ b/src/main/org/apache/tools/ant/Task.java
@@ -0,0 +1,155 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * Base class for all tasks in the
+ *
+ * @author duncan@x180.com
+ */
+
+public abstract class Task {
+
+ protected Project project = null;
+ Target target;
+
+ /**
+ * Sets the project object of this task. This method is used by
+ * project when a task is added to it so that the task has
+ * access to the functions of the project. It should not be used
+ * for any other purpose.
+ *
+ * @param project Project in whose scope this task belongs.
+ */
+
+ void setProject(Project project) {
+ this.project = project;
+ }
+
+ public void setAttribute( String name, Object v) {
+ if("target".equals( name ) ) {
+ Target t=(Target)v;
+ target=t;
+ project=t.getProject();
+ return;
+ }
+ // System.out.println("Set Att " +name + " = " + v );
+ // if( v!=null) System.out.println(v.getClass());
+ }
+
+ /**
+ * Called by the project to let the task do it's work.
+ *
+ * @throws BuildException if someting goes wrong with the build
+ */
+
+ public abstract void execute() throws BuildException;
+
+ /**
+ * Convienence method to copy a file from a source to a destination
+ *
+ * @throws IOException
+ */
+
+ protected void copyFile(String sourceFile, String destFile)
+ throws IOException
+ {
+ copyFile(new File(sourceFile), new File(destFile));
+ }
+
+ /**
+ * Convienence method to copy a file from a source to a destination.
+ *
+ * @throws IOException
+ */
+
+ protected void copyFile(File sourceFile,File destFile) throws IOException {
+
+ if (destFile.lastModified() < sourceFile.lastModified()) {
+ project.log("Copy: " + sourceFile.getAbsolutePath() + " > "
+ + destFile.getAbsolutePath(), project.MSG_VERBOSE);
+
+ // ensure that parent dir of dest file exists!
+ // not using getParentFile method to stay 1.1 compat
+
+ File parent = new File(destFile.getParent());
+ if (!parent.exists()) {
+ parent.mkdirs();
+ }
+
+ // open up streams and copy using a decent buffer
+
+ FileInputStream in = new FileInputStream(sourceFile);
+ FileOutputStream out = new FileOutputStream(destFile);
+ byte[] buffer = new byte[8 * 1024];
+ int count = 0;
+ do {
+ out.write(buffer, 0, count);
+ count = in.read(buffer, 0, buffer.length);
+ } while (count != -1);
+ in.close();
+ out.close();
+ }
+ }
+}
+
diff --git a/src/main/org/apache/tools/ant/defaultManifest.mf b/src/main/org/apache/tools/ant/defaultManifest.mf
new file mode 100644
index 000000000..9d885be53
--- /dev/null
+++ b/src/main/org/apache/tools/ant/defaultManifest.mf
@@ -0,0 +1 @@
+Manifest-Version: 1.0
diff --git a/src/main/org/apache/tools/ant/parser.properties b/src/main/org/apache/tools/ant/parser.properties
new file mode 100644
index 000000000..10716a480
--- /dev/null
+++ b/src/main/org/apache/tools/ant/parser.properties
@@ -0,0 +1 @@
+parser=org.apache.tools.ant.SunParser
\ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/taskdefs/Ant.java b/src/main/org/apache/tools/ant/taskdefs/Ant.java
new file mode 100644
index 000000000..be11f2e54
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Ant.java
@@ -0,0 +1,114 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Call Ant in a sub-project
+ *
+ * @author costin@dnt.ro
+ */
+public class Ant extends Task {
+
+ private String dir = null;
+ private String antFile = null;
+ private String target = null;
+
+ /**
+ * Do the execution.
+ */
+ public void execute() throws BuildException {
+ Project p1=new Project();
+ p1.setOutputLevel( project.getOutputLevel() );
+
+ // set user-define properties
+ Hashtable prop1=project.getProperties();
+ Enumeration e = prop1.keys();
+ while (e.hasMoreElements()) {
+ String arg = (String)e.nextElement();
+ String value = (String)prop1.get(arg);
+ p1.setUserProperty(arg, value);
+ }
+
+ p1.setBasedir( dir );
+ p1.setUserProperty( "basedir" , dir);
+ if(antFile==null) antFile= dir + "/build.xml";
+ ProjectHelper.configureProject(p1, new File(antFile));
+
+ if (target == null) {
+ target = p1.getDefaultTarget();
+ }
+
+ p1.executeTarget( target );
+
+ }
+
+ public void setDir(String d) {
+ this.dir = d;
+ }
+
+ public void setAntfile(String s) {
+ this.antFile = s;
+ }
+
+ public void setTarget(String s) {
+ this.target = s;
+ }
+
+
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Chmod.java b/src/main/org/apache/tools/ant/taskdefs/Chmod.java
new file mode 100644
index 000000000..2de2f1895
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Chmod.java
@@ -0,0 +1,91 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ *
+ *
+ * @author costin@eng.sun.com
+ */
+
+public class Chmod extends Task {
+
+ private File srcFile;
+ private String mod;
+
+ public void setSrc(String src) {
+ srcFile = project.resolveFile(src);
+ }
+
+ public void setPerm(String perm) {
+ mod=perm;
+ }
+
+ public void execute() throws BuildException {
+ try {
+ // XXX if OS=unix
+ if (System.getProperty("path.separator").equals(":"))
+ Runtime.getRuntime().exec("chmod " + mod + " " + srcFile );
+ } catch (IOException ioe) {
+ // ignore, but warn
+ System.out.println("Error chmod" + ioe.toString() );
+ }
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Copydir.java b/src/main/org/apache/tools/ant/taskdefs/Copydir.java
new file mode 100644
index 000000000..703bff19e
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Copydir.java
@@ -0,0 +1,153 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ *
+ *
+ * @author duncan@x180.com
+ */
+
+public class Copydir extends Task {
+
+ public File srcDir;
+ public File destDir;
+
+ private Hashtable filecopyList = new Hashtable();
+ private Vector ignoreList = new Vector();
+
+ public void setSrc(String src) {
+ srcDir = project.resolveFile(src);
+ }
+
+ public void setDest(String dest) {
+ destDir = project.resolveFile(dest);
+ }
+
+ public void execute() throws BuildException {
+ scanDir(srcDir, destDir);
+ if (filecopyList.size() > 0) {
+ project.log("Copying " + filecopyList.size() + " files to "
+ + destDir.getAbsolutePath());
+ Enumeration enum = filecopyList.keys();
+ while (enum.hasMoreElements()) {
+ String fromFile = (String)enum.nextElement();
+ String toFile = (String)filecopyList.get(fromFile);
+ try {
+ copyFile(fromFile, toFile);
+ } catch (IOException ioe) {
+ String msg = "Failed to copy " + fromFile + " to " + toFile
+ + " due to " + ioe.getMessage();
+ throw new BuildException(msg);
+ }
+ }
+ }
+ }
+
+ /**
+ List of filenames and directory names to not
+ include in the final .jar file. They should be either
+ , or " " (space) separated.
+
+ For example:
+
+ ignore="package.html, foo.class"
+
+ The ignored files will be logged.
+
+ @author Jon S. Stevens jon@clearink.com
+ */
+ public void setIgnore(String ignoreString) {
+ ignoreString = ignoreString;
+ if (ignoreString != null && ignoreString.length() > 0) {
+ StringTokenizer tok =
+ new StringTokenizer(ignoreString, ", ", false);
+ while (tok.hasMoreTokens()) {
+ ignoreList.addElement ( tok.nextToken().trim() );
+ }
+ }
+ }
+
+ private void scanDir(File from, File to) {
+ String[] list = from.list(new DesirableFilter());
+ if (list == null) {
+ project.log("Source directory " + srcDir.getAbsolutePath()
+ + " does not exist.", "copydir", Project.MSG_WARN);
+ return;
+ }
+ for (int i = 0; i < list.length; i++) {
+ String filename = list[i];
+ File srcFile = new File(from, filename);
+ File destFile = new File(to, filename);
+ if ( ! ignoreList.contains(filename) ) {
+ if (srcFile.isDirectory()) {
+ scanDir(srcFile, destFile);
+ } else {
+ if (srcFile.lastModified() > destFile.lastModified()) {
+ filecopyList.put(srcFile.getAbsolutePath(),
+ destFile.getAbsolutePath());
+ }
+ }
+ } else {
+ project.log("Copydir Ignored: " + filename, Project.MSG_WARN);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/taskdefs/Copyfile.java b/src/main/org/apache/tools/ant/taskdefs/Copyfile.java
new file mode 100644
index 000000000..fa78d8f0b
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Copyfile.java
@@ -0,0 +1,92 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ *
+ *
+ * @author duncan@x180.com
+ */
+
+public class Copyfile extends Task {
+
+ public File srcFile;
+ public File destFile;
+
+ public void setSrc(String src) {
+ srcFile = project.resolveFile(src);
+ }
+
+ public void setDest(String dest) {
+ destFile = project.resolveFile(dest);
+ }
+
+ public void execute() throws BuildException {
+ if (srcFile.lastModified() > destFile.lastModified()) {
+ try {
+ copyFile(srcFile, destFile);
+ } catch (IOException ioe) {
+ String msg = "Error copying file: " + srcFile.getAbsolutePath()
+ + " due to " + ioe.getMessage();
+ throw new BuildException(msg);
+ }
+ }
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Cvs.java b/src/main/org/apache/tools/ant/taskdefs/Cvs.java
new file mode 100644
index 000000000..1f0b85203
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Cvs.java
@@ -0,0 +1,139 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+
+/**
+ *
+ *
+ * @author costin@dnt.ro
+ * @author stefano@apache.org
+ */
+
+public class Cvs extends Task {
+
+ private String cvsRoot;
+ private String dest;
+ private String pack;
+ private String tag;
+
+ public void execute() throws BuildException {
+
+ // XXX: we should use JCVS (www.ice.com/JCVS) instead of command line
+ // execution so that we don't rely on having native CVS stuff around (SM)
+
+ try {
+ String ant=project.getProperty("ant.home");
+ if(ant==null) throw new BuildException("Needs ant.home");
+
+ StringBuffer sb=new StringBuffer();
+ sb.append(ant).append("/bin/antRun ").append(dest);
+ sb.append(" cvs -d ").append( cvsRoot ).append(" checkout ");
+ if(tag!=null)
+ sb.append("-r ").append(tag).append(" ");
+
+ sb.append( pack );
+ String command=sb.toString();
+
+ project.log(command, "cvs", Project.MSG_WARN);
+
+
+ // exec command on system runtime
+ Process proc = Runtime.getRuntime().exec( command);
+
+ // ignore response
+ InputStreamReader isr=new InputStreamReader(proc.getInputStream());
+ BufferedReader din = new BufferedReader(isr);
+
+ // pipe CVS output to STDOUT
+ String line;
+ while((line = din.readLine()) != null) {
+ project.log(line, "cvs", Project.MSG_WARN);
+ //System.out.println(line);
+ }
+
+ proc.waitFor();
+ int err = proc.exitValue();
+ if (err != 0) {
+ throw new BuildException( "Error " + err + "in " + command);
+ }
+
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ throw new BuildException("Error checking out: " + pack );
+ } catch (InterruptedException ex) {
+ }
+ }
+
+ public void setCvsRoot(String root) {
+ this.cvsRoot = root;
+ }
+
+ public void setDest(String dest) {
+ this.dest = dest;
+ }
+
+ public void setPackage(String p) {
+ this.pack = p;
+ }
+
+ public void setTag(String p) {
+ this.tag = p;
+ }
+}
+
+
diff --git a/src/main/org/apache/tools/ant/taskdefs/Deltree.java b/src/main/org/apache/tools/ant/taskdefs/Deltree.java
new file mode 100644
index 000000000..63df48085
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Deltree.java
@@ -0,0 +1,115 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+
+/**
+ *
+ *
+ * @author duncan@x180.com
+ */
+
+public class Deltree extends Task {
+
+ private File dir;
+
+ public void setDir(String dirName) {
+ dir = project.resolveFile(dirName);
+ }
+
+ public void execute() throws BuildException {
+ project.log("Deleting: " + dir.getAbsolutePath());
+
+ if (dir.exists()) {
+ if (!dir.isDirectory()) {
+ dir.delete();
+ return;
+ // String msg = "Given dir: " + dir.getAbsolutePath() +
+ // " is not a dir";
+ // throw new BuildException(msg);
+ }
+ try {
+ removeDir(dir);
+ } catch (IOException ioe) {
+ String msg = "Unable to delete " + dir.getAbsolutePath();
+ throw new BuildException(msg);
+ }
+ }
+ }
+
+ private void removeDir(File dir) throws IOException {
+
+ // check to make sure that the given dir isn't a symlink
+ // the comparison of absolute path and canonical path
+ // catches this
+
+ if (dir.getCanonicalPath().equals(dir.getAbsolutePath())) {
+ String[] list = dir.list();
+ for (int i = 0; i < list.length; i++) {
+ String s = list[i];
+ File f = new File(dir, s);
+ if (f.isDirectory()) {
+ removeDir(f);
+ } else {
+ f.delete();
+ }
+ }
+ }
+ dir.delete();
+ }
+}
+
diff --git a/src/main/org/apache/tools/ant/taskdefs/Echo.java b/src/main/org/apache/tools/ant/taskdefs/Echo.java
new file mode 100644
index 000000000..6c0cf6c38
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Echo.java
@@ -0,0 +1,75 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+import java.net.*;
+/**
+ * Echo
+ *
+ * @author costin@dnt.ro
+ */
+public class Echo extends Task {
+ String message; // required
+
+ public void execute() throws BuildException {
+ System.out.println(message);
+ }
+
+ public void setMessage(String d) {
+ this.message=d;
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Exec.java b/src/main/org/apache/tools/ant/taskdefs/Exec.java
new file mode 100644
index 000000000..ac3ec50a8
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Exec.java
@@ -0,0 +1,147 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+
+/**
+ *
+ *
+ * @author duncan@x180.com
+ */
+
+public class Exec extends Task {
+ private String os;
+ private String out;
+ private String dir;
+ private String command;
+
+ public void execute() throws BuildException {
+ try {
+ // test if os match
+ String myos=System.getProperty("os.name");
+ project.log("Myos= " + myos, Project.MSG_VERBOSE);
+ if( ( os != null ) && ( os.indexOf(myos) < 0 ) ){
+ // this command will be executed only on the specified OS
+ project.log("Not found in " + os, Project.MSG_VERBOSE);
+ return;
+ }
+
+ // XXX: we should use JCVS (www.ice.com/JCVS) instead of command line
+ // execution so that we don't rely on having native CVS stuff around (SM)
+
+ String ant=project.getProperty("ant.home");
+ if(ant==null) throw new BuildException("Needs ant.home");
+
+ String antRun = project.resolveFile(ant + "/bin/antRun").toString();
+ if (myos.toLowerCase().indexOf("windows")>=0)
+ antRun=antRun+".bat";
+ command=antRun + " " + project.resolveFile(dir) + " " + command;
+ project.log(command, Project.MSG_VERBOSE);
+
+ // exec command on system runtime
+ Process proc = Runtime.getRuntime().exec( command);
+ // ignore response
+ InputStreamReader isr=new InputStreamReader(proc.getInputStream());
+ BufferedReader din = new BufferedReader(isr);
+
+ PrintWriter fos=null;
+ if( out!=null ) {
+ fos=new PrintWriter( new FileWriter( out ) );
+ project.log("Output redirected to " + out, Project.MSG_VERBOSE);
+ }
+
+ // pipe CVS output to STDOUT
+ String line;
+ while((line = din.readLine()) != null) {
+ if( fos==null)
+ project.log(line, "exec", Project.MSG_INFO);
+ else
+ fos.println(line);
+ }
+ if(fos!=null)
+ fos.close();
+
+ proc.waitFor();
+ int err = proc.exitValue();
+ if (err != 0) {
+ project.log("Result: " + err, "exec", Project.MSG_ERR);
+ }
+
+ } catch (IOException ioe) {
+ throw new BuildException("Error exec: " + command );
+ } catch (InterruptedException ex) {
+ }
+
+ }
+
+ public void setDir(String d) {
+ this.dir = d;
+ }
+
+ public void setOs(String os) {
+ this.os = os;
+ }
+
+ public void setCommand(String command) {
+ this.command = command;
+ }
+
+ public void setOutput(String out) {
+ this.out = out;
+ }
+
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Expand.java b/src/main/org/apache/tools/ant/taskdefs/Expand.java
new file mode 100644
index 000000000..51fe4b2b8
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Expand.java
@@ -0,0 +1,118 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+import java.util.zip.*;
+/**
+ * Unzip a file.
+ *
+ * @author costin@dnt.ro
+ */
+public class Expand extends Task {
+ String dest; // req
+ String source; // req
+
+ // XXX move it to util or tools
+ public void execute() throws BuildException {
+ try {
+ File srcF=project.resolveFile(source);
+ File dir=project.resolveFile(dest);
+
+ project.log("Expanding: " + srcF + " into " + dir, Project.MSG_INFO);
+ // code from WarExpand
+ ZipInputStream zis = new ZipInputStream(new FileInputStream(srcF));
+ ZipEntry ze = null;
+
+ while ((ze = zis.getNextEntry()) != null) {
+ try {
+ File f = new File(dir, project.translatePath(ze.getName()));
+ project.log("expand-file " + ze.getName() , "expand", Project.MSG_VERBOSE );
+ // create intermediary directories - sometimes zip don't add them
+ File dirF=new File(f.getParent());
+ dirF.mkdirs();
+
+ if (ze.isDirectory()) {
+ f.mkdirs();
+ } else {
+ byte[] buffer = new byte[1024];
+ int length = 0;
+ FileOutputStream fos = new FileOutputStream(f);
+
+ while ((length = zis.read(buffer)) >= 0) {
+ fos.write(buffer, 0, length);
+ }
+
+ fos.close();
+ }
+ } catch( FileNotFoundException ex ) {
+ System.out.println("FileNotFoundException: " + ze.getName() );
+ }
+ }
+ project.log("", Project.MSG_VERBOSE );
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
+ public void setDest(String d) {
+ this.dest=d;
+ }
+
+ public void setSrc(String s) {
+ this.source = s;
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/GZip.java b/src/main/org/apache/tools/ant/taskdefs/GZip.java
new file mode 100644
index 000000000..28f38157f
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/GZip.java
@@ -0,0 +1,123 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+
+import java.io.*;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.zip.*;
+
+/**
+ * Allows one to create a .gz file from another file such as a tar file.
+ *
+ * @author duncan@x180.com
+ * @author Jon S. Stevens jon@clearink.com
+ */
+public class GZip extends Task {
+
+ private File zipFile;
+ private File source;
+ private Vector items = new Vector();
+ private Vector ignoreList = new Vector();
+
+ public void setZipfile(String zipFilename) {
+ zipFile = project.resolveFile(zipFilename);
+ }
+
+ public void setSrc(String src) {
+ source = project.resolveFile(src);
+ }
+
+ public void execute() throws BuildException {
+ project.log("Building gzip: " + zipFile.getAbsolutePath());
+
+ try {
+ GZIPOutputStream zOut = new GZIPOutputStream(new FileOutputStream(zipFile));
+
+ if (source.isDirectory()) {
+ project.log ("Cannot Gzip a directory!");
+ } else {
+ zipFile(source, zOut);
+ }
+ // close up
+ zOut.close();
+ } catch (IOException ioe) {
+ String msg = "Problem creating gzip " + ioe.getMessage();
+ throw new BuildException(msg);
+ }
+ }
+
+ private void zipFile(InputStream in, GZIPOutputStream 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);
+ }
+
+ private void zipFile(File file, GZIPOutputStream zOut)
+ throws IOException
+ {
+ FileInputStream fIn = new FileInputStream(file);
+ zipFile(fIn, zOut);
+ fIn.close();
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Get.java b/src/main/org/apache/tools/ant/taskdefs/Get.java
new file mode 100644
index 000000000..0a53b75a6
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Get.java
@@ -0,0 +1,105 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+import java.net.*;
+/**
+ * Get a particular source.
+ *
+ * @author costin@dnt.ro
+ */
+public class Get extends Task {
+ String source; // required
+ String dest; // required
+ String verbose;
+
+ public void execute() throws BuildException {
+ try {
+ URL url=new URL( source );
+ project.log("Getting: " + source);
+ File destF=new File(dest);
+ FileOutputStream fos = new FileOutputStream(destF);
+
+ InputStream is=url.openStream();
+ byte[] buffer = new byte[100 * 1024];
+ int length;
+
+ while ((length = is.read(buffer)) >= 0) {
+ fos.write(buffer, 0, length);
+ if( "true".equals(verbose)) System.out.print(".");
+ }
+ if( "true".equals(verbose)) System.out.println();
+ fos.close();
+ is.close();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ throw new BuildException(ioe.toString());
+ }
+ }
+
+ public void setSrc(String d) {
+ this.source=d;
+ }
+
+ public void setDest(String dest) {
+ this.dest = dest;
+ }
+
+ public void setVerbose(String v) {
+ verbose=v;
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Jar.java b/src/main/org/apache/tools/ant/taskdefs/Jar.java
new file mode 100644
index 000000000..866cc5e9b
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Jar.java
@@ -0,0 +1,113 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+
+import java.io.*;
+import java.util.zip.*;
+
+/**
+ *
+ *
+ * @author duncan@x180.com
+ */
+
+public class Jar extends Zip {
+
+ private File manifest;
+
+ public void setJarfile(String jarFilename) {
+ super.setZipfile(jarFilename);
+ super.archiveType = "jar";
+ }
+
+ public void setManifest(String manifestFilename) {
+ manifest = project.resolveFile(manifestFilename);
+ }
+
+ protected void initZipOutputStream(ZipOutputStream zOut)
+ throws IOException, BuildException
+ {
+ zOut.setMethod(ZipOutputStream.DEFLATED);
+
+ // add manifest first
+ if (manifest != null) {
+ ZipEntry ze = new ZipEntry("META-INF/");
+ zOut.putNextEntry(ze);
+ zipFile(manifest, zOut, "META-INF/MANIFEST.MF");
+ } else {
+ ZipEntry ze = new ZipEntry("META-INF/");
+ zOut.putNextEntry(ze);
+ String s = "/org/apache/tools/ant/defaultManifest.mf";
+ InputStream in = this.getClass().getResourceAsStream(s);
+ if ( in == null )
+ throw new BuildException ( "Could not find: " + s );
+ zipFile(in, zOut, "META-INF/MANIFEST.MF");
+ }
+ }
+
+ protected void zipDir(File dir, ZipOutputStream zOut, String vPath)
+ throws IOException
+ {
+ // First add directory to zip entry
+ if( ! "META-INF/".equals(vPath) ) {
+ // we already added a META-INF
+ ZipEntry ze = new ZipEntry(vPath);
+ zOut.putNextEntry(ze);
+ }
+ super.zipDir(dir, zOut, vPath);
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Java.java b/src/main/org/apache/tools/ant/taskdefs/Java.java
new file mode 100644
index 000000000..ffdbb5a0e
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Java.java
@@ -0,0 +1,158 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+/**
+ * This task acts as a loader for java applications but allows to use the same JVM
+ * for the called application thus resulting in much faster operation.
+ *
+ * @author Stefano Mazzocchi stefano@apache.org
+ */
+public class Java extends Task {
+
+ private String classname = null;
+ private String args = null;
+
+ /**
+ * Do the execution.
+ */
+ public void execute() throws BuildException {
+
+ project.log("Calling " + classname, "java", project.MSG_VERBOSE);
+
+ if (classname == null) {
+ throw new BuildException("Class name must not be null.");
+ }
+
+ Vector argList = tokenize(args);
+
+ project.log("Java args: " + argList.toString(), "java", project.MSG_VERBOSE);
+
+ run(classname, argList);
+ }
+
+ /**
+ * Set the source file.
+ */
+ public void setClass(String s) {
+ this.classname = s;
+ }
+
+ /**
+ * Set the destination file.
+ */
+ public void setArgs(String s) {
+ this.args = s;
+ }
+
+ /**
+ * Executes the given classname with the given arguments as it
+ * was a command line application.
+ */
+ protected void run(String classname, Vector args) throws BuildException {
+ try {
+ Class[] param = { Class.forName("[Ljava.lang.String;") };
+ Class c = Class.forName(classname);
+ Method main = c.getMethod("main", param);
+ Object[] a = { array(args) };
+ main.invoke(null, a);
+ } catch (NullPointerException e) {
+ throw new BuildException("Could not find main() method in " + classname);
+ } catch (ClassNotFoundException e) {
+ throw new BuildException("Could not find " + classname + ". Make sure you have it in your classpath");
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getTargetException();
+ if (!(t instanceof SecurityException)) {
+ throw new BuildException(t.toString());
+ }
+ // else ignore because the security exception is thrown
+ // if the invoked application tried to call System.exit()
+ } catch (Exception e) {
+ throw new BuildException(e.toString());
+ }
+ }
+
+ /**
+ * Transforms an argument string into a vector of strings.
+ */
+ protected Vector tokenize(String args) {
+ Vector v = new Vector();
+ StringTokenizer t = new StringTokenizer(args, " ");
+
+ while (t.hasMoreTokens()) {
+ v.addElement(t.nextToken());
+ }
+
+ return v;
+ }
+
+ /**
+ * Transforms a vector of strings into an array.
+ */
+ protected String[] array(Vector v) {
+ String[] s = new String[v.size()];
+ Enumeration e = v.elements();
+
+ for (int i = 0; e.hasMoreElements(); i++) {
+ s[i] = (String) e.nextElement();
+ }
+
+ return s;
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Javac.java b/src/main/org/apache/tools/ant/taskdefs/Javac.java
new file mode 100644
index 000000000..5a7cbc675
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Javac.java
@@ -0,0 +1,574 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+
+import java.io.*;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * Task to compile Java source files. This task can take the following
+ * arguments:
+ *
+ * - sourcedir
+ *
- destdir
+ *
- deprecation
+ *
- classpath
+ *
- bootclasspath
+ *
- extdirs
+ *
- optimize
+ *
- debug
+ *
- target
+ *
+ * Of these arguments, the sourcedir and destdir are required.
+ *
+ * When this task executes, it will recursively scan the sourcedir and
+ * destdir looking for Java source files to compile. This task makes its
+ * compile decision based on timestamp. Any other file in the
+ * sourcedir will be copied to the destdir allowing support files to be
+ * located properly in the classpath.
+ *
+ * @author duncan@x180.com
+ */
+
+public class Javac extends Task {
+
+ private File srcDir;
+ private File destDir;
+ private String compileClasspath;
+ private boolean debug = false;
+ private boolean optimize = false;
+ private boolean deprecation = false;
+ private String target;
+ private String bootclasspath;
+ private String extdirs;
+
+ private Vector compileList = new Vector();
+ private Hashtable filecopyList = new Hashtable();
+
+ /**
+ * Set the source dir to find the source Java files.
+ */
+
+ public void setSrcdir(String srcDirName) {
+ srcDir = project.resolveFile(srcDirName);
+ }
+
+ /**
+ * Set the destination directory into which the Java source
+ * files should be compiled.
+ */
+
+ public void setDestdir(String destDirName) {
+ destDir = project.resolveFile(destDirName);
+ }
+
+ /**
+ * Set the classpath to be used for this compilation.
+ */
+
+ public void setClasspath(String classpath) {
+ compileClasspath = Project.translatePath(classpath);
+ }
+
+ /**
+ * Sets the bootclasspath that will be used to compile the classes
+ * against.
+ */
+
+ public void setBootclasspath(String bootclasspath) {
+ this.bootclasspath = Project.translatePath(bootclasspath);
+ }
+
+ /**
+ * Sets the extension directories that will be used during the
+ * compilation.
+ */
+
+ public void setExtdirs(String extdirs) {
+ this.extdirs = Project.translatePath(extdirs);
+ }
+
+
+ /**
+ * Set the deprecation flag. Valid strings are "on", "off", "true", and
+ * "false".
+ */
+
+ public void setDeprecation(String deprecation) {
+ if (deprecation.equalsIgnoreCase("on") ||
+ deprecation.equalsIgnoreCase("true")) {
+ this.deprecation = true;
+ } else {
+ this.deprecation = false;
+ }
+ }
+
+
+ /**
+ * Set the debug flag. Valid strings are "on", "off", "true", and "false".
+ */
+
+ public void setDebug(String debugString) {
+ if (debugString.equalsIgnoreCase("on") ||
+ debugString.equalsIgnoreCase("true")) {
+ debug = true;
+ } else {
+ debug = false;
+ }
+ }
+
+ /**
+ * Set the optimize flag. Valid strings are "on", "off", "true", and
+ * "false".
+ */
+
+ public void setOptimize(String optimizeString) {
+ if (optimizeString.equalsIgnoreCase("on") ||
+ optimizeString.equalsIgnoreCase("true")) {
+ optimize = true;
+ } else {
+ optimize = false;
+ }
+ }
+
+ /**
+ * Sets the target VM that the classes will be compiled for. Valid
+ * strings are "1.1", "1.2", and "1.3".
+ */
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+ /**
+ * Executes the task.
+ */
+
+ public void execute() throws BuildException {
+
+ // first off, make sure that we've got a srcdir and destdir
+
+ if (srcDir == null || destDir == null ) {
+ String msg = "srcDir and destDir attributes must be set!";
+ throw new BuildException(msg);
+ }
+
+ // scan source and dest dirs to build up both copy lists and
+ // compile lists
+
+ scanDir(srcDir, destDir);
+
+ // compile the source files
+
+ String compiler = project.getProperty("build.compiler");
+ if (compiler == null) {
+ if (Project.getJavaVersion().startsWith("1.3")) {
+ compiler = "modern";
+ } else {
+ compiler = "classic";
+ }
+ }
+
+ if (compileList.size() > 0) {
+ project.log("Compiling " + compileList.size() +
+ " source files to " + destDir);
+
+ if (compiler.equalsIgnoreCase("classic")) {
+ doClassicCompile();
+ } else if (compiler.equalsIgnoreCase("modern")) {
+ doModernCompile();
+ } else if (compiler.equalsIgnoreCase("jikes")) {
+ doJikesCompile();
+ } else {
+ String msg = "Don't know how to use compiler " + compiler;
+ throw new BuildException(msg);
+ }
+ }
+
+ // copy the support files
+
+ if (filecopyList.size() > 0) {
+ project.log("Copying " + filecopyList.size() +
+ " support files to " + destDir.getAbsolutePath());
+ Enumeration enum = filecopyList.keys();
+ while (enum.hasMoreElements()) {
+ String fromFile = (String)enum.nextElement();
+ String toFile = (String)filecopyList.get(fromFile);
+ try {
+ copyFile(fromFile, toFile);
+ } catch (IOException ioe) {
+ String msg = "Failed to copy " + fromFile + " to " + toFile
+ + " due to " + ioe.getMessage();
+ throw new BuildException(msg);
+ }
+ }
+ }
+ }
+
+ /**
+ * Scans the directory looking for source files to be compiled and
+ * support files to be copied.
+ */
+
+ private void scanDir(File srcDir, File destDir) {
+
+ String[] list = srcDir.list(new DesirableFilter());
+ int len = (list==null ? 0 : list.length);
+ for (int i = 0; i < len; i++) {
+ String filename = list[i];
+ File srcFile = new File(srcDir, filename);
+ File destFile = new File(destDir, filename);
+ if (srcFile.isDirectory()) {
+ // it's a dir, scan that recursively
+ scanDir(srcFile, destFile);
+ } else {
+ // it's a file, see if we compile it or just copy it
+ if (filename.endsWith(".java")) {
+ File classFile =
+ new File(destDir,
+ filename.substring(0,
+ filename.indexOf(".java"))
+ + ".class");
+ if (srcFile.lastModified() > classFile.lastModified()) {
+ compileList.addElement(srcFile.getAbsolutePath());
+ }
+ } else {
+ if (srcFile.lastModified() > destFile.lastModified()) {
+ filecopyList.put(srcFile.getAbsolutePath(),
+ destFile.getAbsolutePath());
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Builds the compilation classpath.
+ */
+
+ // XXX
+ // we need a way to not use the current classpath.
+
+ private String getCompileClasspath() {
+ StringBuffer classpath = new StringBuffer();
+
+ // add dest dir to classpath so that previously compiled and
+ // untouched classes are on classpath
+
+ //classpath.append(sourceDir.getAbsolutePath());
+ //classpath.append(File.pathSeparator);
+ classpath.append(destDir.getAbsolutePath());
+
+ // add our classpath to the mix
+
+ if (compileClasspath != null) {
+ addExistingToClasspath(classpath,compileClasspath);
+ }
+
+ // add the system classpath
+
+ addExistingToClasspath(classpath,System.getProperty("java.class.path"));
+ return classpath.toString();
+ }
+
+
+ /**
+ * Takes a classpath-like string, and adds each element of
+ * this string to a new classpath, if the components exist.
+ * Components that don't exist, aren't added.
+ * We do this, because jikes issues warnings for non-existant
+ * files/dirs in his classpath, and these warnings are pretty
+ * annoying.
+ * @param target - target classpath
+ * @param source - source classpath
+ * to get file objects.
+ */
+ private void addExistingToClasspath(StringBuffer target,String source) {
+ StringTokenizer tok = new StringTokenizer(source,
+ System.getProperty("path.separator"), false);
+ while (tok.hasMoreTokens()) {
+ File f = project.resolveFile(tok.nextToken());
+
+ if (f.exists()) {
+ target.append(File.pathSeparator);
+ target.append(f.getAbsolutePath());
+ } else {
+ project.log("Dropping from classpath: "+
+ f.getAbsolutePath(),project.MSG_VERBOSE);
+ }
+ }
+
+ }
+
+
+ /**
+ * Peforms a copmile using the classic compiler that shipped with
+ * JDK 1.1 and 1.2.
+ */
+
+ private void doClassicCompile() throws BuildException {
+ project.log("Using classic compiler", project.MSG_VERBOSE);
+ String classpath = getCompileClasspath();
+ Vector argList = new Vector();
+
+ if (deprecation == true)
+ argList.addElement("-deprecation");
+
+ argList.addElement("-d");
+ argList.addElement(destDir.getAbsolutePath());
+ argList.addElement("-classpath");
+ // Just add "sourcepath" to classpath ( for JDK1.1 )
+ if (Project.getJavaVersion().startsWith("1.1")) {
+ argList.addElement(classpath + File.pathSeparator +
+ srcDir.getAbsolutePath());
+ } else {
+ argList.addElement(classpath);
+ argList.addElement("-sourcepath");
+ argList.addElement(srcDir.getAbsolutePath());
+ if (target != null) {
+ argList.addElement("-target");
+ argList.addElement(target);
+ }
+ }
+ if (debug) {
+ argList.addElement("-g");
+ }
+ if (optimize) {
+ argList.addElement("-O");
+ }
+ if (bootclasspath != null) {
+ argList.addElement("-bootclasspath");
+ argList.addElement(bootclasspath);
+ }
+ if (extdirs != null) {
+ argList.addElement("-extdirs");
+ argList.addElement(extdirs);
+ }
+
+ project.log("Compilation args: " + argList.toString(),
+ project.MSG_VERBOSE);
+
+ String[] args = new String[argList.size() + compileList.size()];
+ int counter = 0;
+
+ for (int i = 0; i < argList.size(); i++) {
+ args[i] = (String)argList.elementAt(i);
+ counter++;
+ }
+
+ // XXX
+ // should be using system independent line feed!
+
+ StringBuffer niceSourceList = new StringBuffer("Files to be compiled:"
+ + "\r\n");
+
+ Enumeration enum = compileList.elements();
+ while (enum.hasMoreElements()) {
+ args[counter] = (String)enum.nextElement();
+ niceSourceList.append(" " + args[counter] + "\r\n");
+ counter++;
+ }
+
+ project.log(niceSourceList.toString(), project.MSG_VERBOSE);
+
+ // XXX
+ // provide the compiler a different message sink - namely our own
+
+ JavacOutputStream jos = new JavacOutputStream(project);
+
+ sun.tools.javac.Main compiler =
+ new sun.tools.javac.Main(jos, "javac");
+ compiler.compile(args);
+ if (jos.getErrorFlag()) {
+ String msg = "Compile failed, messages should have been provided.";
+ throw new BuildException(msg);
+ }
+ }
+
+ /**
+ * Performs a compile using the newer compiler that ships with JDK 1.3
+ */
+
+ private void doModernCompile() throws BuildException {
+ project.log("Performing a Modern Compile");
+ }
+
+ /**
+ * Performs a compile using the Jikes compiler from IBM..
+ * Mostly of this code is identical to doClassicCompile()
+ * However, it does not support all options like
+ * bootclasspath, extdirs, deprecation and so on, because
+ * there is no option in jikes and I don't understand
+ * what they should do.
+ *
+ * It has been successfully tested with jikes 1.10
+ *
+ * @author skanthak@muehlheim.de
+ */
+
+ private void doJikesCompile() throws BuildException {
+ project.log("Using jikes compiler",project.MSG_VERBOSE);
+ String classpath = getCompileClasspath();
+ Vector argList = new Vector();
+
+ if (deprecation == true)
+ argList.addElement("-deprecation");
+
+ // We want all output on stdout to make
+ // parsing easier
+ argList.addElement("-Xstdout");
+
+ argList.addElement("-d");
+ argList.addElement(destDir.getAbsolutePath());
+ argList.addElement("-classpath");
+ // Jikes has no option for source-path so we
+ // will add it to classpath.
+ // XXX is this correct?
+ argList.addElement(classpath+File.pathSeparator +
+ srcDir.getAbsolutePath());
+ if (debug) {
+ argList.addElement("-g");
+ }
+ if (optimize) {
+ argList.addElement("-O");
+ }
+
+ /**
+ * XXX
+ * Perhaps we shouldn't use properties for these
+ * two options (emacs mode and warnings),
+ * but include it in the javac directive?
+ */
+
+ /**
+ * Jikes has the nice feature to print error
+ * messages in a form readable by emacs, so
+ * that emcas can directly set the cursor
+ * to the place, where the error occured.
+ */
+ boolean emacsMode = false;
+ String emacsProperty = project.getProperty("build.compiler.emacs");
+ if (emacsProperty != null &&
+ (emacsProperty.equalsIgnoreCase("on") ||
+ emacsProperty.equalsIgnoreCase("true"))
+ ) {
+ emacsMode = true;
+ }
+
+ /**
+ * Jikes issues more warnings that javac, for
+ * example, when you have files in your classpath
+ * that don't exist. As this is often the case, these
+ * warning can be pretty annoying.
+ */
+ boolean warnings = true;
+ String warningsProperty = project.getProperty("build.compiler.warnings");
+ if (warningsProperty != null &&
+ (warningsProperty.equalsIgnoreCase("off") ||
+ warningsProperty.equalsIgnoreCase("false"))
+ ) {
+ warnings = false;
+ }
+
+ if (emacsMode)
+ argList.addElement("+E");
+
+ if (!warnings)
+ argList.addElement("-nowarn");
+
+ project.log("Compilation args: " + argList.toString(),
+ project.MSG_VERBOSE);
+
+ String[] args = new String[argList.size() + compileList.size()];
+ int counter = 0;
+
+ for (int i = 0; i < argList.size(); i++) {
+ args[i] = (String)argList.elementAt(i);
+ counter++;
+ }
+
+ // XXX
+ // should be using system independent line feed!
+
+ StringBuffer niceSourceList = new StringBuffer("Files to be compiled:"
+ + "\r\n");
+
+ Enumeration enum = compileList.elements();
+ while (enum.hasMoreElements()) {
+ args[counter] = (String)enum.nextElement();
+ niceSourceList.append(" " + args[counter] + "\r\n");
+ counter++;
+ }
+
+ project.log(niceSourceList.toString(), project.MSG_VERBOSE);
+
+ // XXX
+ // provide the compiler a different message sink - namely our own
+
+ JikesOutputParser jop = new JikesOutputParser(project,emacsMode);
+
+ Jikes compiler = new Jikes(jop,"jikes");
+ compiler.compile(args);
+ if (jop.getErrorFlag()) {
+ String msg = "Compile failed, messages should have been provided.";
+ throw new BuildException(msg);
+ }
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/JavacOutputStream.java b/src/main/org/apache/tools/ant/taskdefs/JavacOutputStream.java
new file mode 100644
index 000000000..5fdd11e01
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/JavacOutputStream.java
@@ -0,0 +1,125 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+
+/**
+ * Serves as an output stream to Javac. This let's us print messages
+ * out to the project and detect whether or not Javac had an error
+ * while compiling.
+ *
+ * @author James Duncan Davidson (duncan@x180.com)
+ */
+
+class JavacOutputStream extends OutputStream {
+
+ private Project project;
+ private StringBuffer line;
+ private boolean errorFlag = false;
+
+ /**
+ * Constructs a new JavacOutputStream with the given project
+ * as the output source for messages.
+ */
+
+ JavacOutputStream(Project project) {
+ this.project = project;
+ line = new StringBuffer();
+ }
+
+ /**
+ * Write a character to the output stream. This method looks
+ * to make sure that there isn't an error being reported and
+ * will flush each line of input out to the project's log stream.
+ */
+
+ public void write(int c) throws IOException {
+ char cc = (char)c;
+ if (cc == '\r' || cc == '\n') {
+ // line feed
+ if (line.length() > 0) {
+ processLine();
+ }
+ } else {
+ line.append(cc);
+ }
+ }
+
+ /**
+ * Processes a line of input and determines if an error occured.
+ */
+
+ private void processLine() {
+ String s = line.toString();
+ if (s.indexOf("error") > -1) {
+ errorFlag = true;
+ }
+ project.log(s);
+ line = new StringBuffer();
+ }
+
+ /**
+ * Returns the error status of the compile. If no errors occured,
+ * this method will return false, else this method will return true.
+ */
+
+ boolean getErrorFlag() {
+ return errorFlag;
+ }
+}
+
diff --git a/src/main/org/apache/tools/ant/taskdefs/Javadoc2.java b/src/main/org/apache/tools/ant/taskdefs/Javadoc2.java
new file mode 100644
index 000000000..504ff6a56
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Javadoc2.java
@@ -0,0 +1,564 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * This Task makes it easy to generate javadocs for a collection of source code.
+ *
+ * Current known limitations are:
+ * - multiple source path breaks operation
+ * - patterns must be of the form "xxx.*", every other pattern doesn't work.
+ * - the java comment-stripper reader is horribly slow
+ * - stupid javadoc calls System.exit() and breaks Ant execution
+ * (two solutions: security manager and decompilation for better hooks)
+ * - there is no control on arguments sanity since they are left
+ * to the javadoc implementation.
+ *
+ * @author Jon S. Stevens jon@clearink.com
+ * @author Stefano Mazzocchi stefano@apache.org
+ */
+public class Javadoc2 extends Java {
+
+ private String sourcePath = null;
+ private File destDir = null;
+ private File overviewFile = null;
+ private String sourceFiles = null;
+ private String packageNames = null;
+ private boolean pub = false;
+ private boolean prot = false;
+ private boolean pack = false;
+ private boolean priv = false;
+ private boolean author = true;
+ private boolean version = true;
+ private String doclet = null;
+ private File docletpath = null;
+ private boolean old = false;
+ private String classpath = null;
+ private String bootclasspath = null;
+ private String extdirs = null;
+ private boolean verbose = false;
+ private String locale = null;
+ private String encoding = null;
+ private boolean use = false;
+ private boolean splitindex = false;
+ private String windowtitle = null;
+ private String doctitle = null;
+ private String header = null;
+ private String footer = null;
+ private String bottom = null;
+ private String link = null;
+ private String linkoffline = null;
+ private String group = null;
+ private boolean nodeprecated = false;
+ private boolean nodeprecatedlist = false;
+ private boolean notree = false;
+ private boolean noindex = false;
+ private boolean nohelp = false;
+ private boolean nonavbar = false;
+ private File stylesheetfile = null;
+ private File helpfile = null;
+ private String docencoding = null;
+
+ private Vector compileList = new Vector();
+
+ public void setSourcepath(String src) {
+ sourcePath = project.translatePath(src);
+ }
+ public void setDestdir(String src) {
+ destDir = project.resolveFile(src);
+ }
+ public void setSourcefiles(String src) {
+ sourceFiles = src;
+ }
+ public void setPackagenames(String src) {
+ packageNames = src;
+ }
+ public void setOverview(String src) {
+ overviewFile = project.resolveFile(src);
+ }
+ public void setPublic(String src) {
+ pub = new Boolean(src).booleanValue();
+ }
+ public void setProtected(String src) {
+ prot = new Boolean(src).booleanValue();
+ }
+ public void setPackage(String src) {
+ pack = new Boolean(src).booleanValue();
+ }
+ public void setPrivate(String src) {
+ priv = new Boolean(src).booleanValue();
+ }
+ public void setDoclet(String src) {
+ doclet = src;
+ }
+ public void setDocletPath(String src) {
+ docletpath = project.resolveFile(src);
+ }
+ public void setOld(String src) {
+ old = new Boolean(src).booleanValue();
+ }
+ public void setClasspath(String src) {
+ classpath = Project.translatePath(src);
+ }
+ public void setBootclasspath(String src) {
+ bootclasspath = Project.translatePath(src);
+ }
+ public void setExtdirs(String src) {
+ extdirs = src;
+ }
+ public void setVerbose(String src) {
+ verbose = new Boolean(src).booleanValue();
+ }
+ public void setLocale(String src) {
+ locale = src;
+ }
+ public void setEncoding(String src) {
+ encoding = src;
+ }
+ public void setVersion(String src) {
+ version = new Boolean(src).booleanValue();
+ }
+ public void setUse(String src) {
+ use = new Boolean(src).booleanValue();
+ }
+ public void setAuthor(String src) {
+ author = new Boolean(src).booleanValue();
+ }
+ public void setSplitindex(String src) {
+ splitindex = new Boolean(src).booleanValue();
+ }
+ public void setWindowtitle(String src) {
+ windowtitle = src;
+ }
+ public void setDoctitle(String src) {
+ doctitle = src;
+ }
+ public void setHeader(String src) {
+ header = src;
+ }
+ public void setFooter(String src) {
+ footer = src;
+ }
+ public void setBottom(String src) {
+ bottom = src;
+ }
+ public void setLink(String src) {
+ link = src;
+ }
+ public void setLinkoffline(String src) {
+ linkoffline = src;
+ }
+ public void setGroup(String src) {
+ group = src;
+ }
+ public void setNodeprecated(String src) {
+ nodeprecated = new Boolean(src).booleanValue();
+ }
+ public void setNodeprecatedlist(String src) {
+ nodeprecatedlist = new Boolean(src).booleanValue();
+ }
+ public void setNotree(String src) {
+ notree = new Boolean(src).booleanValue();
+ }
+ public void setNoindex(String src) {
+ noindex = new Boolean(src).booleanValue();
+ }
+ public void setNohelp(String src) {
+ nohelp = new Boolean(src).booleanValue();
+ }
+ public void setNonavbar(String src) {
+ nonavbar = new Boolean(src).booleanValue();
+ }
+ public void setStylesheetfile(String src) {
+ stylesheetfile = project.resolveFile(src);
+ }
+ public void setDocencoding(String src) {
+ docencoding = src;
+ }
+
+ public void execute() throws BuildException {
+ if (sourcePath == null && destDir == null ) {
+ String msg = "sourcePath and destDir attributes must be set!";
+ throw new BuildException(msg);
+ }
+
+ project.log("Generating Javadoc", project.MSG_INFO);
+
+ Vector argList = new Vector();
+
+ if (overviewFile != null) {
+ argList.addElement("-overview");
+ argList.addElement(overviewFile.getAbsolutePath());
+ }
+ if (pub)
+ argList.addElement ("-public");
+ if (prot)
+ argList.addElement ("-protected");
+ if (pack)
+ argList.addElement ("-package");
+ if (priv)
+ argList.addElement ("-private");
+ if (old)
+ argList.addElement ("-1.1");
+ if (verbose)
+ argList.addElement ("-verbose");
+ if (version)
+ argList.addElement ("-version");
+ if (use)
+ argList.addElement ("-use");
+ if (author)
+ argList.addElement ("-author");
+ if (splitindex)
+ argList.addElement ("-splitindex");
+ if (nodeprecated)
+ argList.addElement ("-nodeprecated");
+ if (nodeprecatedlist)
+ argList.addElement ("-nodeprecatedlist");
+ if (notree)
+ argList.addElement ("-notree");
+ if (noindex)
+ argList.addElement ("-noindex");
+ if (nohelp)
+ argList.addElement ("-nohelp");
+ if (nonavbar)
+ argList.addElement ("-nonavbar");
+
+ if (doclet != null) {
+ argList.addElement("-doclet");
+ argList.addElement(doclet);
+ }
+ argList.addElement("-classpath");
+ if (classpath != null) {
+ argList.addElement(classpath);
+ } else {
+ argList.addElement(System.getProperty("java.class.path"));
+ }
+ if (bootclasspath != null) {
+ argList.addElement("-bootclasspath");
+ argList.addElement(bootclasspath);
+ }
+ if (extdirs != null) {
+ argList.addElement("-extdirs");
+ argList.addElement(extdirs);
+ }
+ if (locale != null) {
+ argList.addElement("-locale");
+ argList.addElement(locale);
+ }
+ if (encoding != null) {
+ argList.addElement("-encoding");
+ argList.addElement(encoding);
+ }
+ if (windowtitle != null) {
+ argList.addElement("-windowtitle");
+ argList.addElement(windowtitle);
+ }
+ if (doctitle != null) {
+ argList.addElement("-doctitle");
+ argList.addElement(doctitle);
+ }
+ if (header != null) {
+ argList.addElement("-header");
+ argList.addElement(header);
+ }
+ if (footer != null) {
+ argList.addElement("-footer");
+ argList.addElement(footer);
+ }
+ if (bottom != null) {
+ argList.addElement("-bottom");
+ argList.addElement(bottom);
+ }
+ if (link != null) {
+ argList.addElement("-link");
+ argList.addElement(link);
+ }
+ if (linkoffline != null) {
+ argList.addElement("-linkoffline");
+ argList.addElement(linkoffline);
+ }
+ if (group != null) {
+ argList.addElement("-group");
+ argList.addElement(group);
+ }
+ if (stylesheetfile != null) {
+ argList.addElement("-stylesheetfile");
+ argList.addElement(stylesheetfile.getAbsolutePath());
+ }
+ if (helpfile != null) {
+ argList.addElement("-helpfile");
+ argList.addElement(helpfile.getAbsolutePath());
+ }
+ if (docencoding != null) {
+ argList.addElement("-docencoding");
+ argList.addElement(docencoding);
+ }
+ if (destDir != null) {
+ argList.addElement("-d");
+ argList.addElement(destDir.getAbsolutePath());
+ }
+ if (sourcePath != null) {
+ argList.addElement("-sourcepath");
+ argList.addElement(sourcePath);
+ }
+
+ if ((packageNames != null) && (packageNames.length() > 0)) {
+ Vector packages = new Vector();
+ StringTokenizer tok = new StringTokenizer(packageNames, ",", false);
+ while (tok.hasMoreTokens()) {
+ String name = tok.nextToken().trim();
+ if (name.endsWith(".*")) {
+ packages.addElement(name);
+ } else {
+ argList.addElement(name);
+ }
+ }
+ if (packages.size() > 0) {
+ evaluatePackages(sourcePath, packages, argList);
+ }
+ }
+
+ if ((sourceFiles != null) && (sourceFiles.length() > 0)) {
+ StringTokenizer tok = new StringTokenizer(sourceFiles, ",", false);
+ while (tok.hasMoreTokens()) {
+ argList.addElement(tok.nextToken().trim());
+ }
+ }
+
+ project.log("Javadoc args: " + argList.toString(), "javadoc", project.MSG_VERBOSE);
+
+ project.log("Javadoc execution", project.MSG_INFO);
+
+ run("com.sun.tools.javadoc.Main", argList);
+ }
+
+ /**
+ * Given a source path, a list of package patterns, fill the given list
+ * with the packages found in that path subdirs matching one of the given
+ * patterns.
+ */
+ private void evaluatePackages(String source, Vector packages, Vector list) {
+ project.log("Parsing source files for packages (will take a while)", project.MSG_INFO);
+
+ Hashtable map = mapClasses(new File(source));
+
+ Enumeration e = map.keys();
+ while (e.hasMoreElements()) {
+ String pack = (String) e.nextElement();
+ for (int i = 0; i < packages.size(); i++) {
+ if (matches(pack, (String) packages.elementAt(i))) {
+ list.addElement(pack);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Implements the pattern matching. For now it's only able to
+ * guarantee that "aaa.bbb.ccc" matches "aaa.*" and "aaa.bbb.*"
+ * FIXME: this code needs much improvement.
+ */
+ private boolean matches(String string, String pattern) {
+ return string.startsWith(pattern.substring(0, pattern.length() - 2));
+ }
+
+ /**
+ * Returns an hashtable of packages linked to the last parsed
+ * file in that package. This map is use to return a list of unique
+ * packages as map keys.
+ */
+ private Hashtable mapClasses(File path) {
+ Hashtable map = new Hashtable();
+
+ Vector files = new Vector();
+ getFiles(path, files);
+
+ Enumeration e = files.elements();
+ while (e.hasMoreElements()) {
+ File file = (File) e.nextElement();
+ String packageName = getPackageName(file);
+ if (packageName != null) map.put(packageName, file);
+ }
+
+ return map;
+ }
+
+ /**
+ * Fills the given vector with files under the given path filtered
+ * by the given file filter.
+ */
+ private void getFiles(File path, Vector list) {
+ if (!path.exists()) {
+ throw new BuildException("Path " + path + " does not exist.");
+ }
+
+ String[] files = path.list();
+ String cwd = path.getName() + System.getProperty("path.separator");
+
+ if (files != null) {
+ int count = 0;
+ for (int i = 0; i < files.length; i++) {
+ File file = new File(cwd + files[i]);
+ if (file.isDirectory()) {
+ getFiles(file, list);
+ } else if (files[i].endsWith(".java")) {
+ count++;
+ list.addElement(files[i]);
+ }
+ }
+ if (count > 0) {
+ project.log("found " + count + " source files in " + path, "javadoc", project.MSG_VERBOSE);
+ }
+ } else {
+ throw new BuildException("Error occurred during " + path + " evaluation.");
+ }
+ }
+
+ /**
+ * Return the package name of the given java source file.
+ * This method performs valid java parsing to figure out the package.
+ */
+ private String getPackageName(File file) {
+ String name = null;
+
+ try {
+ BufferedReader reader = new BufferedReader(new JavaReader(new FileReader(file)));
+ String line;
+ while (true) {
+ line = reader.readLine();
+ if (line == null) {
+ project.log("Could not evaluate package for " + file, "javadoc", project.MSG_WARN);
+ return null;
+ }
+ if (line.trim().startsWith("package ")) {
+ name = line.substring(8, line.indexOf(";")).trim();
+ break;
+ }
+ }
+ reader.close();
+ } catch (Exception e) {
+ project.log("Exception " + e + " parsing " + file, "javadoc", project.MSG_WARN);
+ return null;
+ }
+
+ project.log(file + " --> " + name, "javadoc", project.MSG_VERBOSE);
+
+ return name;
+ }
+
+ /**
+ * This is a java comment stripper reader that filters comments out
+ * for more significant java parsing.
+ */
+ class JavaReader extends FilterReader {
+
+ public JavaReader(Reader in) {
+ super(in);
+ }
+
+ public int read() throws IOException {
+ int c = in.read();
+ if (c == '/') {
+ c = in.read();
+ if (c == '*') {
+ while (true) {
+ c = in.read();
+ if (c == '*') {
+ c = in.read();
+ if (c == '/') {
+ c = in.read();
+ break;
+ }
+ }
+ }
+ }
+ }
+ return c;
+ }
+
+ /**
+ * FIXME: this method is the one called by BuffereReader and it should
+ * use char[] based methods instead of relying on single char ones
+ * to speed up execution. Please, make this faster.
+ */
+ public int read(char cbuf[], int off, int len) throws IOException {
+ for (int i = 0; i < len; i++) {
+ int c = read();
+ if (c == -1) {
+ if (i == 0) {
+ return -1;
+ } else {
+ return i;
+ }
+ }
+ cbuf[off + i] = (char) c;
+ }
+ return len;
+ }
+
+ public long skip(long n) throws IOException {
+ for (long i = 0; i < n; i++) {
+ if (in.read() == -1) return i;
+ }
+ return n;
+ }
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Jikes.java b/src/main/org/apache/tools/ant/taskdefs/Jikes.java
new file mode 100644
index 000000000..dba4db80a
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Jikes.java
@@ -0,0 +1,47 @@
+package org.apache.tools.ant.taskdefs;
+
+import java.io.*;
+
+/**
+ * Encapsulates a Jikes compiler, by
+ * directly executing an external process.
+ * @author skanthak@muehlheim.de
+ */
+public class Jikes {
+ protected JikesOutputParser jop;
+ protected String command;
+
+ /**
+ * Constructs a new Jikes obect.
+ * @param jop - Parser to send jike's output to
+ * @param command - name of jikes executeable
+ */
+ protected Jikes(JikesOutputParser jop,String command) {
+ super();
+ this.jop = jop;
+ this.command = command;
+ }
+
+ /**
+ * Do the compile with the specified arguments.
+ * @param args - arguments to pass to process on command line
+ */
+ protected void compile(String[] args) {
+ String[] commandArray = new String[args.length+1];
+ commandArray[0] = command;
+ System.arraycopy(args,0,commandArray,1,args.length);
+
+ // We assume, that everything jikes writes goes to
+ // standard output, not to standard error. The option
+ // -Xstdout that is given to Jikes in Javac.doJikesCompile()
+ // should guarantee this. At least I hope so. :)
+ try {
+ Process jikes = Runtime.getRuntime().exec(commandArray);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(jikes.getInputStream()));
+ jop.parseOutput(reader);
+ } catch (IOException e) {
+ // Where could we log this to? We don't have an instance
+ // of project. Perhaps we should add one to our constructor?
+ }
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/JikesOutputParser.java b/src/main/org/apache/tools/ant/taskdefs/JikesOutputParser.java
new file mode 100644
index 000000000..69d6f4d97
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/JikesOutputParser.java
@@ -0,0 +1,103 @@
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+
+import java.io.*;
+
+/**
+ * Parses output from jikes and
+ * passes errors and warnings
+ * into the right logging channels of Project.
+ *
+ * TODO:
+ * Parsing could be much better
+ * @author skanthak@muehlheim.de
+ */
+public class JikesOutputParser {
+ protected Project project;
+ protected boolean errorFlag = false; // no errors so far
+ protected int errors,warnings;
+ protected boolean error = false;
+ protected boolean emacsMode;
+
+ /**
+ * Construct a new Parser object
+ * @param project - project in whichs context we are called
+ */
+ protected JikesOutputParser(Project project, boolean emacsMode) {
+ super();
+ this.project = project;
+ this.emacsMode = emacsMode;
+ }
+
+ /**
+ * Parse the output of a jikes compiler
+ * @param reader - Reader used to read jikes's output
+ */
+ protected void parseOutput(BufferedReader reader) throws IOException {
+ if (emacsMode)
+ parseEmacsOutput(reader);
+ else
+ parseStandardOutput(reader);
+ }
+
+ private void parseStandardOutput(BufferedReader reader) throws IOException {
+ String line;
+ String lower;
+ // We assume, that every output, jike does, stands for an error/warning
+ // XXX
+ // Is this correct?
+
+ // TODO:
+ // A warning line, that shows code, which contains a variable
+ // error will cause some trouble. The parser should definitely
+ // be much better.
+
+ while ((line = reader.readLine()) != null) {
+ lower = line.toLowerCase();
+ if (line.trim().equals(""))
+ continue;
+ if (lower.indexOf("error") != -1)
+ setError(true);
+ else if (lower.indexOf("warning") != -1)
+ setError(false);
+ else {
+ // If we don't know the type of the line
+ // and we are in emacs mode, it will be
+ // an error, because in this mode, jikes won't
+ // always print "error", but sometimes other
+ // keywords like "Syntax". We should look for
+ // all those keywords.
+ if (emacsMode)
+ setError(true);
+ }
+ log(line);
+ }
+ }
+
+ private void parseEmacsOutput(BufferedReader reader) throws IOException {
+ // This may change, if we add advanced parsing capabilities.
+ parseStandardOutput(reader);
+ }
+
+ private void setError(boolean err) {
+ error = err;
+ if(error)
+ errorFlag = true;
+ }
+
+ private void log(String line) {
+ if (!emacsMode) {
+ project.log("", (error ? Project.MSG_ERR : Project.MSG_WARN));
+ }
+ project.log(line, (error ? Project.MSG_ERR : Project.MSG_WARN));
+ }
+
+ /**
+ * Indicate if there were errors during the compile
+ * @return if errors ocured
+ */
+ protected boolean getErrorFlag() {
+ return errorFlag;
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/KeySubst.java b/src/main/org/apache/tools/ant/taskdefs/KeySubst.java
new file mode 100644
index 000000000..6ed03e99b
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/KeySubst.java
@@ -0,0 +1,202 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Keyword substitution. Input file is written to output file.
+ * Do not make input file same as output file.
+ * Keywords in input files look like this: @foo@. See the docs for the
+ * setKeys method to understand how to do the substitutions.
+ *
+ * @author Jon S. Stevens jon@clearink.com
+ */
+public class KeySubst extends Task {
+ private File source = null;
+ private File dest = null;
+ private String sep = "*";
+ private Hashtable replacements = new Hashtable();
+
+ /**
+ Do the execution.
+ */
+ public void execute() throws BuildException {
+ project.log("Performing Substitions");
+ if ( source == null || dest == null ) {
+ project.log("Source and destinations must not be null");
+ return;
+ }
+ BufferedReader br = null;
+ BufferedWriter bw = null;
+ try {
+ br = new BufferedReader(new FileReader(source));
+ dest.delete();
+ bw = new BufferedWriter(new FileWriter(dest));
+
+ String line = null;
+ String newline = null;
+ int length;
+ line = br.readLine();
+ while (line != null) {
+ if ( line.length() == 0 ) {
+ bw.newLine();
+ } else {
+ newline = KeySubst.replace ( line, replacements );
+ bw.write ( newline );
+ bw.newLine();
+ }
+ line = br.readLine();
+ }
+ bw.flush();
+ bw.close();
+ br.close();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+ /**
+ Set the source file.
+ */
+ public void setSrc(String s) {
+ this.source=project.resolveFile(s);
+ }
+
+ /**
+ Set the destination file.
+ */
+ public void setDest(String dest) {
+ this.dest = project.resolveFile(dest);
+ }
+
+ /**
+ Sets the seperator between name=value arguments
+ in setKeys(). By default it is "*".
+ */
+ public void setSep(String sep) {
+ this.sep = sep;
+ }
+ /**
+ Format string is like this:
+
+ name=value*name2=value
+
+ Names are case sensitive.
+
+ Use the setSep() method to change the * to something else
+ if you need to use * as a name or value.
+ */
+ public void setKeys(String keys) {
+ if (keys != null && keys.length() > 0) {
+ StringTokenizer tok =
+ new StringTokenizer(keys, this.sep, false);
+ while (tok.hasMoreTokens()) {
+ String token = tok.nextToken().trim();
+ StringTokenizer itok =
+ new StringTokenizer(token, "=", false);
+
+ String name = itok.nextToken();
+ String value = itok.nextToken();
+// project.log ( "Name: " + name );
+// project.log ( "Value: " + value );
+ replacements.put ( name, value );
+ }
+ }
+ }
+
+
+ public static void main(String[] args)
+ {
+ try{
+ Hashtable hash = new Hashtable();
+ hash.put ( "VERSION", "1.0.3" );
+ hash.put ( "b", "ffff" );
+ System.out.println ( KeySubst.replace ( "$f ${VERSION} f ${b} jj $", hash ) );
+ }catch ( Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ Does replacement on text using the hashtable of keys.
+
+ @returns the string with the replacements in it.
+ */
+ public static String replace ( String origString, Hashtable keys )
+ throws BuildException
+ {
+ StringBuffer finalString=new StringBuffer();
+ int index=0;
+ int i = 0;
+ String key = null;
+ while ((index = origString.indexOf("${", i)) > -1) {
+ key = origString.substring(index + 2, origString.indexOf("}", index+3));
+ finalString.append (origString.substring(i, index));
+ if ( keys.containsKey ( key ) ) {
+ finalString.append (keys.get(key));
+ } else {
+ finalString.append ( "${" );
+ finalString.append ( key );
+ finalString.append ( "}" );
+ }
+ i = index + 3 + key.length();
+ }
+ finalString.append (origString.substring(i));
+ return finalString.toString();
+ }
+}
\ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/taskdefs/Mkdir.java b/src/main/org/apache/tools/ant/taskdefs/Mkdir.java
new file mode 100644
index 000000000..e133098c1
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Mkdir.java
@@ -0,0 +1,87 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.File;
+
+
+/**
+ * Creates a given directory.
+ *
+ * @author duncan@x180.com
+ */
+
+public class Mkdir extends Task {
+
+ private String dirName;
+
+ public void execute() throws BuildException {
+ File dir = project.resolveFile(dirName);
+ if (!dir.exists()) {
+ boolean result = dir.mkdirs();
+ if (result == false) {
+ String msg = "Directory " + dirName + " creation was not " +
+ "succesful for an unknown reason";
+ throw new BuildException(msg);
+ }
+ project.log("Created dir: " + dir.getAbsolutePath());
+ }
+ }
+
+ public void setDir(String dirName) {
+ this.dirName = dirName;
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Property.java b/src/main/org/apache/tools/ant/taskdefs/Property.java
new file mode 100644
index 000000000..357b8dff7
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Property.java
@@ -0,0 +1,151 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+import java.util.*;
+/**
+ * Will set a Project property. Used to be a hack in ProjectHelper
+ *
+ * @author costin@dnt.ro
+ */
+public class Property extends Task {
+ String name;
+ String value;
+ String file;
+ String resource;
+
+ // needs to be set at XML-reading time,
+ // no runtime action
+ public void execute() throws BuildException {
+ }
+
+ // XXX ugly - needs to be fixed
+ /** Called after each setter, will set the property at read-time
+ */
+ private void initTimeSetProperty() {
+ try {
+ if((name!=null) && (value!=null) ) {
+ String value1= ProjectHelper.replaceProperties(value, project.getProperties());
+ project.setProperty( name,value1);
+ }
+
+ if( file!=null)
+ loadFile( file );
+
+ if( resource!=null)
+ loadResource( resource );
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public void setName( String name) {
+ this.name=name;
+ initTimeSetProperty();
+ }
+
+ public void setValue(String v) {
+ value=v;
+ initTimeSetProperty();
+ }
+
+ public void setFile(String v) {
+ file=v;
+ initTimeSetProperty();
+ }
+
+ public void setResource(String v) {
+ resource=v;
+ initTimeSetProperty();
+ }
+
+ private void loadFile( String name ) {
+ Properties props = new Properties();
+ project.log("Loading " + name, project.MSG_VERBOSE);
+ try {
+ if( new File(name).exists() )
+ props.load(new FileInputStream( name ));
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ }
+ addProperties( props );
+ }
+
+ private void loadResource( String name ) {
+ Properties props = new Properties();
+ project.log("Resource Loading " + name,
+ project.MSG_VERBOSE);
+ try {
+ InputStream is=this.getClass().getResourceAsStream(name);
+ if(is!=null)
+ props.load(is);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ addProperties( props );
+ }
+
+ private void addProperties( Properties props) {
+ Enumeration e=props.keys();
+ while( e.hasMoreElements() ) {
+ String name=(String)e.nextElement();
+ String value=(String)props.getProperty(name);
+ String value1= ProjectHelper.replaceProperties(value, project.getProperties());
+ project.setProperty( name, value1);
+ }
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Replace.java b/src/main/org/apache/tools/ant/taskdefs/Replace.java
new file mode 100644
index 000000000..7d59898e8
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Replace.java
@@ -0,0 +1,153 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Replaces all the occurrences of the given string token with the given
+ * string value of the indicated file.
+ *
+ * @author Stefano Mazzocchi stefano@apache.org
+ */
+public class Replace extends Task {
+
+ private File src = null;
+ private File dest = null;
+ private String token = null;
+ private String value = "";
+
+ /**
+ * Do the execution.
+ */
+ public void execute() throws BuildException {
+
+ project.log("Replacing " + token + " --> " + value);
+
+ if (src == null || token == null ) {
+ project.log("File and token must not be null");
+ return;
+ }
+
+ if (dest == null) {
+ throw new BuildException("Error creating temp file.");
+ }
+
+ try {
+ BufferedReader br = new BufferedReader(new FileReader(src));
+ BufferedWriter bw = new BufferedWriter(new FileWriter(dest));
+
+ String line;
+
+ while (true) {
+ line = br.readLine();
+ if (line == null) break;
+ if (line.length() != 0) bw.write(replace(line));
+ bw.newLine();
+ }
+
+ bw.flush();
+ bw.close();
+ br.close();
+
+ src.delete();
+ dest.renameTo(src);
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
+ /**
+ * Set the source file.
+ */
+ public void setFile(String file) {
+ this.src = project.resolveFile(file);
+ this.dest = project.resolveFile(file + ".temp");
+ }
+
+ /**
+ * Set the string token to replace.
+ */
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ /**
+ * Set the string value to use as token replacement.
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Perform the token substitution.
+ */
+ private String replace (String orig) {
+ StringBuffer buffer = new StringBuffer();
+ int start = 0, end = 0;
+
+ while ((end = orig.indexOf(token, start)) > -1) {
+ buffer.append(orig.substring(start, end));
+ buffer.append(value);
+ start = end + token.length();
+ }
+
+ buffer.append(orig.substring(start));
+
+ return buffer.toString();
+ }
+}
\ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/taskdefs/Rmic.java b/src/main/org/apache/tools/ant/taskdefs/Rmic.java
new file mode 100644
index 000000000..42aedba47
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Rmic.java
@@ -0,0 +1,113 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+
+/**
+ *
+ *
+ * @author duncan@x180.com
+ */
+
+public class Rmic extends Task {
+
+ private String base;
+ private String classname;
+
+ public void setBase(String base) {
+ this.base = base;
+ }
+
+ public void setClass(String classname) {
+ this.classname = classname;
+ }
+
+ public void execute() throws BuildException {
+ String pathsep = System.getProperty("path.separator");
+ StringBuffer classpath = new StringBuffer();
+ File baseFile = project.resolveFile(base);
+ classpath.append(baseFile.getAbsolutePath());
+ classpath.append(pathsep);
+
+ classpath.append(System.getProperty("java.class.path"));
+
+ // in jdk 1.2, the system classes are not on the visible classpath.
+
+ if (Project.getJavaVersion().startsWith("1.2")) {
+ String bootcp = System.getProperty("sun.boot.class.path");
+ if (bootcp != null) {
+ classpath.append(pathsep);
+ classpath.append(bootcp);
+ }
+ }
+
+ // XXX
+ // need to provide an input stream that we read in from!
+
+ sun.rmi.rmic.Main compiler = new sun.rmi.rmic.Main(System.out, "rmic");
+ String[] args = new String[5];
+ args[0] = "-d";
+ args[1] = baseFile.getAbsolutePath();
+ args[2] = "-classpath";
+ args[3] = classpath.toString();
+ args[4] = classname;
+ compiler.compile(args);
+ }
+
+
+}
+
diff --git a/src/main/org/apache/tools/ant/taskdefs/Taskdef.java b/src/main/org/apache/tools/ant/taskdefs/Taskdef.java
new file mode 100644
index 000000000..ad51bd812
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Taskdef.java
@@ -0,0 +1,96 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+import java.util.*;
+/**
+ * Define a new task - name and class
+ *
+ * @author costin@dnt.ro
+ */
+public class Taskdef extends Task {
+ String name;
+ String value;
+
+ public void execute() throws BuildException {
+ try {
+ if (name==null || value==null ) {
+ String msg = "name or class attributes of taskdef element "
+ + "are undefined";
+ throw new BuildException(msg);
+ }
+ try {
+ Class taskClass = Class.forName(value);
+ project.addTaskDefinition(name, taskClass);
+ } catch (ClassNotFoundException cnfe) {
+ String msg = "taskdef class " + value +
+ " cannot be found";
+ throw new BuildException(msg);
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public void setName( String name) {
+ this.name=name;
+ }
+
+ public void setClass(String v) {
+ value=v;
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Tstamp.java b/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
new file mode 100644
index 000000000..f2ad2d714
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
@@ -0,0 +1,91 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+import java.io.*;
+import java.util.*;
+/**
+ * Will set TSTAMP and DSTAMP
+ *
+ * @author costin@dnt.ro
+ */
+public class Tstamp extends Task {
+
+ public void execute() throws BuildException {
+ try {
+ Calendar d=Calendar.getInstance();
+ StringBuffer tstamp=new StringBuffer();
+ tstamp.append( d.get(Calendar.YEAR));
+ if(d.get(Calendar.MONTH) < 9) tstamp.append("0");
+ tstamp.append( 1+d.get(Calendar.MONTH));
+
+ if( d.get(Calendar.DAY_OF_MONTH) < 10 ) tstamp.append("0");
+ tstamp.append(d.get(Calendar.DAY_OF_MONTH));
+ project.setProperty( "DSTAMP" , tstamp.toString());
+
+ if( d.get(Calendar.HOUR_OF_DAY) < 10 ) tstamp.append("0");
+ tstamp.append( d.get(Calendar.HOUR_OF_DAY));
+
+ if( d.get(Calendar.MINUTE) < 10 ) tstamp.append("0");
+ tstamp.append(d.get(Calendar.MINUTE));
+ project.setProperty( "TSTAMP" , tstamp.toString());
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+
+ }
+
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Zip.java b/src/main/org/apache/tools/ant/taskdefs/Zip.java
new file mode 100644
index 000000000..f2c3a3158
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/Zip.java
@@ -0,0 +1,230 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.*;
+
+import java.io.*;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.zip.*;
+
+/**
+ * Same as the Jar task, but creates .zip files without the MANIFEST
+ * stuff that .jar files have.
+ *
+ * @author James Davidson duncan@x180.com
+ * @author Jon S. Stevens jon@clearink.com
+ */
+
+public class Zip extends Task {
+
+ private File zipFile;
+ private File baseDir;
+ private Vector items = new Vector();
+ private File manifest;
+ private Vector ignoreList = new Vector();
+ private boolean allItems = false;
+ protected String archiveType = "zip";
+
+ /**
+ This is the name/location of where to
+ create the .zip file.
+ */
+ public void setZipfile(String zipFilename) {
+ zipFile = project.resolveFile(zipFilename);
+ }
+ /**
+ This is the base directory to look in for
+ things to zip.
+ */
+ public void setBasedir(String baseDirname) {
+ baseDir = project.resolveFile(baseDirname);
+ }
+
+ /**
+ Set this to be the items in the base directory
+ that you want to include in the zip archive.
+ (ie: items="foo, bar, ack.html, f.java").
+ You can also specify "*" for the items (ie: items="*")
+ and it will include all the items in the base directory.
+ Do not try to have items="*, foo". Also note that
+ you can specify items to ignore with setIgnore and they
+ will still be ignored if you choose "*". Sometimes
+ ignore lists are easier than include lists. ;-)
+ */
+ public void setItems(String itemString) {
+ if ( itemString.equals("*") ) {
+ allItems = true;
+ } else {
+ StringTokenizer tok = new StringTokenizer(itemString, ",", false);
+ while (tok.hasMoreTokens()) {
+ items.addElement(tok.nextToken().trim());
+ }
+ }
+ }
+ /**
+ List of filenames and directory names to not
+ include in the final .jar file. They should be either
+ , or " " (space) separated.
+
+ For example:
+
+ ignore="package.html, foo.class"
+
+ The ignored files will be logged.
+
+ @author Jon S. Stevens jon@clearink.com
+ */
+ public void setIgnore(String ignoreString) {
+ ignoreString = ignoreString;
+ if (ignoreString != null && ignoreString.length() > 0) {
+ StringTokenizer tok =
+ new StringTokenizer(ignoreString, ", ", false);
+ while (tok.hasMoreTokens()) {
+ ignoreList.addElement ( tok.nextToken().trim() );
+ }
+ }
+ }
+
+ public void execute() throws BuildException {
+ project.log("Building " + archiveType + ": " + zipFile.getAbsolutePath());
+
+ try {
+ ZipOutputStream zOut = new ZipOutputStream(new FileOutputStream(zipFile));
+ initZipOutputStream(zOut);
+
+ if ( allItems ) {
+ String[] lst = baseDir.list();
+ for (int i=0;i