diff --git a/bootstrap.bat b/bootstrap.bat new file mode 100755 index 000000000..0bcc1e59a --- /dev/null +++ b/bootstrap.bat @@ -0,0 +1,67 @@ +@ECHO OFF +echo BOOTSTRAPPING ANT DISTRIBUTION + +set C=%CLASSPATH%;..\jakarta-tools\projectx-tr2.jar +set SRCDIR=src\main\org\apache\tools\ant +set TMPDIR=tmp + +if "%OS%" == "Windows_NT" goto nt +goto windows + +:doneOs + +rem Delete temp directory if it exists +if exist %TMPDIR%\nul %RMDIRCMD% %TMPDIR% nul + +rem make the temp directory +mkdir %TMPDIR% + +echo ** COMPILING ANT CLASSES + +rem Compile the classes into the temp directory +javac -classpath "%C%" -d %TMPDIR% %SRCDIR%\*.java + +rem Reset classpath to include base ant class files +set C=%TMPDIR%;%C% + +rem Compile sub classes into the temp directory +javac -classpath "%C%" -d %TMPDIR% %SRCDIR%\taskdefs\*.java + +echo ** COPYING REQUIRED FILES + +rem Copy all the property/manifest files into the temp directory + +%COPYCMD% src\main\org\apache\tools\ant\taskdefs\defaults.properties %TMPDIR%\org\apache\tools\ant\taskdefs +%COPYCMD% src\main\org\apache\tools\ant\parser.properties %TMPDIR%\org\apache\tools\ant + +echo ** BUILDING ANT DISTRIBUTION + +rem Build the distribution using the newly compiled classes in the temp directory +java -classpath "%C%" org.apache.tools.ant.Main jar %1 %2 %3 %4 %5 + +echo ** CLEANING UP BUILD DIRECTORIES + +java -classpath "%C%" org.apache.tools.ant.Main clean %1 %2 %3 %4 %5 + +rem remove the temp directory +%RMDIRCMD% %TMPDIR% + +goto end + +rem Set system dependent commands below +:windows +echo ** CONFIGURING COMMANDS FOR WINDOWS 9x SYSTEM +set RMDIRCMD=deltree /Y +set COPYCMD=copy +goto doneOs + +:nt +echo ** CONFIGURING COMMANDS FOR NT SYSTEM +set RMDIRCMD=rmdir /s /q +set COPYCMD=copy +goto doneOs + +:end + +echo ** DONE BOOTSTRAPPING ANT DISTRIBUTION + diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 000000000..c887d3c1c --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,25 @@ +if [ -f $HOME/.antrc ] ; then + . $HOME/.antrc +fi + +SRCDIR=src/main/org/apache/tools/ant +CLASSDIR=classes +CLASSPATH=${CLASSPATH}:${JAVA_HOME}/lib/classes.zip:${JAVA_HOME}/lib/tools.jar +CLASSPATH=${CLASSPATH}:../jakarta-tomcat/projectx-tr2.jar:src:${CLASSDIR} + +mkdir -p ${CLASSDIR} + +export CLASSPATH +echo $CLASSPATH + +javac -d ${CLASSDIR} ${SRCDIR}/*.java +javac -d ${CLASSDIR} ${SRCDIR}/taskdefs/*.java + +cp src/main/org/apache/tools/ant/taskdefs/defaults.properties ${CLASSDIR}/org/apache/tools/ant/taskdefs +cp src/main/org/apache/tools/ant/parser.properties ${CLASSDIR}/org/apache/tools/ant + +java org.apache.tools.ant.Main jar +java org.apache.tools.ant.Main clean + +rm -rf ${CLASSDIR} + diff --git a/build.bat b/build.bat new file mode 100755 index 000000000..ec5299aeb --- /dev/null +++ b/build.bat @@ -0,0 +1,3 @@ +@echo off +REM convience bat file to build with +java -classpath "%CLASSPATH%;..\jakarta-tools\ant.jar;..\jakarta-tools\projectx-tr2.jar" org.apache.tools.ant.Main %1 %2 %3 %4 %5 diff --git a/build.sh b/build.sh new file mode 100755 index 000000000..2087d6908 --- /dev/null +++ b/build.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +ADDL_CLASSPATH=./../jakarta-tools/ant.jar:./../jakarta-tools/projectx-tr2.jar + +if [ "$CLASSPATH" != "" ] ; then + CLASSPATH=$CLASSPATH:$ADDL_CLASSPATH +else + CLASSPATH=$ADDL_CLASSPATH +fi +export CLASSPATH + +echo Building with classpath $CLASSPATH + +java org.apache.tools.ant.Main $* diff --git a/build.xml b/build.xml new file mode 100644 index 000000000..b905aa248 --- /dev/null +++ b/build.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 000000000..6a5bcfe30 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,51 @@ + + +BuildTool Readme + + + + +

BuildTool

+

BuildTool is a Java based build tool. In theory it is kind of like make without + makes wrinkles.

+

Why?

+

Why another build tool when there is already make, gnumake, nmake, jam, and + others? Because all of those tools have limitations that its original author + couldn't live with when developming software across multiple platforms. Make + like tools are inherently shell based. They evaluate a set of dependencies and + then execute commands not unlike what you would issue on a shell. This means + that you can easily extend these tools by using or writing any program for the + OS that you are working on. However, this also means that you limit yourself + to the OS, or at least the OS type such as Unix, that you are working on.

+

Makefiles are inherently evil as well. Anybody who has worked on them for any + time has run into the dreaded tab problem. "Is my command not executing + because I have a space in front of my tab!!!" said the original author + of BuildTool way too many times. Tools like Jam took care of this to a great + degree, but still use yet another format to use and remember.

+

BuildTool is different. Instead a model where it is extended with shell based + commands, it is extended using Java classes. Instead of writing shell commands, + the configuration files are XML based calling out a target tree where various + tasks get executed. Each task is run by an object which implments a particular + Task interface.

+

Granted, this removes some of the expressive power that is inherent by being + able to construct a shell command such as `find . -name foo -exec rm {}` but + it gives you the ability to be cross platform. To work anywhere and everywhere.And + hey, if you really need to execute a shell command, BuildTool has an exec rule + that allows different commands to be executed based on the OS that it is executing + on.

+

How?

+

To get started using BuildTool check out the following topics:

+ +

License

+

Feedback

+

To provide feedback on this software, please send mail to duncan@x180.com.

+
+

Java is a trademark of Sun Microsystems.

+ + diff --git a/src/bin/ant b/src/bin/ant new file mode 100644 index 000000000..ab91889d3 --- /dev/null +++ b/src/bin/ant @@ -0,0 +1,52 @@ +#! /bin/sh + +if [ -f $HOME/.antrc ] ; then + . $HOME/.antrc +fi + +if [ "$ANT_HOME" = "" ] ; then + # try to find ANT + if [ -d /opt/ant ] ; then + ANT_HOME=/opt/ant + fi + + if [ -d ${HOME}/opt/ant ] ; then + ANT_HOME=${HOME}/opt/ant + fi + + ## resolve links - $0 may be a link to ant's home + PRG=$0 + progname=`basename $0` + + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '.*/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname $PRG`/$link" + fi + done + + ANT_HOME=`dirname "$PRG"`/.. + +fi + +# Allow .antrc to specifiy flags to java cmd +if [ "$JAVACMD" = "" ] ; then + JAVACMD=java +fi + +# Use the original tools.jar if available +if [ ! "$JAVA_HOME" = "" ] ; then + CLASSPATH=${JAVA_HOME}/lib/tools.jar:$CLASSPATH + CLASSPATH=${JAVA_HOME}/lib/classes.zip:$CLASSPATH +fi + + +CLASSPATH=${ANT_HOME}/lib/xml.jar:$CLASSPATH +CLASSPATH=${ANT_HOME}/lib/ant.jar:$CLASSPATH +CLASSPATH=${ANT_HOME}/lib/moo.jar:$CLASSPATH +export CLASSPATH + +$JAVACMD -Dant.home=${ANT_HOME} org.apache.tools.ant.Main $@ diff --git a/src/bin/ant.bat b/src/bin/ant.bat new file mode 100755 index 000000000..320195733 --- /dev/null +++ b/src/bin/ant.bat @@ -0,0 +1,31 @@ +@echo off +@setlocal +if "%ANT_HOME%"=="" goto checkProgFiles +goto checkJavaHome + +:checkProgFiles +rem check for ant on system drive +if not exist "%SystemDrive%\Program Files\ant" goto checkSystemDrive + +set ANT_HOME=%SystemDrive%\Program Files\ant +goto checkJavaHome + +:checkSystemDrive +if not exist "%SystemDrive%\ant" goto noAntHome +set ANT_HOME=%SystemDrive%\ant +goto checkJavaHome + +:noAntHome +echo ANT_HOME is not set and ant could not be located +goto end + +:checkJavaHome +if "%JAVA_HOME%" == "" goto runAnt +set CLASSPATH=%JAVA_HOME%\lib\tools.jar;%CLASSPATH% + +:runAnt +set CLASSPATH=%ANT_HOME%\lib\ant.jar;%ANT_HOME%\lib\xml.jar;%CLASSPATH% +java -Dant.home="%ANT_HOME%" org.apache.tools.ant.Main %1 %2 %3 %4 %5 %6 %7 %8 %9 + +:end +@endlocal diff --git a/src/bin/antRun b/src/bin/antRun new file mode 100644 index 000000000..45bc847d3 --- /dev/null +++ b/src/bin/antRun @@ -0,0 +1,14 @@ +#! /bin/sh + +# Args: DIR command +cd $1 +CMD=$2 +shift +shift + +if test -e $CMD.sh; then + CMD="sh $CMD.sh" +fi + +echo $CMD $@ +$CMD $@ 2>&1 diff --git a/src/bin/antRun.bat b/src/bin/antRun.bat new file mode 100755 index 000000000..b6dc95e6e --- /dev/null +++ b/src/bin/antRun.bat @@ -0,0 +1,3 @@ +cd %1 +echo %2 %3 %4 %5 %6 %7 %8 %9 +%2 %3 %4 %5 %6 %7 %8 %9 2>&1 diff --git a/src/etc/ant.spec b/src/etc/ant.spec new file mode 100644 index 000000000..8681c267c --- /dev/null +++ b/src/etc/ant.spec @@ -0,0 +1,53 @@ +Summary: Java build tool +Name: ant +Version: 1.0 +Release: 0 +Group: Development/Tools +Copyright: Apache - free +Provides: ant +Url: http://jakarta.apache.org + +Source: http://jakarta.apache.org/builds/nightly/ant/jakarta-tools.src.zip +Prefix: /opt + +%description +Platform-independent build tool for java. +Used by tomcat/jakarta projects. + +%prep +rm -rf ${RPM_BUILD_DIR}/jakarta-tools +unzip -x $RPM_SOURCE_DIR/jakarta-tools.src.zip + +%build +cd ${RPM_BUILD_DIR}/jakarta-tools +cd ant +sh bootstrap.sh +sh build.sh + +%install +cd ${RPM_BUILD_DIR}/jakarta-tools +cd ant +sh build.sh -Ddist.dir /opt dist + +%clean + +%post +ln -s /opt/ant/bin/ant /usr/bin + +%preun + +%files +## %defattr(-,root,root) +%dir /opt/ant +%dir /opt/ant/bin +%dir /opt/ant/lib +%dir /opt/ant/docs +/opt/ant/lib/ant.jar +/opt/ant/lib/xml.jar +/opt/ant/lib/moo.jar +%config /opt/ant/lib/build.xml +/opt/ant/bin/ant +/opt/ant/bin/antRun +/opt/ant/docs/index.html + +%changelog diff --git a/src/etc/manifest b/src/etc/manifest new file mode 100644 index 000000000..e6d89928e --- /dev/null +++ b/src/etc/manifest @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Main-Class: org.apache.tools.ant.Main +Class-Path: javac.jar projectx-tr2.jar + + diff --git a/src/etc/pkginfo b/src/etc/pkginfo new file mode 100644 index 000000000..cad292582 --- /dev/null +++ b/src/etc/pkginfo @@ -0,0 +1,9 @@ +PKG="ASFant" +NAME="Apache Ant build tool" +VERSION="1.0" +ARCH="sparc i386" +CLASSES="none" +CATEGORY="utility" +VENDOR="Apache" +EMAIL="costin@eng.sun.com" +BASEDIR=/ diff --git a/src/etc/prototype b/src/etc/prototype new file mode 100644 index 000000000..abd374b7e --- /dev/null +++ b/src/etc/prototype @@ -0,0 +1,12 @@ +i pkginfo +d none /opt/ant 0755 costin other +d none /opt/ant/lib 0755 costin staff +f none /opt/ant/lib/ant.jar 0644 costin staff +f none /opt/ant/lib/xml.jar 0644 costin staff +f none /opt/ant/lib/moo.jar 0644 costin staff +f none /opt/ant/lib/build.xml 0644 costin staff +d none /opt/ant/bin 0755 costin staff +f none /opt/ant/bin/ant 0755 costin staff +f none /opt/ant/bin/antRun 0755 costin staff +d none /opt/ant/docs 0755 costin staff +f none /opt/ant/docs/index.html 0644 costin staff diff --git a/src/main/com/ice/tar/InvalidHeaderException.java b/src/main/com/ice/tar/InvalidHeaderException.java new file mode 100644 index 000000000..16deb2e78 --- /dev/null +++ b/src/main/com/ice/tar/InvalidHeaderException.java @@ -0,0 +1,43 @@ +/* +** 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 +InvalidHeaderException extends Exception + { + + public + InvalidHeaderException() + { + super(); + } + + public + InvalidHeaderException( String msg ) + { + super( msg ); + } + + } + diff --git a/src/main/com/ice/tar/TarArchive.java b/src/main/com/ice/tar/TarArchive.java new file mode 100644 index 000000000..2f26f511a --- /dev/null +++ b/src/main/com/ice/tar/TarArchive.java @@ -0,0 +1,472 @@ +/* +** 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.*; + +/** + * The TarArchive class implements the concept of a + * tar archive. A tar archive is a series of entries, each of + * which represents a file system object. Each entry in + * the archive consists of a header record. Directory entries + * consist only of the header record, and are followed by entries + * for the directory's contents. File entries consist of a + * header record followed by the number of records needed to + * contain the file's contents. All entries are written on + * record boundaries. Records are 512 bytes long. + * + * TarArchives are instantiated in either read or write mode, + * based upon whether they are instantiated with an InputStream + * or an OutputStream. Once instantiated TarArchives read/write + * mode can not be changed. + * + * There is currently no support for random access to tar archives. + * However, it seems that subclassing TarArchive, and using the + * TarBuffer.getCurrentRecordNum() and TarBuffer.getCurrentBlockNum() + * methods, this would be rather trvial. + * + * @version $Revision$ + * @author Timothy Gerard Endres, + * time@ice.com. + * @see TarBuffer + * @see TarHeader + * @see TarEntry + */ + + +public class +TarArchive extends Object + { + public static final int RECORDSIZE = 512; + + protected boolean verbose; + protected boolean debug; + protected boolean keepOldFiles; + + protected int userId; + protected String userName; + protected int groupId; + protected String groupName; + + protected String pathPrefix; + + protected int recordSize; + protected byte[] recordBuf; + + protected TarBuffer buffer; + + protected TarProgressDisplay progressDisplay; + + + public + TarArchive( InputStream inStream ) + { + this( inStream, TarBuffer.DEFAULT_BLKSIZE ); + } + + public + TarArchive( InputStream inStream, int blockSize ) + { + this( inStream, blockSize, TarArchive.RECORDSIZE ); + } + + public + TarArchive( InputStream inStream, int blockSize, int recordSize ) + { + this.initialize( recordSize ); + this.buffer = new TarBuffer( this, inStream, blockSize ); + } + + public + TarArchive( OutputStream outStream ) + { + this( outStream, TarBuffer.DEFAULT_BLKSIZE ); + } + + public + TarArchive( OutputStream outStream, int blockSize ) + { + this( outStream, blockSize, TarArchive.RECORDSIZE ); + } + + public + TarArchive( OutputStream outStream, int blockSize, int recordSize ) + { + this.initialize( recordSize ); + this.buffer = new TarBuffer( this, outStream, blockSize ); + } + + public void + initialize( int recordSize ) + { + this.pathPrefix = null; + this.recordSize = recordSize; + this.recordBuf = new byte[ recordSize ]; + + this.userId = 0; + this.userName = ""; + this.groupId = 0; + this.groupName = ""; + + this.debug = false; + this.verbose = false; + this.keepOldFiles = false; + this.progressDisplay = null; + } + + public void + setDebug( boolean debugF ) + { + this.debug = debugF; + } + + public void + setBufferDebug( boolean debug ) + { + this.buffer.setDebug( debug ); + } + + public boolean + isVerbose() + { + return this.verbose; + } + + public void + setVerbose( boolean verbose ) + { + this.verbose = verbose; + } + + public void + setTarProgressDisplay( TarProgressDisplay display ) + { + this.progressDisplay = display; + } + + public void + setKeepOldFiles( boolean keepOldFiles ) + { + this.keepOldFiles = keepOldFiles; + } + + public void + setUserInfo( + int userId, String userName, + int groupId, String groupName ) + { + this.userId = userId; + this.userName = userName; + this.groupId = groupId; + this.groupName = groupName; + } + + public int + getUserId() + { + return this.userId; + } + + public String + getUserName() + { + return this.userName; + } + + public int + getGroupId() + { + return this.groupId; + } + + public String + getGroupName() + { + return this.groupName; + } + + public void + closeArchive() + throws IOException + { + this.buffer.flushBlock(); + this.buffer.closeBuffer(); + } + + public int + getRecordSize() + { + return this.recordSize; + } + + public TarEntry + parseArchive() + { + return null; + } + + public TarEntry + parseEntry() + { + return null; + } + + public void + extractArchive() + { + } + + public void + listContents() + throws IOException, InvalidHeaderException + { + TarEntry entry; + byte[] headerBuf; + + for ( ; ; ) + { + headerBuf = this.buffer.readRecord(); + if ( headerBuf == null ) + { + if ( this.debug ) + { + System.err.println( "READ NULL RECORD" ); + } + break; + } + + if ( this.isEOFRecord( headerBuf ) ) + { + if ( this.debug ) + { + System.err.println( "READ EOF RECORD" ); + } + break; + } + + try { + entry = new TarEntry( this, headerBuf ); + } + catch ( InvalidHeaderException ex ) + { + throw new InvalidHeaderException + ( "bad header in block " + + this.buffer.getCurrentBlockNum() + + " record " + + this.buffer.getCurrentRecordNum() ); + } + + if ( this.progressDisplay != null ) + this.progressDisplay.showTarProgressMessage + ( entry.getName() ); + + this.buffer.skipBytes( (int)entry.getSize() ); + } + } + + public void + extractContents( File destDir ) + throws IOException, InvalidHeaderException + { + TarEntry entry; + byte[] headerBuf; + + for ( ; ; ) + { + headerBuf = this.buffer.readRecord(); + if ( headerBuf == null ) + { + if ( this.debug ) + { + System.err.println( "READ NULL RECORD" ); + } + break; + } + + if ( this.isEOFRecord( headerBuf ) ) + { + if ( this.debug ) + { + System.err.println( "READ EOF RECORD" ); + } + break; + } + + try { + entry = new TarEntry( this, headerBuf ); + } + catch ( InvalidHeaderException ex ) + { + throw new InvalidHeaderException + ( "bad header in block " + + this.buffer.getCurrentBlockNum() + + " record " + + this.buffer.getCurrentRecordNum() ); + } + + this.extractEntry( destDir, entry ); + } + } + + public void + extractEntry( File destDir, TarEntry entry ) + throws IOException + { + if ( this.verbose ) + { + if ( this.progressDisplay != null ) + this.progressDisplay.showTarProgressMessage + ( entry.getName() ); + } + + File subDir = + new File( destDir, entry.getName() ); + + if ( entry.isDirectory() ) + { + if ( ! subDir.exists() ) + { + if ( ! subDir.mkdirs() ) + { + throw new IOException + ( "error making directory path '" + + subDir.getPath() + "'" ); + } + } + } + else + { + String name = entry.getName().toString(); + name = name.replace( '/', File.separatorChar ); + + File destFile = new File( destDir, name ); + + if ( this.keepOldFiles && destFile.exists() ) + { + if ( this.verbose ) + { + if ( this.progressDisplay != null ) + this.progressDisplay.showTarProgressMessage + ( "not overwriting " + entry.getName() ); + } + } + else + { + FileOutputStream out = + new FileOutputStream( destFile ); + + for ( int num = (int)entry.getSize() ; num > 0 ; ) + { + byte[] record = this.buffer.readRecord(); + + int wNum = + ( num < record.length ) + ? num : record.length; + + out.write( record, 0, wNum ); + + num -= wNum; + } + + out.close(); + } + } + } + + public boolean + isEOFRecord( byte[] record ) + { + for ( int i = 0 ; i < this.recordSize ; ++i ) + if ( record[i] != 0 ) + return false; + + return true; + } + + public void + writeEOFRecord() + throws IOException + { + for ( int i = 0 ; i < this.recordSize ; ++i ) + this.recordBuf[i] = 0; + this.buffer.writeRecord( this.recordBuf ); + } + + public void + writeEntry( TarEntry entry, boolean recurse ) + throws IOException + { + if ( this.verbose ) + { + if ( this.progressDisplay != null ) + this.progressDisplay.showTarProgressMessage + ( entry.getName() ); + } + + entry.writeEntryHeader( this.recordBuf ); + this.buffer.writeRecord( this.recordBuf ); + + if ( entry.isDirectory() ) + { + TarEntry[] list = entry.getDirectoryEntries(); + + for ( int i = 0 ; i < list.length ; ++i ) + { + this.writeEntry( list[i], recurse ); + } + } + else + { + entry.writeEntryContents( this.buffer ); + } + } + + public TarEntry + readEntry() + throws IOException, InvalidHeaderException + { + TarEntry result = null; + + byte[] header = this.readRecord(); + + TarEntry entry = new TarEntry( this, header ); + + return entry; + } + + public byte[] + readRecord() + throws IOException + { + return this.buffer.readRecord(); + } + + public void + writeRecord( byte[] record ) + throws IOException + { + this.buffer.writeRecord( record ); + } + + } + diff --git a/src/main/com/ice/tar/TarBuffer.java b/src/main/com/ice/tar/TarBuffer.java new file mode 100644 index 000000000..84712f09e --- /dev/null +++ b/src/main/com/ice/tar/TarBuffer.java @@ -0,0 +1,331 @@ +/* +** 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.*; + + +/** + * 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