Browse Source

Zap the yet to be converted ant1 code

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272460 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 23 years ago
parent
commit
f2733242f3
100 changed files with 0 additions and 20830 deletions
  1. +0
    -197
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/ANTLR.java
  2. +0
    -291
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Cab.java
  3. +0
    -23
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/ClassArgument.java
  4. +0
    -303
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/DependSet.java
  5. +0
    -108
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Echo.java
  6. +0
    -488
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Entry.java
  7. +0
    -36
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/FileDir.java
  8. +0
    -381
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Get.java
  9. +0
    -1061
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/IContract.java
  10. +0
    -358
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Javah.java
  11. +0
    -101
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/MatchingTask.java
  12. +0
    -770
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/NetRexxC.java
  13. +0
    -323
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/PathConvert.java
  14. +0
    -141
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Property.java
  15. +0
    -128
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Rpm.java
  16. +0
    -836
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/SQLExec.java
  17. +0
    -155
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Script.java
  18. +0
    -256
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Tstamp.java
  19. +0
    -181
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/WaitFor.java
  20. +0
    -97
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Ear.java
  21. +0
    -286
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Expand.java
  22. +0
    -395
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Jar.java
  23. +0
    -306
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Tar.java
  24. +0
    -48
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/TarFileSet.java
  25. +0
    -66
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/TarLongFileMode.java
  26. +0
    -53
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Untar.java
  27. +0
    -54
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Unzip.java
  28. +0
    -109
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/War.java
  29. +0
    -22
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/WhenEmpty.java
  30. +0
    -895
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Zip.java
  31. +0
    -98
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/ZipFileSet.java
  32. +0
    -98
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/ZipScanner.java
  33. +0
    -79
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/conditions/Http.java
  34. +0
    -66
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/conditions/Socket.java
  35. +0
    -64
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/exec/ExecuteStreamHandler.java
  36. +0
    -635
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/i18n/Translate.java
  37. +0
    -45
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/CompilerAdapter.java
  38. +0
    -155
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/CompilerAdapterFactory.java
  39. +0
    -468
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/DefaultCompilerAdapter.java
  40. +0
    -107
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Gcj.java
  41. +0
    -43
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/ImplementationSpecificArgument.java
  42. +0
    -753
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Javac.java
  43. +0
    -69
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Javac12.java
  44. +0
    -64
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Javac13.java
  45. +0
    -42
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/JavacExternal.java
  46. +0
    -134
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Jikes.java
  47. +0
    -97
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Jvc.java
  48. +0
    -135
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Kjc.java
  49. +0
    -44
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Sj.java
  50. +0
    -175
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javacc/JJTree.java
  51. +0
    -269
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javacc/JavaCC.java
  52. +0
    -21
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/AccessType.java
  53. +0
    -73
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/DocletInfo.java
  54. +0
    -34
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/DocletParam.java
  55. +0
    -65
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/GroupArgument.java
  56. +0
    -23
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/Html.java
  57. +0
    -1020
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/Javadoc.java
  58. +0
    -47
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/LinkArgument.java
  59. +0
    -28
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/PackageName.java
  60. +0
    -25
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/SourceFile.java
  61. +0
    -21
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jdepend/FormatAttribute.java
  62. +0
    -261
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jdepend/JDependTask.java
  63. +0
    -484
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/JspC.java
  64. +0
    -294
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/WLJspc.java
  65. +0
    -46
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/compilers/CompilerAdapter.java
  66. +0
    -103
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/compilers/CompilerAdapterFactory.java
  67. +0
    -91
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/compilers/DefaultCompilerAdapter.java
  68. +0
    -90
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/compilers/JasperC.java
  69. +0
    -230
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/AggregateTransformer.java
  70. +0
    -133
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/BaseTest.java
  71. +0
    -187
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/BatchTest.java
  72. +0
    -272
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/BriefJUnitResultFormatter.java
  73. +0
    -100
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/CompoundIterator.java
  74. +0
    -239
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/DOMElementWriter.java
  75. +0
    -226
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/DOMUtil.java
  76. +0
    -244
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/FormatterElement.java
  77. +0
    -59
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitResultFormatter.java
  78. +0
    -717
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitTask.java
  79. +0
    -186
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitTest.java
  80. +0
    -643
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitTestRunner.java
  81. +0
    -69
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitVersionHelper.java
  82. +0
    -37
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/NodeListImpl.java
  83. +0
    -253
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/PlainJUnitResultFormatter.java
  84. +0
    -190
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/SummaryJUnitResultFormatter.java
  85. +0
    -115
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/XMLConstants.java
  86. +0
    -278
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/XMLJUnitResultFormatter.java
  87. +0
    -336
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/XMLResultAggregator.java
  88. +0
    -38
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/Xalan1Executor.java
  89. +0
    -40
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/Xalan2Executor.java
  90. +0
    -127
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/XalanExecutor.java
  91. +0
    -117
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/Attribute.java
  92. +0
    -175
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/Manifest.java
  93. +0
    -64
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/ManifestException.java
  94. +0
    -27
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/ManifestMode.java
  95. +0
    -198
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/ManifestTask.java
  96. +0
    -242
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/ManifestUtil.java
  97. +0
    -334
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/Section.java
  98. +0
    -3
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/default.mf
  99. +0
    -54
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/net/Action.java
  100. +0
    -63
      proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/net/AntTelnetClient.java

+ 0
- 197
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/ANTLR.java View File

@@ -1,197 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.net.URL;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.java.ExecuteJava;
import org.apache.myrmidon.framework.nativelib.Argument;
import org.apache.myrmidon.framework.file.Path;

/**
* ANTLR task.
*
* @author <a href="mailto:emeade@geekfarm.org">Erik Meade</a>
* @author <a href="mailto:sbailliez@apache.org>Stephane Bailliez</a>
*/
public class ANTLR
extends AbstractTask
{
private final ExecuteJava m_exe = new ExecuteJava();

/**
* where to output the result
*/
private File m_outputDirectory;

/**
* the file to process
*/
private File m_target;

/**
* The working directory of the process
*
* @param dir The new Dir value
*/
public void setDir( final File dir )
{
m_exe.setWorkingDirectory( dir );
}

public void setFork( final boolean fork )
{
m_exe.setFork( fork );
}

public void setOutputdirectory( final File outputDirectory )
{
m_outputDirectory = outputDirectory;
}

public void setTarget( final File target )
{
m_target = target;
}

/**
* <code>&lt;classpath&gt;</code> allows classpath to be set because a
* directory might be given for Antlr debug...
*/
public void addClasspath( final Path path )
{
m_exe.getClassPath().add( path );
}

/**
* Create a new JVM argument. Ignored if no JVM is forked.
*
* @see #setFork(boolean)
*/
public void addJvmarg( final Argument argument )
{
m_exe.getVmArguments().addArgument( argument );
}

public void execute()
throws TaskException
{
//Adds the jars or directories containing Antlr this should make the forked
//JVM work without having to specify it directly.
addClasspathEntry( "/antlr/Tool.class" );

validateAttributes();

//TODO: use ANTLR to parse the grammer file to do this.
if( m_target.lastModified() <= getGeneratedFile().lastModified() )
{
return;
}

m_exe.setClassName( "antlr.Tool" );

m_exe.getArguments().addArgument( "-o" );
m_exe.getArguments().addArgument( m_outputDirectory );
m_exe.getArguments().addArgument( m_target );

m_exe.execute( getContext() );
}

/**
* Search for the given resource and add the directory or archive that
* contains it to the classpath. <p>
*
* Doesn't work for archives in JDK 1.1 as the URL returned by getResource
* doesn't contain the name of the archive.</p>
*
* @param resource The feature to be added to the ClasspathEntry attribute
*/
protected void addClasspathEntry( final String resource )
{
URL url = getClass().getResource( resource );
if( url != null )
{
String u = url.toString();
if( u.startsWith( "jar:file:" ) )
{
int pling = u.indexOf( "!" );
String jarName = u.substring( 9, pling );
getContext().debug( "Implicitly adding " + jarName + " to classpath" );
m_exe.getClassPath().addLocation( new File( jarName ) );
}
else if( u.startsWith( "file:" ) )
{
int tail = u.indexOf( resource );
String dirName = u.substring( 5, tail );
getContext().debug( "Implicitly adding " + dirName + " to classpath" );
m_exe.getClassPath().addLocation( new File( dirName ) );
}
else
{
getContext().debug( "Don\'t know how to handle resource URL " + u );
}
}
else
{
getContext().debug( "Couldn\'t find " + resource );
}
}

private File getGeneratedFile()
throws TaskException
{
String generatedFileName = null;
try
{
BufferedReader in = new BufferedReader( new FileReader( m_target ) );
String line;
while( ( line = in.readLine() ) != null )
{
int extendsIndex = line.indexOf( " extends " );
if( line.startsWith( "class " ) && extendsIndex > -1 )
{
generatedFileName = line.substring( 6, extendsIndex ).trim();
break;
}
}
in.close();
}
catch( Exception e )
{
throw new TaskException( "Unable to determine generated class", e );
}
if( generatedFileName == null )
{
throw new TaskException( "Unable to determine generated class" );
}
return new File( m_outputDirectory, generatedFileName + ".java" );
}

private void validateAttributes()
throws TaskException
{
if( m_target == null || !m_target.isFile() )
{
throw new TaskException( "Invalid target: " + m_target );
}

// if no output directory is specified, used the target's directory
if( m_outputDirectory == null )
{
m_outputDirectory = m_target.getParentFile();
}
if( !m_outputDirectory.isDirectory() )
{
throw new TaskException( "Invalid output directory: " + m_outputDirectory );
}
}
}

+ 0
- 291
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Cab.java View File

@@ -1,291 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.aut.nativelib.Os;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.nativelib.Execute;
import org.apache.myrmidon.framework.FileSet;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.tools.todo.types.ScannerUtil;

/**
* Create a CAB archive.
*
* @author <a href="mailto:rvaughn@seaconinc.com">Roger Vaughn</a>
*/
public class Cab
extends MatchingTask
{
private ArrayList m_filesets = new ArrayList();
private boolean m_compress = true;
private File m_baseDir;
private File m_cabFile;
private String m_options;

/**
* This is the base directory to look in for things to cab.
*
* @param baseDir The new Basedir value
*/
public void setBasedir( final File baseDir )
{
m_baseDir = baseDir;
}

/**
* This is the name/location of where to create the .cab file.
*
* @param cabFile The new Cabfile value
*/
public void setCabfile( final File cabFile )
{
m_cabFile = cabFile;
}

/**
* Sets whether we want to compress the files or only store them.
*
* @param compress The new Compress value
*/
public void setCompress( final boolean compress )
{
m_compress = compress;
}

/**
* Sets additional cabarc options that aren't supported directly.
*
* @param options The new Options value
*/
public void setOptions( final String options )
{
m_options = options;
}

/**
* Adds a set of files (nested fileset attribute).
*
* @param set The feature to be added to the Fileset attribute
*/
public void addFileset( final FileSet set )
{
m_filesets.add( set );
}

public void execute()
throws TaskException
{
checkConfiguration();

final ArrayList files = getFileList();

// quick exit if the target is up to date
if( isUpToDate( files ) )
{
return;
}

getContext().info( "Building cab: " + m_cabFile.getAbsolutePath() );

if( !Os.isFamily( Os.OS_FAMILY_WINDOWS ) )
{
getContext().debug( "Using listcab/libcabinet" );

final StringBuffer sb = new StringBuffer();

final Iterator e = files.iterator();
while( e.hasNext() )
{
sb.append( e.next() ).append( "\n" );
}
sb.append( "\n" ).append( m_cabFile.getAbsolutePath() ).append( "\n" );

try
{
Process p = Runtime.getRuntime().exec( "listcab" );
OutputStream out = p.getOutputStream();
out.write( sb.toString().getBytes() );
out.flush();
out.close();
}
catch( IOException ex )
{
String msg = "Problem creating " + m_cabFile + " " + ex.getMessage();
throw new TaskException( msg );
}
}
else
{
try
{
File listFile = createListFile( files );
Execute exe = new Execute();
exe.setWorkingDirectory( m_baseDir );
createCommand( exe, listFile );
exe.execute( getContext() );

listFile.delete();
}
catch( final IOException ioe )
{
final String message =
"Problem creating " + m_cabFile + " " + ioe.getMessage();
throw new TaskException( message );
}
}
}

/**
* Get the complete list of files to be included in the cab. Filenames are
* gathered from filesets if any have been added, otherwise from the
* traditional include parameters.
*/
protected ArrayList getFileList()
throws TaskException
{
ArrayList files = new ArrayList();

if( m_filesets.size() == 0 )
{
// get files from old methods - includes and nested include
appendFiles( files, super.getDirectoryScanner( m_baseDir ) );
}
else
{
// get files from filesets
for( int i = 0; i < m_filesets.size(); i++ )
{
FileSet fs = (FileSet)m_filesets.get( i );
if( fs != null )
{
appendFiles( files, ScannerUtil.getDirectoryScanner( fs ) );
}
}
}

return files;
}

/**
* Check to see if the target is up to date with respect to input files.
*
* @param files Description of Parameter
* @return true if the cab file is newer than its dependents.
*/
protected boolean isUpToDate( ArrayList files )
{
boolean upToDate = true;
for( int i = 0; i < files.size() && upToDate; i++ )
{
String file = files.get( i ).toString();
if( new File( m_baseDir, file ).lastModified() >
m_cabFile.lastModified() )
{
upToDate = false;
}
}
return upToDate;
}

/**
* Append all files found by a directory scanner to a vector.
*
* @param files Description of Parameter
* @param ds Description of Parameter
*/
protected void appendFiles( ArrayList files, DirectoryScanner ds )
{
String[] dsfiles = ds.getIncludedFiles();

for( int i = 0; i < dsfiles.length; i++ )
{
files.add( dsfiles[ i ] );
}
}

/*
* I'm not fond of this pattern: "sub-method expected to throw
* task-cancelling exceptions". It feels too much like programming
* for side-effects to me...
*/
protected void checkConfiguration()
throws TaskException
{
if( m_baseDir == null )
{
throw new TaskException( "basedir attribute must be set!" );
}
if( !m_baseDir.exists() )
{
throw new TaskException( "basedir does not exist!" );
}
if( m_cabFile == null )
{
throw new TaskException( "cabfile attribute must be set!" );
}
}

/**
* Create the cabarc command line to use.
*/
protected void createCommand( final Commandline cmd, final File listFile )
throws TaskException
{
cmd.setExecutable( "cabarc" );
cmd.addArgument( "-r" );
cmd.addArgument( "-p" );

if( !m_compress )
{
cmd.addArgument( "-m" );
cmd.addArgument( "none" );
}

if( m_options != null )
{
cmd.addLine( m_options );
}

cmd.addArgument( "n" );
cmd.addArgument( m_cabFile );
cmd.addArgument( "@" + listFile.getAbsolutePath() );
}

/**
* Creates a list file. This temporary file contains a list of all files to
* be included in the cab, one file per line.
*
* @param files Description of Parameter
* @return Description of the Returned Value
* @exception java.io.IOException Description of Exception
*/
protected File createListFile( ArrayList files )
throws IOException
{
File listFile = File.createTempFile( "ant", "", getBaseDirectory() );

PrintWriter writer = new PrintWriter( new FileOutputStream( listFile ) );

for( int i = 0; i < files.size(); i++ )
{
writer.println( files.get( i ).toString() );
}
writer.close();

return listFile;
}
}

+ 0
- 23
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/ClassArgument.java View File

@@ -1,23 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

public class ClassArgument
{
private String m_name;

public void setName( String name )
{
m_name = name;
}

public String getName()
{
return m_name;
}
}

+ 0
- 303
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/DependSet.java View File

@@ -1,303 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import org.apache.aut.nativelib.Os;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.FileSet;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.tools.todo.types.ScannerUtil;
import org.apache.tools.todo.types.SimpleFileList;

/**
* A Task to record explicit dependencies. If any of the target files are out of
* date with respect to any of the source files, all target files are removed.
* This is useful where dependencies cannot be computed (for example,
* dynamically interpreted parameters or files that need to stay in synch but
* are not directly linked) or where the ant task in question could compute them
* but does not (for example, the linked DTD for an XML file using the style
* task). nested arguments:
* <ul>
* <li> srcfileset (fileset describing the source files to examine)
* <li> srcfilelist (filelist describing the source files to examine)
* <li> targetfileset (fileset describing the target files to examine)
* <li> targetfilelist (filelist describing the target files to examine)
* </ul>
* At least one instance of either a fileset or filelist for both source and
* target are required. <p>
*
* This task will examine each of the source files against each of the target
* files. If any target files are out of date with respect to any of the source
* files, all targets are removed. If any files named in a (src or target)
* filelist do not exist, all targets are removed. Hint: If missing files should
* be ignored, specify them as include patterns in filesets, rather than using
* filelists. </p> <p>
*
* This task attempts to optimize speed of dependency checking. It will stop
* after the first out of date file is found and remove all targets, rather than
* exhaustively checking every source vs target combination unnecessarily. </p>
* <p>
*
* Example uses:
* <ul>
* <li> Record the fact that an XML file must be up to date with respect to
* its XSD (Schema file), even though the XML file itself includes no
* reference to its XSD. </li>
* <li> Record the fact that an XSL stylesheet includes other sub-stylesheets
* </li>
* <li> Record the fact that java files must be recompiled if the ant build
* file changes </li>
* </ul>
*
*
* @author <a href="mailto:cstrong@arielpartners.com">Craeg Strong</a>
* @version $Revision$ $Date$
*/
public class DependSet extends MatchingTask
{

private ArrayList sourceFileSets = new ArrayList();
private ArrayList sourceFileLists = new ArrayList();
private ArrayList targetFileSets = new ArrayList();
private ArrayList targetFileLists = new ArrayList();

/**
* Creates a new DependSet Task.
*/
public DependSet()
{
}

/**
* Nested &lt;srcfilelist&gt; element.
*
* @param fl The feature to be added to the Srcfilelist attribute
*/
public void addSrcfilelist( SimpleFileList fl )
{
sourceFileLists.add( fl );
}//-- DependSet

/**
* Nested &lt;srcfileset&gt; element.
*
* @param fs The feature to be added to the Srcfileset attribute
*/
public void addSrcfileset( FileSet fs )
{
sourceFileSets.add( fs );
}

/**
* Nested &lt;targetfilelist&gt; element.
*
* @param fl The feature to be added to the Targetfilelist attribute
*/
public void addTargetfilelist( SimpleFileList fl )
{
targetFileLists.add( fl );
}

/**
* Nested &lt;targetfileset&gt; element.
*
* @param fs The feature to be added to the Targetfileset attribute
*/
public void addTargetfileset( FileSet fs )
{
targetFileSets.add( fs );
}

/**
* Executes the task.
*
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
public void execute()
throws TaskException
{
if( ( sourceFileSets.size() == 0 ) && ( sourceFileLists.size() == 0 ) )
{
throw new TaskException( "At least one <srcfileset> or <srcfilelist> element must be set" );
}

if( ( targetFileSets.size() == 0 ) && ( targetFileLists.size() == 0 ) )
{
throw new TaskException( "At least one <targetfileset> or <targetfilelist> element must be set" );
}

long now = ( new Date() ).getTime();
/*
* If we're on Windows, we have to munge the time up to 2 secs to
* be able to check file modification times.
* (Windows has a max resolution of two secs for modification times)
*/
if( Os.isFamily( Os.OS_FAMILY_WINDOWS ) )
{
now += 2000;
}

//
// Grab all the target files specified via filesets
//
ArrayList allTargets = new ArrayList();
Iterator enumTargetSets = targetFileSets.iterator();
while( enumTargetSets.hasNext() )
{

FileSet targetFS = (FileSet)enumTargetSets.next();
DirectoryScanner targetDS = ScannerUtil.getDirectoryScanner( targetFS );
String[] targetFiles = targetDS.getIncludedFiles();

for( int i = 0; i < targetFiles.length; i++ )
{

File dest = new File( targetFS.getDir(), targetFiles[ i ] );
allTargets.add( dest );

if( dest.lastModified() > now )
{
getContext().warn( "Warning: " + targetFiles[ i ] + " modified in the future." );
}
}
}

//
// Grab all the target files specified via filelists
//
boolean upToDate = true;
Iterator enumTargetLists = targetFileLists.iterator();
while( enumTargetLists.hasNext() )
{

SimpleFileList targetFL = (SimpleFileList)enumTargetLists.next();
String[] targetFiles = targetFL.getFiles();

for( int i = 0; i < targetFiles.length; i++ )
{

File dest = new File( targetFL.getDir(), targetFiles[ i ] );
if( !dest.exists() )
{
getContext().debug( targetFiles[ i ] + " does not exist." );
upToDate = false;
continue;
}
else
{
allTargets.add( dest );
}
if( dest.lastModified() > now )
{
getContext().warn( "Warning: " + targetFiles[ i ] + " modified in the future." );
}
}
}

//
// Check targets vs source files specified via filesets
//
if( upToDate )
{
Iterator enumSourceSets = sourceFileSets.iterator();
while( upToDate && enumSourceSets.hasNext() )
{

FileSet sourceFS = (FileSet)enumSourceSets.next();
DirectoryScanner sourceDS = ScannerUtil.getDirectoryScanner( sourceFS );
String[] sourceFiles = sourceDS.getIncludedFiles();

for( int i = 0; upToDate && i < sourceFiles.length; i++ )
{
File src = new File( sourceFS.getDir(), sourceFiles[ i ] );

if( src.lastModified() > now )
{
getContext().warn( "Warning: " + sourceFiles[ i ] + " modified in the future." );
}

Iterator enumTargets = allTargets.iterator();
while( upToDate && enumTargets.hasNext() )
{

File dest = (File)enumTargets.next();
if( src.lastModified() > dest.lastModified() )
{
getContext().debug( dest.getPath() + " is out of date with respect to " + sourceFiles[ i ] );
upToDate = false;

}
}
}
}
}

//
// Check targets vs source files specified via filelists
//
if( upToDate )
{
Iterator enumSourceLists = sourceFileLists.iterator();
while( upToDate && enumSourceLists.hasNext() )
{

SimpleFileList sourceFL = (SimpleFileList)enumSourceLists.next();
String[] sourceFiles = sourceFL.getFiles();

int i = 0;
do
{
File src = new File( sourceFL.getDir(), sourceFiles[ i ] );

if( src.lastModified() > now )
{
getContext().warn( "Warning: " + sourceFiles[ i ] + " modified in the future." );
}

if( !src.exists() )
{
getContext().debug( sourceFiles[ i ] + " does not exist." );
upToDate = false;
break;
}

Iterator enumTargets = allTargets.iterator();
while( upToDate && enumTargets.hasNext() )
{

File dest = (File)enumTargets.next();

if( src.lastModified() > dest.lastModified() )
{
getContext().debug( dest.getPath() + " is out of date with respect to " + sourceFiles[ i ] );
upToDate = false;

}
}
} while( upToDate && ( ++i < sourceFiles.length ) );
}
}

if( !upToDate )
{
getContext().debug( "Deleting all target files. " );
for( Iterator e = allTargets.iterator(); e.hasNext(); )
{
File fileToRemove = (File)e.next();
getContext().debug( "Deleting file " + fileToRemove.getAbsolutePath() );
fileToRemove.delete();
}
}

}//-- execute

}//-- DependSet.java

+ 0
- 108
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Echo.java View File

@@ -1,108 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;

/**
* Log
*
* @author costin@dnt.ro
*/
public class Echo
extends AbstractTask
{
private String m_message = "";// required
private File m_file;
private boolean m_append;

/**
* Shall we append to an existing file?
*
* @param append The new Append value
*/
public void setAppend( final boolean append )
{
m_append = append;
}

/**
* Sets the file attribute.
*
* @param file The new File value
*/
public void setFile( final File file )
{
m_file = file;
}

/**
* Sets the message variable.
*
* @param msg Sets the value for the message variable.
*/
public void setMessage( final String message )
{
m_message = message;
}

/**
* Set a multiline message.
*
* @param msg The feature to be added to the Text attribute
*/
public void addContent( final String message )
throws TaskException
{
m_message = message;
}

/**
* Does the work.
*
* @exception org.apache.myrmidon.api.TaskException if someting goes wrong with the build
*/
public void execute()
throws TaskException
{
if( m_file == null )
{
throw new TaskException( "Echo only used to write to files now !" );
}
else
{
FileWriter out = null;
try
{
out = new FileWriter( m_file.getAbsolutePath(), m_append );
out.write( m_message, 0, m_message.length() );
}
catch( IOException ioe )
{
throw new TaskException( "Error", ioe );
}
finally
{
if( out != null )
{
try
{
out.close();
}
catch( IOException ioex )
{
}
}
}
}
}
}

+ 0
- 488
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Entry.java View File

@@ -1,488 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Properties;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.todo.types.EnumeratedAttribute;

/**
* Instance of this class represents nested elements of a task propertyfile.
*/
public class Entry
{
final static String NOW_VALUE_ = "now";
final static String NULL_VALUE_ = "never";

private final static int DEFAULT_INT_VALUE = 1;
private final static GregorianCalendar
DEFAULT_DATE_VALUE = new GregorianCalendar();

private String m_key;
private int m_type = Type.STRING_TYPE;
private int m_operation = Operation.EQUALS_OPER;
private String m_value = "";
private String m_default;
private String m_pattern;

public void setDefault( String value )
{
this.m_default = value;
}

public void setKey( String value )
{
this.m_key = value;
}

public void setOperation( Operation value )
{
int newOperation = Operation.toOperation( value.getValue() );
if( newOperation == Operation.NOW_VALUE )
{
this.m_operation = Operation.EQUALS_OPER;
this.setValue( this.NOW_VALUE_ );
}
else if( newOperation == Operation.NULL_VALUE )
{
this.m_operation = Operation.EQUALS_OPER;
this.setValue( this.NULL_VALUE_ );
}
else
{
this.m_operation = newOperation;
}
}

public void setPattern( String value )
{
this.m_pattern = value;
}

public void setType( Type value )
{
this.m_type = Type.toType( value.getValue() );
}

public void setValue( String value )
{
this.m_value = value;
}

protected void executeOn( Properties props )
throws TaskException
{
checkParameters();

// m_type may be null because it wasn't set
try
{
if( m_type == Type.INTEGER_TYPE )
{
executeInteger( (String)props.get( m_key ) );
}
else if( m_type == Type.DATE_TYPE )
{
executeDate( (String)props.get( m_key ) );
}
else if( m_type == Type.STRING_TYPE )
{
executeString( (String)props.get( m_key ) );
}
else
{
throw new TaskException( "Unknown operation type: " + m_type + "" );
}
}
catch( NullPointerException npe )
{
// Default to string type
// which means do nothing
npe.printStackTrace();
}
// Insert as a string by default
props.put( m_key, m_value );

}

/**
* Check if parameter combinations can be supported
*
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
private void checkParameters()
throws TaskException
{
if( m_type == Type.STRING_TYPE &&
m_operation == Operation.DECREMENT_OPER )
{
throw new TaskException( "- is not suported for string properties (key:" + m_key + ")" );
}
if( m_value == null && m_default == null )
{
throw new TaskException( "value and/or default must be specified (key:" + m_key + ")" );
}
if( m_key == null )
{
throw new TaskException( "key is mandatory" );
}
if( m_type == Type.STRING_TYPE &&
m_pattern != null )
{
throw new TaskException( "pattern is not suported for string properties (key:" + m_key + ")" );
}
}

/**
* Handle operations for type <code>date</code>.
*
* @param oldValue the current value read from the property file or
* <code>null</code> if the <code>key</code> was not contained in
* the property file.
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
private void executeDate( String oldValue )
throws TaskException
{
GregorianCalendar value = new GregorianCalendar();
GregorianCalendar newValue = new GregorianCalendar();

if( m_pattern == null )
{
m_pattern = "yyyy/MM/dd HH:mm";
}
DateFormat fmt = new SimpleDateFormat( m_pattern );

// special case
if( m_default != null &&
NOW_VALUE_.equals( m_default.toLowerCase() ) &&
( m_operation == Operation.INCREMENT_OPER ||
m_operation == Operation.DECREMENT_OPER ) )
{
oldValue = null;
}

if( oldValue != null )
{
try
{
value.setTime( fmt.parse( oldValue ) );
}
catch( ParseException pe )
{
/*
* swollow
*/
}
}

if( m_value != null )
{
if( NOW_VALUE_.equals( m_value.toLowerCase() ) )
{
value.setTime( new Date() );
}
else if( NULL_VALUE_.equals( m_value.toLowerCase() ) )
{
value = null;
}
else
{
try
{
value.setTime( fmt.parse( m_value ) );
}
catch( Exception ex )
{
// obviously not a date, try a simple int
try
{
int offset = Integer.parseInt( m_value );
value.clear();
value.set( Calendar.DAY_OF_YEAR, offset );
}
catch( Exception ex_ )
{
value.clear();
value.set( Calendar.DAY_OF_YEAR, 1 );
}
}

}
}

if( m_default != null && oldValue == null )
{
if( NOW_VALUE_.equals( m_default.toLowerCase() ) )
{
value.setTime( new Date() );
}
else if( NULL_VALUE_.equals( m_default.toLowerCase() ) )
{
value = null;
}
else
{
try
{
value.setTime( fmt.parse( m_default ) );
}
catch( ParseException pe )
{
/*
* swollow
*/
}
}
}

if( m_operation == Operation.EQUALS_OPER )
{
newValue = value;
}
else if( m_operation == Operation.INCREMENT_OPER )
{
newValue.add( Calendar.SECOND, value.get( Calendar.SECOND ) );
newValue.add( Calendar.MINUTE, value.get( Calendar.MINUTE ) );
newValue.add( Calendar.HOUR_OF_DAY, value.get( Calendar.HOUR_OF_DAY ) );
newValue.add( Calendar.DAY_OF_YEAR, value.get( Calendar.DAY_OF_YEAR ) );
}
else if( m_operation == Operation.DECREMENT_OPER )
{
newValue.add( Calendar.SECOND, -1 * value.get( Calendar.SECOND ) );
newValue.add( Calendar.MINUTE, -1 * value.get( Calendar.MINUTE ) );
newValue.add( Calendar.HOUR_OF_DAY, -1 * value.get( Calendar.HOUR_OF_DAY ) );
newValue.add( Calendar.DAY_OF_YEAR, -1 * value.get( Calendar.DAY_OF_YEAR ) );
}
if( newValue != null )
{
m_value = fmt.format( newValue.getTime() );
}
else
{
m_value = "";
}
}

/**
* Handle operations for type <code>int</code>.
*
* @param oldValue the current value read from the property file or
* <code>null</code> if the <code>key</code> was not contained in
* the property file.
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
private void executeInteger( String oldValue )
throws TaskException
{
int value = 0;
int newValue = 0;

DecimalFormat fmt = ( m_pattern != null ) ? new DecimalFormat( m_pattern )
: new DecimalFormat();

if( oldValue != null )
{
try
{
value = fmt.parse( oldValue ).intValue();
}
catch( NumberFormatException nfe )
{
/*
* swollow
*/
}
catch( ParseException pe )
{
/*
* swollow
*/
}
}
if( m_value != null )
{
try
{
value = fmt.parse( m_value ).intValue();
}
catch( NumberFormatException nfe )
{
/*
* swollow
*/
}
catch( ParseException pe )
{
/*
* swollow
*/
}
}
if( m_default != null && oldValue == null )
{
try
{
value = fmt.parse( m_default ).intValue();
}
catch( NumberFormatException nfe )
{
/*
* swollow
*/
}
catch( ParseException pe )
{
/*
* swollow
*/
}
}

if( m_operation == Operation.EQUALS_OPER )
{
newValue = value;
}
else if( m_operation == Operation.INCREMENT_OPER )
{
newValue = ++value;
}
else if( m_operation == Operation.DECREMENT_OPER )
{
newValue = --value;
}
m_value = fmt.format( newValue );
}

/**
* Handle operations for type <code>string</code>.
*
* @param oldValue the current value read from the property file or
* <code>null</code> if the <code>key</code> was not contained in
* the property file.
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
private void executeString( String oldValue )
throws TaskException
{
String value = "";
String newValue = "";

// the order of events is, of course, very important here
// default initially to the old value
if( oldValue != null )
{
value = oldValue;
}
// but if a value is specified, use it
if( m_value != null )
{
value = m_value;
}
// even if value is specified, ignore it and set to the default
// value if it is specified and there is no previous value
if( m_default != null && oldValue == null )
{
value = m_default;
}

if( m_operation == Operation.EQUALS_OPER )
{
newValue = value;
}
else if( m_operation == Operation.INCREMENT_OPER )
{
newValue += value;
}
m_value = newValue;
}

/**
* Enumerated attribute with the values "+", "-", "=", "now" and
* "never".
*
* @author RT
*/
public static class Operation extends EnumeratedAttribute
{

// Property type operations
public final static int INCREMENT_OPER = 0;
public final static int DECREMENT_OPER = 1;
public final static int EQUALS_OPER = 2;

// Special values
public final static int NOW_VALUE = 3;
public final static int NULL_VALUE = 4;

public static int toOperation( String oper )
{
if( "+".equals( oper ) )
{
return INCREMENT_OPER;
}
else if( "-".equals( oper ) )
{
return DECREMENT_OPER;
}
else if( NOW_VALUE_.equals( oper ) )
{
return NOW_VALUE;
}
else if( NULL_VALUE_.equals( oper ) )
{
return NULL_VALUE;
}
return EQUALS_OPER;
}

public String[] getValues()
{
return new String[]{"+", "-", "=", NOW_VALUE_, NULL_VALUE_};
}
}

/**
* Enumerated attribute with the values "int", "date" and "string".
*
* @author RT
*/
public static class Type extends EnumeratedAttribute
{

// Property types
public final static int INTEGER_TYPE = 0;
public final static int DATE_TYPE = 1;
public final static int STRING_TYPE = 2;

public static int toType( String type )
{
if( "int".equals( type ) )
{
return INTEGER_TYPE;
}
else if( "date".equals( type ) )
{
return DATE_TYPE;
}
return STRING_TYPE;
}

public String[] getValues()
{
return new String[]{"int", "date", "string"};
}
}
}

+ 0
- 36
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/FileDir.java View File

@@ -1,36 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import org.apache.tools.todo.types.EnumeratedAttribute;

public class FileDir
extends EnumeratedAttribute
{
private final static String[] values = {"file", "dir"};

public String[] getValues()
{
return values;
}

public boolean isDir()
{
return "dir".equalsIgnoreCase( getValue() );
}

public boolean isFile()
{
return "file".equalsIgnoreCase( getValue() );
}

public String toString()
{
return getValue();
}
}

+ 0
- 381
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Get.java View File

@@ -1,381 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.TaskContext;

/**
* Get a particular file from a URL source. Options include verbose reporting,
* timestamp based fetches and controlling actions on failures. NB: access
* through a firewall only works if the whole Java runtime is correctly
* configured.
*
* @author costin@dnt.ro
* @author gg@grtmail.com (Added Java 1.1 style HTTP basic auth)
*/
public class Get extends AbstractTask
{// required
private boolean verbose = false;
private boolean useTimestamp = false;//off by default
private boolean ignoreErrors = false;
private String uname = null;
private String pword = null;// required
private File dest;
private URL source;

/**
* Where to copy the source file.
*
* @param dest Path to file.
*/
public void setDest( File dest )
{
this.dest = dest;
}

/**
* Don't stop if get fails if set to "<CODE>true</CODE>".
*
* @param v if "true" then don't report download errors up to ant
*/
public void setIgnoreErrors( boolean v )
{
ignoreErrors = v;
}

/**
* password for the basic auth.
*
* @param p password for authentication
*/
public void setPassword( String p )
{
this.pword = p;
}

/**
* Set the URL.
*
* @param u URL for the file.
*/
public void setSrc( URL u )
{
this.source = u;
}

/**
* Use timestamps, if set to "<CODE>true</CODE>". <p>
*
* In this situation, the if-modified-since header is set so that the file
* is only fetched if it is newer than the local file (or there is no local
* file) This flag is only valid on HTTP connections, it is ignored in other
* cases. When the flag is set, the local copy of the downloaded file will
* also have its timestamp set to the remote file time. <br>
* Note that remote files of date 1/1/1970 (GMT) are treated as 'no
* timestamp', and web servers often serve files with a timestamp in the
* future by replacing their timestamp with that of the current time. Also,
* inter-computer clock differences can cause no end of grief.
*
* @param v "true" to enable file time fetching
*/
public void setUseTimestamp( boolean v )
{
useTimestamp = v;
}

/**
* Username for basic auth.
*
* @param u username for authentication
*/
public void setUsername( String u )
{
this.uname = u;
}

/**
* Be verbose, if set to "<CODE>true</CODE>".
*
* @param v if "true" then be verbose
*/
public void setVerbose( boolean v )
{
verbose = v;
}

/**
* Does the work.
*
* @exception org.apache.myrmidon.api.TaskException Thrown in unrecoverable error.
*/
public void execute()
throws TaskException
{
if( source == null )
{
throw new TaskException( "src attribute is required" );
}

if( dest == null )
{
throw new TaskException( "dest attribute is required" );
}

if( dest.exists() && dest.isDirectory() )
{
throw new TaskException( "The specified destination is a directory" );
}

if( dest.exists() && !dest.canWrite() )
{
throw new TaskException( "Can't write to " + dest.getAbsolutePath() );
}

try
{
getContext().info( "Getting: " + source );

//set the timestamp to the file date.
long timestamp = 0;

boolean hasTimestamp = false;
if( useTimestamp && dest.exists() )
{
timestamp = dest.lastModified();
if( verbose )
{
Date t = new Date( timestamp );
getContext().verbose( "local file date : " + t.toString() );
}

hasTimestamp = true;
}

//set up the URL connection
URLConnection connection = source.openConnection();
//modify the headers
//NB: things like user authentication could go in here too.
if( useTimestamp && hasTimestamp )
{
connection.setIfModifiedSince( timestamp );
}
// prepare Java 1.1 style credentials
if( uname != null || pword != null )
{
String up = uname + ":" + pword;
String encoding;
// check to see if sun's Base64 encoder is available.
try
{
sun.misc.BASE64Encoder encoder =
(sun.misc.BASE64Encoder)Class.forName( "sun.misc.BASE64Encoder" ).newInstance();
encoding = encoder.encode( up.getBytes() );

}
catch( Exception ex )
{// sun's base64 encoder isn't available
Base64Converter encoder = new Base64Converter();
encoding = encoder.encode( up.getBytes() );
}
connection.setRequestProperty( "Authorization", "Basic " + encoding );
}

//connect to the remote site (may take some time)
connection.connect();
//next test for a 304 result (HTTP only)
if( connection instanceof HttpURLConnection )
{
HttpURLConnection httpConnection = (HttpURLConnection)connection;
if( httpConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED )
{
//not modified so no file download. just return instead
//and trace out something so the user doesn't think that the
//download happened when it didnt
getContext().verbose( "Not modified - so not downloaded" );
return;
}
// test for 401 result (HTTP only)
if( httpConnection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED )
{
getContext().info( "Not authorized - check " + dest + " for details" );
return;
}

}

//REVISIT: at this point even non HTTP connections may support the if-modified-since
//behaviour -we just check the date of the content and skip the write if it is not
//newer. Some protocols (FTP) dont include dates, of course.

FileOutputStream fos = new FileOutputStream( dest );

InputStream is = null;
for( int i = 0; i < 3; i++ )
{
try
{
is = connection.getInputStream();
break;
}
catch( IOException ex )
{
getContext().info( "Error opening connection " + ex );
}
}
if( is == null )
{
getContext().info( "Can't get " + source + " to " + dest );
if( ignoreErrors )
{
return;
}
throw new TaskException( "Can't get " + source + " to " + dest );
}

byte[] buffer = new byte[ 100 * 1024 ];
int length;

while( ( length = is.read( buffer ) ) >= 0 )
{
fos.write( buffer, 0, length );
if( verbose )
{
System.out.print( "." );
}
}
if( verbose )
{
System.out.println();
}
fos.close();
is.close();

//if (and only if) the use file time option is set, then the
//saved file now has its timestamp set to that of the downloaded file
if( useTimestamp )
{
long remoteTimestamp = connection.getLastModified();
if( verbose )
{
Date t = new Date( remoteTimestamp );
getContext().verbose( "last modified = " + t.toString()
+ ( ( remoteTimestamp == 0 ) ? " - using current time instead" : "" ) );
}

if( remoteTimestamp != 0 )
{
dest.setLastModified( remoteTimestamp );
}
}
}
catch( IOException ioe )
{
getContext().info( "Error getting " + source + " to " + dest );
if( ignoreErrors )
{
return;
}
throw new TaskException( "Error", ioe );
}
}

/**
* BASE 64 encoding of a String or an array of bytes. Based on RFC 1421.
*
* @author Unknown
* @author <a HREF="gg@grtmail.com">Gautam Guliani</a>
*/

class Base64Converter
{

public final char[] alphabet = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0 to 7
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 8 to 15
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 16 to 23
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 24 to 31
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 32 to 39
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 40 to 47
'w', 'x', 'y', 'z', '0', '1', '2', '3', // 48 to 55
'4', '5', '6', '7', '8', '9', '+', '/'};// 56 to 63

public String encode( String s )
{
return encode( s.getBytes() );
}

public String encode( byte[] octetString )
{
int bits24;
int bits6;

char[] out
= new char[ ( ( octetString.length - 1 ) / 3 + 1 ) * 4 ];

int outIndex = 0;
int i = 0;

while( ( i + 3 ) <= octetString.length )
{
// store the octets
bits24 = ( octetString[ i++ ] & 0xFF ) << 16;
bits24 |= ( octetString[ i++ ] & 0xFF ) << 8;

bits6 = ( bits24 & 0x00FC0000 ) >> 18;
out[ outIndex++ ] = alphabet[ bits6 ];
bits6 = ( bits24 & 0x0003F000 ) >> 12;
out[ outIndex++ ] = alphabet[ bits6 ];
bits6 = ( bits24 & 0x00000FC0 ) >> 6;
out[ outIndex++ ] = alphabet[ bits6 ];
bits6 = ( bits24 & 0x0000003F );
out[ outIndex++ ] = alphabet[ bits6 ];
}

if( octetString.length - i == 2 )
{
// store the octets
bits24 = ( octetString[ i ] & 0xFF ) << 16;
bits24 |= ( octetString[ i + 1 ] & 0xFF ) << 8;
bits6 = ( bits24 & 0x00FC0000 ) >> 18;
out[ outIndex++ ] = alphabet[ bits6 ];
bits6 = ( bits24 & 0x0003F000 ) >> 12;
out[ outIndex++ ] = alphabet[ bits6 ];
bits6 = ( bits24 & 0x00000FC0 ) >> 6;
out[ outIndex++ ] = alphabet[ bits6 ];

// padding
out[ outIndex++ ] = '=';
}
else if( octetString.length - i == 1 )
{
// store the octets
bits24 = ( octetString[ i ] & 0xFF ) << 16;
bits6 = ( bits24 & 0x00FC0000 ) >> 18;
out[ outIndex++ ] = alphabet[ bits6 ];
bits6 = ( bits24 & 0x0003F000 ) >> 12;
out[ outIndex++ ] = alphabet[ bits6 ];

// padding
out[ outIndex++ ] = '=';
out[ outIndex++ ] = '=';
}

return new String( out );
}
}
}

+ 0
- 1061
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/IContract.java
File diff suppressed because it is too large
View File


+ 0
- 358
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Javah.java View File

@@ -1,358 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.StringTokenizer;
import org.apache.avalon.excalibur.util.StringUtil;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.file.FileListUtil;
import org.apache.myrmidon.framework.file.Path;
import org.apache.myrmidon.framework.nativelib.ArgumentList;
import org.apache.tools.todo.util.FileUtils;

/**
* Task to generate JNI header files using javah. This task can take the
* following arguments:
* <ul>
* <li> classname - the fully-qualified name of a class</li>
* <li> outputFile - Concatenates the resulting header or source files for all
* the classes listed into this file</li>
* <li> destdir - Sets the directory where javah saves the header files or the
* stub files</li>
* <li> classpath</li>
* <li> bootclasspath</li>
* <li> force - Specifies that output files should always be written (JDK1.2
* only)</li>
* <li> old - Specifies that old JDK1.0-style header files should be generated
* (otherwise output file contain JNI-style native method function prototypes)
* (JDK1.2 only)</li>
* <li> stubs - generate C declarations from the Java object file (used with
* old)</li>
* <li> verbose - causes javah to print a message to stdout concerning the
* status of the generated files</li>
* <li> extdirs - Override location of installed extensions</li>
* </ul>
* Of these arguments, either <b>outputFile</b> or <b>destdir</b> is required,
* but not both. More than one classname may be specified, using a
* comma-separated list or by using <code>&lt;class name="xxx"&gt;</code>
* elements within the task. <p>
*
* When this task executes, it will generate C header and source files that are
* needed to implement native methods.
*
* @author Rick Beton <a href="mailto:richard.beton@physics.org">
* richard.beton@physics.org</a>
*/

public class Javah
extends AbstractTask
{
private final static String FAIL_MSG = "Compile failed, messages should have been provided.";

private ArrayList m_classes = new ArrayList( 2 );
private Path m_classpath;
private File m_outputFile;
private boolean m_verbose;
private boolean m_force;
private boolean m_old;
private boolean m_stubs;
private Path m_bootclasspath;
private String m_cls;
private File m_destDir;

/**
* Adds an element to the bootclasspath.
*/
public void addBootclasspath( final Path bootclasspath )
{
if( m_bootclasspath == null )
{
m_bootclasspath = bootclasspath;
}
else
{
m_bootclasspath.add( bootclasspath );
}
}

public void setClass( final String cls )
{
m_cls = cls;
}

/**
* Adds an element to the classpath.
*/
public void addClasspath( final Path classpath )
throws TaskException
{
if( m_classpath == null )
{
m_classpath = classpath;
}
else
{
m_classpath.add( classpath );
}
}

/**
* Set the destination directory into which the Java source files should be
* compiled.
*
* @param destDir The new Destdir value
*/
public void setDestdir( final File destDir )
{
m_destDir = destDir;
}

/**
* Set the force-write flag.
*/
public void setForce( final boolean force )
{
m_force = force;
}

/**
* Set the old flag.
*/
public void setOld( final boolean old )
{
m_old = old;
}

/**
* Set the output file name.
*/
public void setOutputFile( final File outputFile )
{
m_outputFile = outputFile;
}

/**
* Set the stubs flag.
*/
public void setStubs( final boolean stubs )
{
m_stubs = stubs;
}

/**
* Set the verbose flag.
*/
public void setVerbose( final boolean verbose )
{
m_verbose = verbose;
}

public ClassArgument createClass()
{
final ClassArgument ga = new ClassArgument();
m_classes.add( ga );
return ga;
}

/**
* Executes the task.
*/
public void execute()
throws TaskException
{
validate();
doClassicCompile();
}

private void validate() throws TaskException
{
if( ( m_cls == null ) && ( m_classes.size() == 0 ) )
{
final String message = "class attribute must be set!";
throw new TaskException( message );
}

if( ( m_cls != null ) && ( m_classes.size() > 0 ) )
{
final String message = "set class attribute or class element, not both.";
throw new TaskException( message );
}

if( m_destDir != null )
{
if( !m_destDir.isDirectory() )
{
final String message = "destination directory \"" + m_destDir +
"\" does not exist or is not a directory";
throw new TaskException( message );
}
if( m_outputFile != null )
{
final String message = "destdir and outputFile are mutually exclusive";
throw new TaskException( message );
}
}
}

/**
* Logs the compilation parameters, adds the files to compile and logs the
* &qout;niceSourceList&quot;
*/
private void logAndAddFilesToCompile( final ArgumentList cmd )
throws TaskException
{
final String[] args = cmd.getArguments();
getContext().debug( "Compilation args: " + FileUtils.formatCommandLine( args ) );

int n = 0;
StringBuffer niceClassList = new StringBuffer();
if( m_cls != null )
{
final StringTokenizer tok = new StringTokenizer( m_cls, ",", false );
while( tok.hasMoreTokens() )
{
final String aClass = tok.nextToken().trim();
cmd.addArgument( aClass );
niceClassList.append( " " + aClass + StringUtil.LINE_SEPARATOR );
n++;
}
}

final Iterator enum = m_classes.iterator();
while( enum.hasNext() )
{
final ClassArgument arg = (ClassArgument)enum.next();
final String aClass = arg.getName();
cmd.addArgument( aClass );
niceClassList.append( " " + aClass + StringUtil.LINE_SEPARATOR );
n++;
}

final StringBuffer prefix = new StringBuffer( "Class" );
if( n > 1 )
{
prefix.append( "es" );
}
prefix.append( " to be compiled:" );
prefix.append( StringUtil.LINE_SEPARATOR );

getContext().debug( prefix.toString() + niceClassList.toString() );
}

/**
* Does the command line argument processing common to classic and modern.
*/
private ArgumentList setupJavahCommand()
throws TaskException
{
final ArgumentList cmd = new ArgumentList();

if( m_destDir != null )
{
cmd.addArgument( "-d" );
cmd.addArgument( m_destDir );
}

if( m_outputFile != null )
{
cmd.addArgument( "-o" );
cmd.addArgument( m_outputFile );
}

if( m_classpath != null )
{
cmd.addArgument( "-classpath" );
cmd.addArgument( FileListUtil.formatPath( m_classpath, getContext() ) );
}

if( m_verbose )
{
cmd.addArgument( "-verbose" );
}
if( m_old )
{
cmd.addArgument( "-old" );
}
if( m_force )
{
cmd.addArgument( "-force" );
}

if( m_stubs )
{
if( !m_old )
{
final String message = "stubs only available in old mode.";
throw new TaskException( message );
}
cmd.addArgument( "-stubs" );
}
if( m_bootclasspath != null )
{
cmd.addArgument( "-bootclasspath" );
cmd.addArgument( FileListUtil.formatPath( m_bootclasspath, getContext() ) );
}

logAndAddFilesToCompile( cmd );
return cmd;
}

/**
* Peforms a compile using the classic compiler that shipped with JDK 1.1
* and 1.2.
*
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/

private void doClassicCompile()
throws TaskException
{
ArgumentList cmd = setupJavahCommand();

// Use reflection to be able to build on all JDKs
/*
* / provide the compiler a different message sink - namely our own
* sun.tools.javac.Main compiler =
* new sun.tools.javac.Main(new LogOutputStream(this, Project.MSG_WARN), "javac");
* if (!compiler.compile(cmd.getArguments())) {
* throw new TaskException("Compile failed");
* }
*/
try
{
// Javac uses logstr to change the output stream and calls
// the constructor's invoke method to create a compiler instance
// dynamically. However, javah has a different interface and this
// makes it harder, so here's a simple alternative.
//------------------------------------------------------------------
com.sun.tools.javah.Main main = new com.sun.tools.javah.Main( cmd.getArguments() );
main.run();
}
//catch (ClassNotFoundException ex) {
// throw new TaskException("Cannot use javah because it is not available"+
// " A common solution is to set the environment variable"+
// " JAVA_HOME to your jdk directory.", location);
//}
catch( Exception ex )
{
if( ex instanceof TaskException )
{
throw (TaskException)ex;
}
else
{
throw new TaskException( "Error starting javah: ", ex );
}
}
}
}


+ 0
- 101
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/MatchingTask.java View File

@@ -1,101 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.io.File;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.Pattern;
import org.apache.myrmidon.framework.PatternSet;
import org.apache.myrmidon.framework.FileSet;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.tools.todo.types.ScannerUtil;

/**
* This is an abstract task that should be used by all those tasks that require
* to include or exclude files based on pattern matching.
*
* @author <a href="mailto:ajkuiper@wxs.nl">Arnout J. Kuiper</a>
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a>
* @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public abstract class MatchingTask
extends AbstractTask
{
private FileSet m_fileset = new FileSet();

/**
* Sets whether default exclusions should be used or not.
*/
public void setDefaultexcludes( final boolean useDefaultExcludes )
{
m_fileset.setDefaultExcludes( useDefaultExcludes );
}

/**
* Sets the set of exclude patterns. Patterns may be separated by a comma or
* a space.
*
* @param excludes the string containing the exclude patterns
*/
public void setExcludes( final String excludes )
{
m_fileset.setExcludes( excludes );
}

/**
* Sets the set of include patterns. Patterns may be separated by a comma or
* a space.
*
* @param includes the string containing the include patterns
*/
public void setIncludes( final String includes )
{
m_fileset.setIncludes( includes );
}

/**
* add a name entry on the exclude list
*/
public void addExclude( final Pattern pattern )
{
m_fileset.addExclude( pattern );
}

/**
* add a name entry on the include list
*/
public void addInclude( final Pattern pattern )
throws TaskException
{
m_fileset.addInclude( pattern );
}

/**
* add a set of patterns
*/
public void addPatternSet( final PatternSet set )
{
m_fileset.addPatternSet( set );
}

/**
* Returns the directory scanner needed to access the files to process.
*
* @param baseDir Description of Parameter
* @return The DirectoryScanner value
*/
protected DirectoryScanner getDirectoryScanner( final File baseDir )
throws TaskException
{
m_fileset.setDir( baseDir );
return ScannerUtil.getDirectoryScanner( m_fileset );
}
}

+ 0
- 770
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/NetRexxC.java View File

@@ -1,770 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;
import java.util.StringTokenizer;
import netrexx.lang.Rexx;
import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.avalon.excalibur.util.StringUtil;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskContext;
import org.apache.tools.todo.taskdefs.MatchingTask;
import org.apache.tools.todo.types.DirectoryScanner;

/**
* Task to compile NetRexx source files. This task can take the following
* arguments:
* <ul>
* <li> binary</li>
* <li> classpath</li>
* <li> comments</li>
* <li> compile</li>
* <li> console</li>
* <li> crossref</li>
* <li> decimal</li>
* <li> destdir</li>
* <li> diag</li>
* <li> explicit</li>
* <li> format</li>
* <li> keep</li>
* <li> logo</li>
* <li> replace</li>
* <li> savelog</li>
* <li> srcdir</li>
* <li> sourcedir</li>
* <li> strictargs</li>
* <li> strictassign</li>
* <li> strictcase</li>
* <li> strictimport</li>
* <li> symbols</li>
* <li> time</li>
* <li> trace</li>
* <li> utf8</li>
* <li> verbose</li>
* </ul>
* Of these arguments, the <b>srcdir</b> argument is required. <p>
*
* When this task executes, it will recursively scan the srcdir looking for
* NetRexx source files to compile. This task makes its compile decision based
* on timestamp. <p>
*
* Before files are compiled they and any other file in the srcdir will be
* copied to the destdir allowing support files to be located properly in the
* classpath. The reason for copying the source files before the compile is that
* NetRexxC has only two destinations for classfiles:
* <ol>
* <li> The current directory, and,</li>
* <li> The directory the source is in (see sourcedir option)
* </ol>
*
*
* @author dIon Gillard <a href="mailto:dion@multitask.com.au">
* dion@multitask.com.au</a>
*/

public class NetRexxC extends MatchingTask
{
private boolean compile = true;
private boolean decimal = true;
private boolean logo = true;
private boolean sourcedir = true;
private String trace = "trace2";
private String verbose = "verbose3";

// other implementation variables
private ArrayList compileList = new ArrayList();
private Hashtable filecopyList = new Hashtable();
private String oldClasspath = System.getProperty( "java.class.path" );

// variables to hold arguments
private boolean binary;
private String classpath;
private boolean comments;
private boolean compact;
private boolean console;
private boolean crossref;
private File destDir;
private boolean diag;
private boolean explicit;
private boolean format;
private boolean java;
private boolean keep;
private boolean replace;
private boolean savelog;
private File srcDir;// ?? Should this be the default for ant?
private boolean strictargs;
private boolean strictassign;
private boolean strictcase;
private boolean strictimport;
private boolean strictprops;
private boolean strictsignal;
private boolean symbols;
private boolean time;
private boolean utf8;

/**
* Set whether literals are treated as binary, rather than NetRexx types
*
* @param binary The new Binary value
*/
public void setBinary( boolean binary )
{
this.binary = binary;
}

/**
* Set the classpath used for NetRexx compilation
*
* @param classpath The new Classpath value
*/
public void setClasspath( String classpath )
{
this.classpath = classpath;
}

/**
* Set whether comments are passed through to the generated java source.
* Valid true values are "on" or "true". Anything else sets the flag to
* false. The default value is false
*
* @param comments The new Comments value
*/
public void setComments( boolean comments )
{
this.comments = comments;
}

/**
* Set whether error messages come out in compact or verbose format. Valid
* true values are "on" or "true". Anything else sets the flag to false. The
* default value is false
*
* @param compact The new Compact value
*/
public void setCompact( boolean compact )
{
this.compact = compact;
}

/**
* Set whether the NetRexx compiler should compile the generated java code
* Valid true values are "on" or "true". Anything else sets the flag to
* false. The default value is true. Setting this flag to false, will
* automatically set the keep flag to true.
*
* @param compile The new Compile value
*/
public void setCompile( boolean compile )
{
this.compile = compile;
if( !this.compile && !this.keep )
{
this.keep = true;
}
}

/**
* Set whether or not messages should be displayed on the 'console' Valid
* true values are "on" or "true". Anything else sets the flag to false. The
* default value is true.
*
* @param console The new Console value
*/
public void setConsole( boolean console )
{
this.console = console;
}

/**
* Whether variable cross references are generated
*
* @param crossref The new Crossref value
*/
public void setCrossref( boolean crossref )
{
this.crossref = crossref;
}

/**
* Set whether decimal arithmetic should be used for the netrexx code.
* Binary arithmetic is used when this flag is turned off. Valid true values
* are "on" or "true". Anything else sets the flag to false. The default
* value is true.
*
* @param decimal The new Decimal value
*/
public void setDecimal( boolean decimal )
{
this.decimal = decimal;
}

/**
* Set the destination directory into which the NetRexx source files should
* be copied and then compiled.
*
* @param destDirName The new DestDir value
*/
public void setDestDir( File destDirName )
{
destDir = destDirName;
}

/**
* Whether diagnostic information about the compile is generated
*
* @param diag The new Diag value
*/
public void setDiag( boolean diag )
{
this.diag = diag;
}

/**
* Sets whether variables must be declared explicitly before use. Valid true
* values are "on" or "true". Anything else sets the flag to false. The
* default value is false.
*
* @param explicit The new Explicit value
*/
public void setExplicit( boolean explicit )
{
this.explicit = explicit;
}

/**
* Whether the generated java code is formatted nicely or left to match
* NetRexx line numbers for call stack debugging
*
* @param format The new Format value
*/
public void setFormat( boolean format )
{
this.format = format;
}

/**
* Whether the generated java code is produced Valid true values are "on" or
* "true". Anything else sets the flag to false. The default value is false.
*
* @param java The new Java value
*/
public void setJava( boolean java )
{
this.java = java;
}

/**
* Sets whether the generated java source file should be kept after
* compilation. The generated files will have an extension of .java.keep,
* <b>not</b> .java Valid true values are "on" or "true". Anything else sets
* the flag to false. The default value is false.
*
* @param keep The new Keep value
*/
public void setKeep( boolean keep )
{
this.keep = keep;
}

/**
* Whether the compiler text logo is displayed when compiling
*
* @param logo The new Logo value
*/
public void setLogo( boolean logo )
{
this.logo = logo;
}

/**
* Whether the generated .java file should be replaced when compiling Valid
* true values are "on" or "true". Anything else sets the flag to false. The
* default value is false.
*
* @param replace The new Replace value
*/
public void setReplace( boolean replace )
{
this.replace = replace;
}

/**
* Sets whether the compiler messages will be written to NetRexxC.log as
* well as to the console Valid true values are "on" or "true". Anything
* else sets the flag to false. The default value is false.
*
* @param savelog The new Savelog value
*/
public void setSavelog( boolean savelog )
{
this.savelog = savelog;
}

/**
* Tells the NetRexx compiler to store the class files in the same directory
* as the source files. The alternative is the working directory Valid true
* values are "on" or "true". Anything else sets the flag to false. The
* default value is true.
*
* @param sourcedir The new Sourcedir value
*/
public void setSourcedir( boolean sourcedir )
{
this.sourcedir = sourcedir;
}

/**
* Set the source dir to find the source Java files.
*
* @param srcDirName The new SrcDir value
*/
public void setSrcDir( File srcDirName )
{
srcDir = srcDirName;
}

/**
* Tells the NetRexx compiler that method calls always need parentheses,
* even if no arguments are needed, e.g. <code>aStringVar.getBytes</code>
* vs. <code>aStringVar.getBytes()</code> Valid true values are "on" or
* "true". Anything else sets the flag to false. The default value is false.
*
* @param strictargs The new Strictargs value
*/
public void setStrictargs( boolean strictargs )
{
this.strictargs = strictargs;
}

/**
* Tells the NetRexx compile that assignments must match exactly on type
*
* @param strictassign The new Strictassign value
*/
public void setStrictassign( boolean strictassign )
{
this.strictassign = strictassign;
}

/**
* Specifies whether the NetRexx compiler should be case sensitive or not
*
* @param strictcase The new Strictcase value
*/
public void setStrictcase( boolean strictcase )
{
this.strictcase = strictcase;
}

/**
* Sets whether classes need to be imported explicitly using an <code>import</code>
* statement. By default the NetRexx compiler will import certain packages
* automatically Valid true values are "on" or "true". Anything else sets
* the flag to false. The default value is false.
*
* @param strictimport The new Strictimport value
*/
public void setStrictimport( boolean strictimport )
{
this.strictimport = strictimport;
}

/**
* Sets whether local properties need to be qualified explicitly using
* <code>this</code> Valid true values are "on" or "true". Anything else
* sets the flag to false. The default value is false.
*
* @param strictprops The new Strictprops value
*/
public void setStrictprops( boolean strictprops )
{
this.strictprops = strictprops;
}

/**
* Whether the compiler should force catching of exceptions by explicitly
* named types
*
* @param strictsignal The new Strictsignal value
*/
public void setStrictsignal( boolean strictsignal )
{
this.strictsignal = strictsignal;
}

/**
* Sets whether debug symbols should be generated into the class file Valid
* true values are "on" or "true". Anything else sets the flag to false. The
* default value is false.
*
* @param symbols The new Symbols value
*/
public void setSymbols( boolean symbols )
{
this.symbols = symbols;
}

/**
* Asks the NetRexx compiler to print compilation times to the console Valid
* true values are "on" or "true". Anything else sets the flag to false. The
* default value is false.
*
* @param time The new Time value
*/
public void setTime( boolean time )
{
this.time = time;
}

/**
* Turns on or off tracing and directs the resultant trace output Valid
* values are: "trace", "trace1", "trace2" and "notrace". "trace" and
* "trace2"
*
* @param trace The new Trace value
*/
public void setTrace( String trace )
{
if( trace.equalsIgnoreCase( "trace" )
|| trace.equalsIgnoreCase( "trace1" )
|| trace.equalsIgnoreCase( "trace2" )
|| trace.equalsIgnoreCase( "notrace" ) )
{
this.trace = trace;
}
else
{
throw new TaskException( "Unknown trace value specified: '" + trace + "'" );
}
}

/**
* Tells the NetRexx compiler that the source is in UTF8 Valid true values
* are "on" or "true". Anything else sets the flag to false. The default
* value is false.
*
* @param utf8 The new Utf8 value
*/
public void setUtf8( boolean utf8 )
{
this.utf8 = utf8;
}

/**
* Whether lots of warnings and error messages should be generated
*
* @param verbose The new Verbose value
*/
public void setVerbose( String verbose )
{
this.verbose = verbose;
}

/**
* Executes the task, i.e. does the actual compiler call
*
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
public void execute()
throws TaskException
{

// first off, make sure that we've got a srcdir and destdir
if( srcDir == null || destDir == null )
{
throw new TaskException( "srcDir and destDir attributes must be set!" );
}

// scan source and dest dirs to build up both copy lists and
// compile lists
// scanDir(srcDir, destDir);
DirectoryScanner ds = getDirectoryScanner( srcDir );

String[] files = ds.getIncludedFiles();

scanDir( srcDir, destDir, files );

// copy the source and support files
copyFilesToDestination();

// compile the source files
if( compileList.size() > 0 )
{
getContext().info( "Compiling " + compileList.size() + " source file"
+ ( compileList.size() == 1 ? "" : "s" )
+ " to " + destDir );
doNetRexxCompile();
}
}

/**
* Builds the compilation classpath.
*
* @return The CompileClasspath value
*/
private String getCompileClasspath()
throws TaskException
{
StringBuffer classpath = new StringBuffer();

// add dest dir to classpath so that previously compiled and
// untouched classes are on classpath
classpath.append( destDir.getAbsolutePath() );

// add our classpath to the mix
if( this.classpath != null )
{
addExistingToClasspath( classpath, this.classpath );
}

// add the system classpath
// addExistingToClasspath(classpath,System.getProperty("java.class.path"));
return classpath.toString();
}

/**
* This
*
* @return The CompileOptionsAsArray value
*/
private String[] getCompileOptionsAsArray()
{
ArrayList options = new ArrayList();
options.add( binary ? "-binary" : "-nobinary" );
options.add( comments ? "-comments" : "-nocomments" );
options.add( compile ? "-compile" : "-nocompile" );
options.add( compact ? "-compact" : "-nocompact" );
options.add( console ? "-console" : "-noconsole" );
options.add( crossref ? "-crossref" : "-nocrossref" );
options.add( decimal ? "-decimal" : "-nodecimal" );
options.add( diag ? "-diag" : "-nodiag" );
options.add( explicit ? "-explicit" : "-noexplicit" );
options.add( format ? "-format" : "-noformat" );
options.add( keep ? "-keep" : "-nokeep" );
options.add( logo ? "-logo" : "-nologo" );
options.add( replace ? "-replace" : "-noreplace" );
options.add( savelog ? "-savelog" : "-nosavelog" );
options.add( sourcedir ? "-sourcedir" : "-nosourcedir" );
options.add( strictargs ? "-strictargs" : "-nostrictargs" );
options.add( strictassign ? "-strictassign" : "-nostrictassign" );
options.add( strictcase ? "-strictcase" : "-nostrictcase" );
options.add( strictimport ? "-strictimport" : "-nostrictimport" );
options.add( strictprops ? "-strictprops" : "-nostrictprops" );
options.add( strictsignal ? "-strictsignal" : "-nostrictsignal" );
options.add( symbols ? "-symbols" : "-nosymbols" );
options.add( time ? "-time" : "-notime" );
options.add( "-" + trace );
options.add( utf8 ? "-utf8" : "-noutf8" );
options.add( "-" + verbose );
String[] results = new String[ options.size() ];
options.copyInto( results );
return results;
}

/**
* 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 )
throws TaskException
{
final StringTokenizer tok = new StringTokenizer( source,
System.getProperty( "path.separator" ), false );
while( tok.hasMoreTokens() )
{
File f = getContext().resolveFile( tok.nextToken() );

if( f.exists() )
{
target.append( File.pathSeparator );
target.append( f.getAbsolutePath() );
}
else
{
getContext().debug( "Dropping from classpath: " + f.getAbsolutePath() );
}
}

}

/**
* Copy eligible files from the srcDir to destDir
*/
private void copyFilesToDestination()
{
//FIXME: This should be zapped no ?
if( filecopyList.size() > 0 )
{
getContext().info( "Copying " + filecopyList.size() + " file"
+ ( filecopyList.size() == 1 ? "" : "s" )
+ " to " + destDir.getAbsolutePath() );
Iterator enum = filecopyList.keySet().iterator();
while( enum.hasNext() )
{
String fromFile = (String)enum.next();
String toFile = (String)filecopyList.get( fromFile );
try
{
FileUtil.copyFile( new File( fromFile ), new File( toFile ) );
}
catch( IOException ioe )
{
String msg = "Failed to copy " + fromFile + " to " + toFile
+ " due to " + ioe.getMessage();
throw new TaskException( msg, ioe );
}
}
}
}

/**
* Peforms a copmile using the NetRexx 1.1.x compiler
*
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
private void doNetRexxCompile()
throws TaskException
{
getContext().debug( "Using NetRexx compiler" );
String classpath = getCompileClasspath();
StringBuffer compileOptions = new StringBuffer();
StringBuffer fileList = new StringBuffer();

// create an array of strings for input to the compiler: one array
// comes from the compile options, the other from the compileList
String[] compileOptionsArray = getCompileOptionsAsArray();
String[] fileListArray = new String[ compileList.size() ];
Iterator e = compileList.iterator();
int j = 0;
while( e.hasNext() )
{
fileListArray[ j ] = (String)e.next();
j++;
}
// create a single array of arguments for the compiler
String compileArgs[] = new String[ compileOptionsArray.length + fileListArray.length ];
for( int i = 0; i < compileOptionsArray.length; i++ )
{
compileArgs[ i ] = compileOptionsArray[ i ];
}
for( int i = 0; i < fileListArray.length; i++ )
{
compileArgs[ i + compileOptionsArray.length ] = fileListArray[ i ];
}

// print nice output about what we are doing for the log
compileOptions.append( "Compilation args: " );
for( int i = 0; i < compileOptionsArray.length; i++ )
{
compileOptions.append( compileOptionsArray[ i ] );
compileOptions.append( " " );
}
getContext().debug( compileOptions.toString() );

StringBuffer niceSourceList = new StringBuffer( "Files to be compiled:" + StringUtil.LINE_SEPARATOR );

for( int i = 0; i < compileList.size(); i++ )
{
niceSourceList.append( " " );
niceSourceList.append( compileList.get( i ).toString() );
niceSourceList.append( StringUtil.LINE_SEPARATOR );
}

getContext().debug( niceSourceList.toString() );

// need to set java.class.path property and restore it later
// since the NetRexx compiler has no option for the classpath
String currentClassPath = System.getProperty( "java.class.path" );
Properties currentProperties = System.getProperties();
currentProperties.put( "java.class.path", classpath );

try
{
StringWriter out = new StringWriter();
int rc =
COM.ibm.netrexx.process.NetRexxC.main( new Rexx( compileArgs ), new PrintWriter( out ) );

if( rc > 1 )
{// 1 is warnings from real NetRexxC
getContext().error( out.toString() );
String msg = "Compile failed, messages should have been provided.";
throw new TaskException( msg );
}
else if( rc == 1 )
{
getContext().warn( out.toString() );
}
else
{
getContext().info( out.toString() );
}
}
finally
{
// need to reset java.class.path property
// since the NetRexx compiler has no option for the classpath
currentProperties = System.getProperties();
currentProperties.put( "java.class.path", currentClassPath );
}
}

/**
* Scans the directory looking for source files to be compiled and support
* files to be copied.
*
* @param srcDir Description of Parameter
* @param destDir Description of Parameter
* @param files Description of Parameter
*/
private void scanDir( File srcDir, File destDir, String[] files )
{
for( int i = 0; i < files.length; i++ )
{
File srcFile = new File( srcDir, files[ i ] );
File destFile = new File( destDir, files[ i ] );
String filename = files[ i ];
// if it's a non source file, copy it if a later date than the
// dest
// if it's a source file, see if the destination class file
// needs to be recreated via compilation
if( filename.toLowerCase().endsWith( ".nrx" ) )
{
File classFile =
new File( destDir,
filename.substring( 0, filename.lastIndexOf( '.' ) ) + ".class" );

if( !compile || srcFile.lastModified() > classFile.lastModified() )
{
filecopyList.put( srcFile.getAbsolutePath(), destFile.getAbsolutePath() );
compileList.add( destFile.getAbsolutePath() );
}
}
else
{
if( srcFile.lastModified() > destFile.lastModified() )
{
filecopyList.put( srcFile.getAbsolutePath(), destFile.getAbsolutePath() );
}
}
}
}
}

+ 0
- 323
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/PathConvert.java View File

@@ -1,323 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.io.File;
import java.util.ArrayList;
import org.apache.aut.nativelib.Os;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.file.Path;

/**
* This task converts path and classpath information to a specific target OS
* format. The resulting formatted path is placed into a specified property. <p>
*
* LIMITATION: Currently this implementation groups all machines into one of two
* types: Unix or Windows. Unix is defined as NOT windows.
*
* @author Larry Streepy <a href="mailto:streepy@healthlanguage.com">
* streepy@healthlanguage.com</a>
*/
public class PathConvert extends AbstractTask
{
private Path m_path;// Path to be converted
private String m_targetOS;// The target OS type
private boolean m_targetWindows;// Set when targetOS is set
private boolean m_onWindows;// Set if we're running on windows
private String m_property;// The property to receive the results
private ArrayList m_prefixMap = new ArrayList();// Path prefix map
private String m_pathSep;// User override on path sep char
private String m_dirSep;

/**
* Override the default directory separator string for the target os
*/
public void setDirSep( final String dirSep )
{
m_dirSep = dirSep;
}

/**
* Override the default path separator string for the target os
*
* @param pathSep The new PathSep value
*/
public void setPathSep( final String pathSep )
{
m_pathSep = pathSep;
}

/**
* Set the value of the proprty attribute - this is the property into which
* our converted path will be placed.
*/
public void setProperty( final String property )
{
m_property = property;
}

/**
* Set the value of the targetos attribute
*
* @param targetOS The new Targetos value
*/
public void setTargetos( String targetOS )
throws TaskException
{
m_targetOS = targetOS.toLowerCase();

if( !m_targetOS.equals( "windows" ) && !targetOS.equals( "unix" ) &&
!m_targetOS.equals( "netware" ) )
{
throw new TaskException( "targetos must be one of 'unix', 'netware', or 'windows'" );
}

// Currently, we deal with only two path formats: Unix and Windows
// And Unix is everything that is not Windows

// for NetWare, piggy-back on Windows, since in the validateSetup code,
// the same assumptions can be made as with windows -
// that ; is the path separator

m_targetWindows = ( m_targetOS.equals( "windows" ) || m_targetOS.equals( "netware" ) );
}

/**
* Create a nested MAP element
*/
public void addMap( final MapEntry entry )
{
m_prefixMap.add( entry );
}

/**
* Adds a PATH element
*/
public void addPath( Path path )
throws TaskException
{
if( m_path == null )
{
m_path = path;
}
else
{
m_path.add( path );
}
}

public void execute()
throws TaskException
{
// If we are a reference, the create a Path from the reference
validate();// validate our setup

// Currently, we deal with only two path formats: Unix and Windows
// And Unix is everything that is not Windows
// (with the exception for NetWare below)

// for NetWare, piggy-back on Windows, since here and in the
// apply code, the same assumptions can be made as with windows -
// that \\ is an OK separator, and do comparisons case-insensitive.
m_onWindows = ( Os.isFamily( Os.OS_FAMILY_WINDOWS ) || Os.isFamily( Os.OS_FAMILY_NETWARE ) );

// Determine the from/to char mappings for dir sep
char fromDirSep = m_onWindows ? '\\' : '/';
char toDirSep = m_dirSep.charAt( 0 );

StringBuffer rslt = new StringBuffer( 100 );

// Get the list of path components in canonical form
String[] elems = m_path.listFiles( getContext() );

for( int i = 0; i < elems.length; i++ )
{
String elem = elems[ i ];

elem = mapElement( elem );// Apply the path prefix map

// Now convert the path and file separator characters from the
// current os to the target os.

elem = elem.replace( fromDirSep, toDirSep );

if( i != 0 )
{
rslt.append( m_pathSep );
}
rslt.append( elem );
}

// Place the result into the specified property
final String value = rslt.toString();

getContext().debug( "Set property " + m_property + " = " + value );

final String name = m_property;
getContext().setProperty( name, value );
}

/**
* Apply the configured map to a path element. The map is used to convert
* between Windows drive letters and Unix paths. If no map is configured,
* then the input string is returned unchanged.
*
* @param elem The path element to apply the map to
* @return String Updated element
*/
private String mapElement( String elem )
throws TaskException
{
int size = m_prefixMap.size();

if( size != 0 )
{

// Iterate over the map entries and apply each one. Stop when one of the
// entries actually changes the element

for( int i = 0; i < size; i++ )
{
MapEntry entry = (MapEntry)m_prefixMap.get( i );
String newElem = entry.apply( elem );

// Note I'm using "!=" to see if we got a new object back from
// the apply method.

if( newElem != elem )
{
elem = newElem;
break;// We applied one, so we're done
}
}
}

return elem;
}

/**
* Validate that all our parameters have been properly initialized.
*
* @throws org.apache.myrmidon.api.TaskException if something is not setup properly
*/
private void validate()
throws TaskException
{

if( m_path == null )
{
throw new TaskException( "You must specify a path to convert" );
}

if( m_property == null )
{
throw new TaskException( "You must specify a property" );
}

// Must either have a target OS or both a dirSep and pathSep

if( m_targetOS == null && m_pathSep == null && m_dirSep == null )
{
throw new TaskException( "You must specify at least one of targetOS, dirSep, or pathSep" );
}

// Determine the separator strings. The dirsep and pathsep attributes
// override the targetOS settings.
String dsep = File.separator;
String psep = File.pathSeparator;

if( m_targetOS != null )
{
psep = m_targetWindows ? ";" : ":";
dsep = m_targetWindows ? "\\" : "/";
}

if( m_pathSep != null )
{// override with pathsep=
psep = m_pathSep;
}

if( m_dirSep != null )
{// override with dirsep=
dsep = m_dirSep;
}

m_pathSep = psep;
m_dirSep = dsep;
}

/**
* Helper class, holds the nested <map> values. Elements will look like
* this: &lt;map from="d:" to="/foo"/> <p>
*
* When running on windows, the prefix comparison will be case insensitive.
*/
public class MapEntry
{
private String m_from;
private String m_to;

/**
* Set the "from" attribute of the map entry
*
* @param from The new From value
*/
public void setFrom( final String from )
{
m_from = from;
}

/**
* Set the "to" attribute of the map entry
*
* @param to The new To value
*/
public void setTo( final String to )
{
m_to = to;
}

/**
* Apply this map entry to a given path element
*
* @param elem Path element to process
* @return String Updated path element after mapping
*/
public String apply( String elem )
throws TaskException
{
if( m_from == null || m_to == null )
{
throw new TaskException( "Both 'from' and 'to' must be set in a map entry" );
}

// If we're on windows, then do the comparison ignoring case
final String cmpElem = m_onWindows ? elem.toLowerCase() : elem;
final String cmpFrom = m_onWindows ? m_from.toLowerCase() : m_from;

// If the element starts with the configured prefix, then convert the prefix
// to the configured 'to' value.

if( cmpElem.startsWith( cmpFrom ) )
{
final int len = m_from.length();
if( len >= elem.length() )
{
elem = m_to;
}
else
{
elem = m_to + elem.substring( len );
}
}

return elem;
}
}
}

+ 0
- 141
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Property.java View File

@@ -1,141 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Properties;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.file.Path;
import org.apache.myrmidon.framework.file.FileListUtil;

/**
* Will set a Project property. Used to be a hack in ProjectHelper Will not
* override values set by the command line or parent projects.
*
* @author costin@dnt.ro
* @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a>
* @author <a href="mailto:glennm@ca.ibm.com">Glenn McAllister</a>
*/
public class Property
extends AbstractTask
{
private Path m_classpath = new Path();

private String m_name;
private String m_resource;
private String m_value;

public void addClasspath( final Path classpath )
throws TaskException
{
m_classpath.add( classpath );
}

public void setLocation( File location )
{
setValue( location.getAbsolutePath() );
}

public void setName( String name )
{
m_name = name;
}

public void setResource( String resource )
{
m_resource = resource;
}

public void setValue( String value )
{
m_value = value;
}

public void execute()
throws TaskException
{
validate();

if( ( m_name != null ) && ( m_value != null ) )
{
final String name = m_name;
final Object value = m_value;
getContext().setProperty( name, value );
}

if( m_resource != null )
{
loadResource( m_resource );
}
}

private void validate() throws TaskException
{
if( m_name != null )
{
if( m_value == null )
{
throw new TaskException( "You must specify value, location or refid with the name attribute" );
}
}
else
{
if( m_resource == null )
{
throw new TaskException( "You must specify resource when not using the name attribute" );
}
}
}

public String toString()
{
return m_value == null ? "" : m_value;
}

protected void addProperties( Properties props )
throws TaskException
{
final Iterator e = props.keySet().iterator();
while( e.hasNext() )
{
final String name = (String)e.next();
final String value = (String)props.getProperty( name );
getContext().setProperty( name, value );
}
}

protected void loadResource( String name )
throws TaskException
{
Properties props = new Properties();
getContext().debug( "Resource Loading " + name );
try
{
final ClassLoader classLoader = FileListUtil.createClassLoader( m_classpath, getContext() );
final InputStream is = classLoader.getResourceAsStream( name );

if( is != null )
{
props.load( is );
addProperties( props );
}
else
{
getContext().warn( "Unable to find resource " + name );
}
}
catch( IOException ex )
{
throw new TaskException( "Error", ex );
}
}
}

+ 0
- 128
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Rpm.java View File

@@ -1,128 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.io.File;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.nativelib.Execute;
import org.apache.myrmidon.framework.nativelib.Commandline;

/**
* @author lucas@collab.net
*/
public class Rpm
extends AbstractTask
{
/**
* the rpm command to use
*/
private String m_command = "-bb";

/**
* clean BUILD directory
*/
private boolean m_cleanBuildDir;

/**
* remove spec file
*/
private boolean m_removeSpec;

/**
* remove sources
*/
private boolean m_removeSource;

/**
* the spec file
*/
private String m_specFile;

/**
* the rpm top dir
*/
private File m_topDir;

public void setCleanBuildDir( boolean cleanBuildDir )
{
m_cleanBuildDir = cleanBuildDir;
}

public void setCommand( final String command )
{
m_command = command;
}

public void setRemoveSource( final boolean removeSource )
{
m_removeSource = removeSource;
}

public void setRemoveSpec( final boolean removeSpec )
{
m_removeSpec = removeSpec;
}

public void setSpecFile( final String specFile )
throws TaskException
{
if( ( specFile == null ) || ( specFile.trim().equals( "" ) ) )
{
throw new TaskException( "You must specify a spec file" );
}
m_specFile = specFile;
}

public void setTopDir( final File topDir )
{
m_topDir = topDir;
}

public void execute()
throws TaskException
{
final Execute exe = createCommand();
exe.setWorkingDirectory( m_topDir );

final String message = "Building the RPM based on the " + m_specFile + " file";
getContext().info( message );
exe.execute( getContext() );
}

private Execute createCommand()
throws TaskException
{
final Execute cmd = new Execute();
cmd.setExecutable( "rpm" );
if( m_topDir != null )
{
cmd.addArgument( "--define" );
cmd.addArgument( "_topdir" + m_topDir );
}

cmd.addLine( m_command );

if( m_cleanBuildDir )
{
cmd.addArgument( "--clean" );
}
if( m_removeSpec )
{
cmd.addArgument( "--rmspec" );
}
if( m_removeSource )
{
cmd.addArgument( "--rmsource" );
}

cmd.addArgument( "SPECS/" + m_specFile );

return cmd;
}
}

+ 0
- 836
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/SQLExec.java View File

@@ -1,836 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Reader;
import java.io.StringReader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Driver;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Properties;
import java.util.StringTokenizer;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.file.Path;
import org.apache.myrmidon.framework.file.FileListUtil;
import org.apache.myrmidon.framework.FileSet;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.tools.todo.types.EnumeratedAttribute;
import org.apache.tools.todo.types.ScannerUtil;

/**
* Reads in a text file containing SQL statements seperated with semicolons and
* executes it in a given db. Comments may be created with REM -- or //.
*
* @author <a href="mailto:jeff@custommonkey.org">Jeff Martin</a>
* @author <A href="mailto:gholam@xtra.co.nz">Michael McCallum</A>
* @author <A href="mailto:tim.stephenson@sybase.com">Tim Stephenson</A>
*/
public class SQLExec
extends AbstractTask
{
private int goodSql = 0, totalSql = 0;

private ArrayList filesets = new ArrayList();

/**
* Database connection
*/
private Connection conn;

/**
* Autocommit flag. Default value is false
*/
private boolean autocommit;

/**
* SQL statement
*/
private Statement statement;

/**
* DB driver.
*/
private String driver;

/**
* DB url.
*/
private String url;

/**
* User name.
*/
private String userId;

/**
* Password
*/
private String password;

/**
* SQL input file
*/
private File srcFile;

/**
* SQL input command
*/
private String sqlCommand = "";

/**
* SQL transactions to perform
*/
private ArrayList transactions = new ArrayList();

/**
* SQL Statement delimiter
*/
private String delimiter = ";";

/**
* The delimiter type indicating whether the delimiter will only be
* recognized on a line by itself
*/
private String delimiterType = DelimiterType.NORMAL;

/**
* Print SQL results.
*/
private boolean print;

/**
* Print header columns.
*/
private boolean showheaders = true;

/**
* Results Output file.
*/
private File output;

/**
* RDBMS Product needed for this SQL.
*/
private String rdbms;

/**
* RDBMS Version needed for this SQL.
*/
private String version;

/**
* Action to perform if an error is found
*/
private String onError = "abort";

/**
* Encoding to use when reading SQL statements from a file
*/
private String encoding;

private Path classpath = new Path();

/**
* Set the autocommit flag for the DB connection.
*
* @param autocommit The new Autocommit value
*/
public void setAutocommit( boolean autocommit )
{
this.autocommit = autocommit;
}

/**
* Adds an element to the classpath for loading the driver.
*
* @param classpath The new Classpath value
*/
public void addClasspath( final Path classpath )
throws TaskException
{
this.classpath.add( classpath );
}

/**
* Set the statement delimiter. <p>
*
* For example, set this to "go" and delimitertype to "ROW" for Sybase ASE
* or MS SQL Server.</p>
*
* @param delimiter The new Delimiter value
*/
public void setDelimiter( String delimiter )
{
this.delimiter = delimiter;
}

/**
* Set the Delimiter type for this sql task. The delimiter type takes two
* values - normal and row. Normal means that any occurence of the delimiter
* terminate the SQL command whereas with row, only a line containing just
* the delimiter is recognized as the end of the command.
*
* @param delimiterType The new DelimiterType value
*/
public void setDelimiterType( DelimiterType delimiterType )
{
this.delimiterType = delimiterType.getValue();
}

/**
* Set the JDBC driver to be used.
*
* @param driver The new Driver value
*/
public void setDriver( String driver )
{
this.driver = driver;
}

/**
* Set the file encoding to use on the sql files read in
*
* @param encoding the encoding to use on the files
*/
public void setEncoding( String encoding )
{
this.encoding = encoding;
}

/**
* Set the action to perform onerror
*
* @param action The new Onerror value
*/
public void setOnerror( OnError action )
{
this.onError = action.getValue();
}

/**
* Set the output file.
*
* @param output The new Output value
*/
public void setOutput( File output )
{
this.output = output;
}

/**
* Set the password for the DB connection.
*
* @param password The new Password value
*/
public void setPassword( String password )
{
this.password = password;
}

/**
* Set the print flag.
*
* @param print The new Print value
*/
public void setPrint( boolean print )
{
this.print = print;
}

/**
* Set the rdbms required
*
* @param vendor The new Rdbms value
*/
public void setRdbms( String vendor )
{
this.rdbms = vendor.toLowerCase();
}

/**
* Set the showheaders flag.
*
* @param showheaders The new Showheaders value
*/
public void setShowheaders( boolean showheaders )
{
this.showheaders = showheaders;
}

/**
* Set the name of the sql file to be run.
*
* @param srcFile The new Src value
*/
public void setSrc( File srcFile )
{
this.srcFile = srcFile;
}

/**
* Set the DB connection url.
*
* @param url The new Url value
*/
public void setUrl( String url )
{
this.url = url;
}

/**
* Set the user name for the DB connection.
*
* @param userId The new Userid value
*/
public void setUserid( String userId )
{
this.userId = userId;
}

/**
* Set the version required
*
* @param version The new Version value
*/
public void setVersion( String version )
{
this.version = version.toLowerCase();
}

/**
* Adds a set of files (nested fileset attribute).
*
* @param set The feature to be added to the Fileset attribute
*/
public void addFileset( FileSet set )
{
filesets.add( set );
}

/**
* Set the sql command to execute
*
* @param sql The feature to be added to the Text attribute
*/
public void addContent( String sql )
{
this.sqlCommand += sql;
}

/**
* Set the sql command to execute
*
* @return Description of the Returned Value
*/
public Transaction createTransaction()
{
Transaction t = new Transaction();
transactions.add( t );
return t;
}

/**
* Load the sql file and then execute it
*
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
public void execute()
throws TaskException
{
sqlCommand = sqlCommand.trim();

if( srcFile == null && sqlCommand.length() == 0 && filesets.isEmpty() )
{
if( transactions.size() == 0 )
{
throw new TaskException( "Source file or fileset, transactions or sql statement must be set!" );
}
}
else
{
// deal with the filesets
for( int i = 0; i < filesets.size(); i++ )
{
FileSet fs = (FileSet)filesets.get( i );
DirectoryScanner ds = ScannerUtil.getDirectoryScanner( fs );
File srcDir = fs.getDir();

String[] srcFiles = ds.getIncludedFiles();

// Make a transaction for each file
for( int j = 0; j < srcFiles.length; j++ )
{
Transaction t = createTransaction();
t.setSrc( new File( srcDir, srcFiles[ j ] ) );
}
}

// Make a transaction group for the outer command
Transaction t = createTransaction();
t.setSrc( srcFile );
t.addContent( sqlCommand );
}

if( driver == null )
{
throw new TaskException( "Driver attribute must be set!" );
}
if( userId == null )
{
throw new TaskException( "User Id attribute must be set!" );
}
if( password == null )
{
throw new TaskException( "Password attribute must be set!" );
}
if( url == null )
{
throw new TaskException( "Url attribute must be set!" );
}
if( srcFile != null && !srcFile.exists() )
{
throw new TaskException( "Source file does not exist!" );
}
Driver driverInstance = null;
// Load the driver using the
try
{
final ClassLoader classLoader = FileListUtil.createClassLoader( classpath, getContext() );
final Class dc = classLoader.loadClass( driver );
driverInstance = (Driver)dc.newInstance();
}
catch( ClassNotFoundException e )
{
throw new TaskException( "Class Not Found: JDBC driver " + driver + " could not be loaded" );
}
catch( IllegalAccessException e )
{
throw new TaskException( "Illegal Access: JDBC driver " + driver + " could not be loaded" );
}
catch( InstantiationException e )
{
throw new TaskException( "Instantiation Exception: JDBC driver " + driver + " could not be loaded" );
}

try
{
getContext().debug( "connecting to " + url );
Properties info = new Properties();
info.put( "user", userId );
info.put( "password", password );
conn = driverInstance.connect( url, info );

if( conn == null )
{
// Driver doesn't understand the URL
throw new SQLException( "No suitable Driver for " + url );
}

if( !isValidRdbms( conn ) )
{
return;
}

conn.setAutoCommit( autocommit );

statement = conn.createStatement();

PrintStream out = System.out;
try
{
if( output != null )
{
getContext().debug( "Opening PrintStream to output file " + output );
out = new PrintStream( new BufferedOutputStream( new FileOutputStream( output ) ) );
}

// Process all transactions
for( Iterator e = transactions.iterator();
e.hasNext(); )
{

( (Transaction)e.next() ).runTransaction( out );
if( !autocommit )
{
getContext().debug( "Commiting transaction" );
conn.commit();
}
}
}
finally
{
if( out != null && out != System.out )
{
out.close();
}
}
}
catch( IOException e )
{
if( !autocommit && conn != null && onError.equals( "abort" ) )
{
try
{
conn.rollback();
}
catch( SQLException ex )
{
}
}
throw new TaskException( "Error", e );
}
catch( SQLException e )
{
if( !autocommit && conn != null && onError.equals( "abort" ) )
{
try
{
conn.rollback();
}
catch( SQLException ex )
{
}
}
throw new TaskException( "Error", e );
}
finally
{
try
{
if( statement != null )
{
statement.close();
}
if( conn != null )
{
conn.close();
}
}
catch( SQLException e )
{
}
}

getContext().info( goodSql + " of " + totalSql +
" SQL statements executed successfully" );
}

/**
* Verify if connected to the correct RDBMS
*
* @param conn Description of Parameter
* @return The ValidRdbms value
*/
protected boolean isValidRdbms( Connection conn )
{
if( rdbms == null && version == null )
{
return true;
}

try
{
DatabaseMetaData dmd = conn.getMetaData();

if( rdbms != null )
{
String theVendor = dmd.getDatabaseProductName().toLowerCase();

getContext().debug( "RDBMS = " + theVendor );
if( theVendor == null || theVendor.indexOf( rdbms ) < 0 )
{
getContext().debug( "Not the required RDBMS: " + rdbms );
return false;
}
}

if( version != null )
{
String theVersion = dmd.getDatabaseProductVersion().toLowerCase();

getContext().debug( "Version = " + theVersion );
if( theVersion == null ||
!( theVersion.startsWith( version ) ||
theVersion.indexOf( " " + version ) >= 0 ) )
{
getContext().debug( "Not the required version: \"" + version + "\"" );
return false;
}
}
}
catch( SQLException e )
{
// Could not get the required information
getContext().error( "Failed to obtain required RDBMS information" );
return false;
}

return true;
}

/**
* Exec the sql statement.
*
* @param sql Description of Parameter
* @param out Description of Parameter
* @exception java.sql.SQLException Description of Exception
*/
protected void execSQL( String sql, PrintStream out )
throws SQLException
{
// Check and ignore empty statements
if( "".equals( sql.trim() ) )
{
return;
}

try
{
totalSql++;
if( !statement.execute( sql ) )
{
getContext().debug( statement.getUpdateCount() + " rows affected" );
}
else
{
if( print )
{
printResults( out );
}
}

SQLWarning warning = conn.getWarnings();
while( warning != null )
{
getContext().debug( warning + " sql warning" );
warning = warning.getNextWarning();
}
conn.clearWarnings();
goodSql++;
}
catch( SQLException e )
{
getContext().error( "Failed to execute: " + sql );
if( !onError.equals( "continue" ) )
{
throw e;
}
getContext().error( e.toString() );
}
}

/**
* print any results in the statement.
*
* @param out Description of Parameter
* @exception java.sql.SQLException Description of Exception
*/
protected void printResults( PrintStream out )
throws java.sql.SQLException
{
ResultSet rs = null;
do
{
rs = statement.getResultSet();
if( rs != null )
{
getContext().debug( "Processing new result set." );
ResultSetMetaData md = rs.getMetaData();
int columnCount = md.getColumnCount();
StringBuffer line = new StringBuffer();
if( showheaders )
{
for( int col = 1; col < columnCount; col++ )
{
line.append( md.getColumnName( col ) );
line.append( "," );
}
line.append( md.getColumnName( columnCount ) );
out.println( line );
line.setLength( 0 );
}
while( rs.next() )
{
boolean first = true;
for( int col = 1; col <= columnCount; col++ )
{
String columnValue = rs.getString( col );
if( columnValue != null )
{
columnValue = columnValue.trim();
}

if( first )
{
first = false;
}
else
{
line.append( "," );
}
line.append( columnValue );
}
out.println( line );
line.setLength( 0 );
}
}
} while( statement.getMoreResults() );
out.println();
}

protected void runStatements( Reader reader, PrintStream out )
throws SQLException, IOException, TaskException
{
String sql = "";
String line = "";

BufferedReader in = new BufferedReader( reader );

try
{
while( ( line = in.readLine() ) != null )
{
line = line.trim();
final String value = line;
line = "" + getContext().resolveValue( value );
if( line.startsWith( "//" ) )
{
continue;
}
if( line.startsWith( "--" ) )
{
continue;
}
StringTokenizer st = new StringTokenizer( line );
if( st.hasMoreTokens() )
{
String token = st.nextToken();
if( "REM".equalsIgnoreCase( token ) )
{
continue;
}
}

sql += " " + line;
sql = sql.trim();

// SQL defines "--" as a comment to EOL
// and in Oracle it may contain a hint
// so we cannot just remove it, instead we must end it
if( line.indexOf( "--" ) >= 0 )
{
sql += "\n";
}

if( delimiterType.equals( DelimiterType.NORMAL ) && sql.endsWith( delimiter ) ||
delimiterType.equals( DelimiterType.ROW ) && line.equals( delimiter ) )
{
getContext().debug( "SQL: " + sql );
execSQL( sql.substring( 0, sql.length() - delimiter.length() ), out );
sql = "";
}
}

// Catch any statements not followed by ;
if( !sql.equals( "" ) )
{
execSQL( sql, out );
}
}
catch( SQLException e )
{
throw e;
}

}

public static class DelimiterType extends EnumeratedAttribute
{
public final static String NORMAL = "normal";
public final static String ROW = "row";

public String[] getValues()
{
return new String[]{NORMAL, ROW};
}
}

/**
* Enumerated attribute with the values "continue", "stop" and "abort" for
* the onerror attribute.
*
* @author RT
*/
public static class OnError extends EnumeratedAttribute
{
public String[] getValues()
{
return new String[]{"continue", "stop", "abort"};
}
}

/**
* Contains the definition of a new transaction element. Transactions allow
* several files or blocks of statements to be executed using the same JDBC
* connection and commit operation in between.
*
* @author RT
*/
public class Transaction
{
private File tSrcFile = null;
private String tSqlCommand = "";

public void setSrc( File src )
{
this.tSrcFile = src;
}

public void addContent( String sql )
{
this.tSqlCommand += sql;
}

private void runTransaction( PrintStream out )
throws IOException, SQLException, TaskException
{
if( tSqlCommand.length() != 0 )
{
getContext().info( "Executing commands" );
runStatements( new StringReader( tSqlCommand ), out );
}

if( tSrcFile != null )
{
getContext().info( "Executing file: " + tSrcFile.getAbsolutePath() );
Reader reader = ( encoding == null ) ? new FileReader( tSrcFile )
: new InputStreamReader( new FileInputStream( tSrcFile ), encoding );
runStatements( reader, out );
reader.close();
}
}
}

}

+ 0
- 155
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Script.java View File

@@ -1,155 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import com.ibm.bsf.BSFException;
import com.ibm.bsf.BSFManager;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;

/**
* Execute a script
*
* @author Sam Ruby <a href="mailto:rubys@us.ibm.com">rubys@us.ibm.com</a>
*/
public class Script extends AbstractTask
{
private String script = "";
private Hashtable beans = new Hashtable();
private String language;

/**
* Defines the language (required).
*
* @param language The new Language value
*/
public void setLanguage( String language )
{
this.language = language;
}

/**
* Load the script from an external file
*
* @param fileName The new Src value
*/
public void setSrc( String fileName )
{
File file = new File( fileName );
if( !file.exists() )
{
throw new TaskException( "file " + fileName + " not found." );
}

int count = (int)file.length();
byte data[] = new byte[ count ];

try
{
FileInputStream inStream = new FileInputStream( file );
inStream.read( data );
inStream.close();
}
catch( IOException e )
{
throw new TaskException( "Error", e );
}

script += new String( data );
}

/**
* Defines the script.
*
* @param text The feature to be added to the Text attribute
*/
public void addContent( String text )
{
this.script += text;
}

/**
* Do the work.
*
* @exception org.apache.myrmidon.api.TaskException if someting goes wrong with the build
*/
public void execute()
throws TaskException
{
try
{
addBeans( getContext().getProperties() );
//In Ant2 there is no difference between properties and references
//addBeans( getProject().getReferences() );

beans.put( "context", getContext() );

beans.put( "self", this );

BSFManager manager = new BSFManager();

for( Iterator e = beans.keys(); e.hasNext(); )
{
String key = (String)e.next();
Object value = beans.get( key );
manager.declareBean( key, value, value.getClass() );
}

// execute the script
manager.exec( language, "<ANT>", 0, 0, script );
}
catch( BSFException be )
{
Throwable t = be;
Throwable te = be.getTargetException();
if( te != null )
{
if( te instanceof TaskException )
{
throw (TaskException)te;
}
else
{
t = te;
}
}
throw new TaskException( "Error", t );
}
}

/**
* Add a list of named objects to the list to be exported to the script
*
* @param dictionary The feature to be added to the Beans attribute
*/
private void addBeans( Hashtable dictionary )
{
for( Iterator e = dictionary.keys(); e.hasNext(); )
{
String key = (String)e.next();

boolean isValid = key.length() > 0 &&
Character.isJavaIdentifierStart( key.charAt( 0 ) );

for( int i = 1; isValid && i < key.length(); i++ )
{
isValid = Character.isJavaIdentifierPart( key.charAt( i ) );
}

if( isValid )
{
beans.put( key, dictionary.get( key ) );
}
}
}
}

+ 0
- 256
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/Tstamp.java View File

@@ -1,256 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.TimeZone;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.todo.types.EnumeratedAttribute;

/**
* Sets TSTAMP, DSTAMP and TODAY
*
* @author costin@dnt.ro
* @author stefano@apache.org
* @author roxspring@yahoo.com
* @author Conor MacNeill
* @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
*/
public class Tstamp
extends AbstractTask
{
private ArrayList customFormats = new ArrayList();
private String m_prefix = "";

public void setPrefix( String prefix )
{
this.m_prefix = prefix;
if( !this.m_prefix.endsWith( "." ) )
{
this.m_prefix += ".";
}
}

public CustomFormat createFormat()
{
CustomFormat cts = new CustomFormat( m_prefix );
customFormats.add( cts );
return cts;
}

public void execute()
throws TaskException
{
try
{
Date d = new Date();

SimpleDateFormat dstamp = new SimpleDateFormat( "yyyyMMdd" );
final String name = m_prefix + "DSTAMP";
final Object value = dstamp.format( d );
getContext().setProperty( name, value );

SimpleDateFormat tstamp = new SimpleDateFormat( "HHmm" );
final String name1 = m_prefix + "TSTAMP";
final Object value1 = tstamp.format( d );
getContext().setProperty( name1, value1 );

SimpleDateFormat today = new SimpleDateFormat( "MMMM d yyyy", Locale.US );
final String name2 = m_prefix + "TODAY";
final Object value2 = today.format( d );
getContext().setProperty( name2, value2 );

Iterator i = customFormats.iterator();
while( i.hasNext() )
{
CustomFormat cts = (CustomFormat)i.next();
cts.execute( d );
}

}
catch( Exception e )
{
throw new TaskException( "Error", e );
}
}

public static class Unit extends EnumeratedAttribute
{

private final static String MILLISECOND = "millisecond";
private final static String SECOND = "second";
private final static String MINUTE = "minute";
private final static String HOUR = "hour";
private final static String DAY = "day";
private final static String WEEK = "week";
private final static String MONTH = "month";
private final static String YEAR = "year";

private final static String[] units = {
MILLISECOND,
SECOND,
MINUTE,
HOUR,
DAY,
WEEK,
MONTH,
YEAR
};

private Hashtable calendarFields = new Hashtable();

public Unit()
{
calendarFields.put( MILLISECOND,
new Integer( Calendar.MILLISECOND ) );
calendarFields.put( SECOND, new Integer( Calendar.SECOND ) );
calendarFields.put( MINUTE, new Integer( Calendar.MINUTE ) );
calendarFields.put( HOUR, new Integer( Calendar.HOUR_OF_DAY ) );
calendarFields.put( DAY, new Integer( Calendar.DATE ) );
calendarFields.put( WEEK, new Integer( Calendar.WEEK_OF_YEAR ) );
calendarFields.put( MONTH, new Integer( Calendar.MONTH ) );
calendarFields.put( YEAR, new Integer( Calendar.YEAR ) );
}

public int getCalendarField()
{
String key = getValue().toLowerCase();
Integer i = (Integer)calendarFields.get( key );
return i.intValue();
}

public String[] getValues()
{
return units;
}
}

public class CustomFormat
{
private int offset = 0;
private int field = Calendar.DATE;
private String prefix = "";
private String country;
private String language;
private String pattern;
private String propertyName;
private TimeZone timeZone;
private String variant;

public CustomFormat( String prefix )
{
this.prefix = prefix;
}

public void setLocale( String locale )
throws TaskException
{
StringTokenizer st = new StringTokenizer( locale, " \t\n\r\f," );
try
{
language = st.nextToken();
if( st.hasMoreElements() )
{
country = st.nextToken();
if( st.hasMoreElements() )
{
country = st.nextToken();
if( st.hasMoreElements() )
{
throw new TaskException( "bad locale format" );
}
}
}
else
{
country = "";
}
}
catch( NoSuchElementException e )
{
throw new TaskException( "bad locale format", e );
}
}

public void setOffset( int offset )
{
this.offset = offset;
}

public void setPattern( String pattern )
{
this.pattern = pattern;
}

public void setProperty( String propertyName )
{
this.propertyName = prefix + propertyName;
}

public void setTimezone( String id )
{
timeZone = TimeZone.getTimeZone( id );
}

public void setUnit( Unit unit )
{
field = unit.getCalendarField();
}

public void execute( final Date date )
throws TaskException
{
if( propertyName == null )
{
throw new TaskException( "property attribute must be provided" );
}

if( pattern == null )
{
throw new TaskException( "pattern attribute must be provided" );
}

SimpleDateFormat sdf;
if( language == null )
{
sdf = new SimpleDateFormat( pattern );
}
else if( variant == null )
{
sdf = new SimpleDateFormat( pattern, new Locale( language, country ) );
}
else
{
sdf = new SimpleDateFormat( pattern, new Locale( language, country, variant ) );
}

Date time = date;
if( offset != 0 )
{
final Calendar calendar = Calendar.getInstance();
calendar.setTime( time );
calendar.add( field, offset );
time = calendar.getTime();
}
if( timeZone != null )
{
sdf.setTimeZone( timeZone );
}
getContext().setProperty( propertyName, sdf.format( time ) );
}
}
}

+ 0
- 181
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/WaitFor.java View File

@@ -1,181 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs;

import java.util.Hashtable;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.framework.conditions.AndCondition;
import org.apache.myrmidon.framework.conditions.Condition;
import org.apache.tools.todo.types.EnumeratedAttribute;

/**
* Wait for an external event to occur. Wait for an external process to start or
* to complete some task. This is useful with the <code>parallel</code> task to
* syncronize the execution of tests with server startup. The following
* attributes can be specified on a waitfor task:
* <ul>
* <li> maxwait - maximum length of time to wait before giving up</li>
* <li> maxwaitunit - The unit to be used to interpret maxwait attribute</li>
*
* <li> checkevery - amount of time to sleep between each check</li>
* <li> checkeveryunit - The unit to be used to interpret checkevery attribute
* </li>
* <li> timeoutproperty - name of a property to set if maxwait has been
* exceeded.</li>
* </ul>
* The maxwaitunit and checkeveryunit are allowed to have the following values:
* millesond, second, minute, hour, day and week. The default is millisecond.
*
* @author <a href="mailto:denis@network365.com">Denis Hennessy</a>
* @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
*/

public class WaitFor
extends AbstractTask
{
private long maxWaitMillis = 1000l * 60l * 3l;// default max wait time
private long maxWaitMultiplier = 1l;
private long checkEveryMillis = 500l;
private long checkEveryMultiplier = 1l;
private String timeoutProperty;
private AndCondition m_condition = new AndCondition();

/**
* Adds a condition.
*/
public void add( final Condition condition )
{
m_condition.add( condition );
}

/**
* Set the time between each check
*
* @param time The new CheckEvery value
*/
public void setCheckEvery( long time )
{
checkEveryMillis = time;
}

/**
* Set the check every time unit
*
* @param unit The new CheckEveryUnit value
*/
public void setCheckEveryUnit( Unit unit )
{
checkEveryMultiplier = unit.getMultiplier();
}

/**
* Set the maximum length of time to wait
*
* @param time The new MaxWait value
*/
public void setMaxWait( long time )
{
maxWaitMillis = time;
}

/**
* Set the max wait time unit
*
* @param unit The new MaxWaitUnit value
*/
public void setMaxWaitUnit( Unit unit )
{
maxWaitMultiplier = unit.getMultiplier();
}

/**
* Set the timeout property.
*
* @param p The new TimeoutProperty value
*/
public void setTimeoutProperty( String p )
{
timeoutProperty = p;
}

/**
* Check repeatedly for the specified conditions until they become true or
* the timeout expires.
*
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
public void execute()
throws TaskException
{
maxWaitMillis *= maxWaitMultiplier;
checkEveryMillis *= checkEveryMultiplier;
long start = System.currentTimeMillis();
long end = start + maxWaitMillis;

while( System.currentTimeMillis() < end )
{
if( m_condition.evaluate( getContext() ) )
{
return;
}
try
{
Thread.sleep( checkEveryMillis );
}
catch( InterruptedException e )
{
}
}

if( timeoutProperty != null )
{
final String name = timeoutProperty;
getContext().setProperty( name, "true" );
}
}

public static class Unit extends EnumeratedAttribute
{

private final static String MILLISECOND = "millisecond";
private final static String SECOND = "second";
private final static String MINUTE = "minute";
private final static String HOUR = "hour";
private final static String DAY = "day";
private final static String WEEK = "week";

private final static String[] units = {
MILLISECOND, SECOND, MINUTE, HOUR, DAY, WEEK
};

private Hashtable timeTable = new Hashtable();

public Unit()
{
timeTable.put( MILLISECOND, new Long( 1l ) );
timeTable.put( SECOND, new Long( 1000l ) );
timeTable.put( MINUTE, new Long( 1000l * 60l ) );
timeTable.put( HOUR, new Long( 1000l * 60l * 60l ) );
timeTable.put( DAY, new Long( 1000l * 60l * 60l * 24l ) );
timeTable.put( WEEK, new Long( 1000l * 60l * 60l * 24l * 7l ) );
}

public long getMultiplier()
{
String key = getValue().toLowerCase();
Long l = (Long)timeTable.get( key );
return l.longValue();
}

public String[] getValues()
{
return units;
}
}
}

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

@@ -1,97 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import java.io.File;
import java.io.IOException;
import org.apache.excalibur.zip.ZipOutputStream;
import org.apache.myrmidon.api.TaskException;

/**
* Creates a EAR archive. Based on WAR task
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:leslie.hughes@rubus.com">Les Hughes</a>
*/
public class Ear
extends Jar
{
private File m_appxml;
private boolean m_descriptorAdded;

public Ear()
{
m_archiveType = "ear";
m_emptyBehavior = "create";
}

public void setAppxml( final File appxml )
throws TaskException
{
m_appxml = appxml;
if( !m_appxml.exists() )
{
final String message = "Deployment descriptor: " +
m_appxml + " does not exist.";
throw new TaskException( message );
}

addFileAs( m_appxml, "META-INF/application.xml" );
}

public void addArchives( ZipFileSet fs )
{
// We just set the prefix for this fileset, and pass it up.
// Do we need to do this? LH
getContext().debug( "addArchives called" );
fs.setPrefix( "/" );
super.addFileset( fs );
}

protected void initZipOutputStream( final ZipOutputStream zOut )
throws IOException, TaskException
{
if( m_appxml == null && !isInUpdateMode() )
{
final String message = "appxml attribute is required";
throw new TaskException( message );
}

super.initZipOutputStream( zOut );
}

protected void zipFile( File file, ZipOutputStream zOut, String vPath )
throws IOException, TaskException
{
// If the file being added is WEB-INF/web.xml, we warn if it's not the
// one specified in the "webxml" attribute - or if it's being added twice,
// meaning the same file is specified by the "webxml" attribute and in
// a <fileset> element.
if( vPath.equalsIgnoreCase( "META-INF/aplication.xml" ) )
{
if( m_appxml == null ||
!m_appxml.equals( file ) ||
m_descriptorAdded )
{
final String message = "Warning: selected " + m_archiveType +
" files include a META-INF/application.xml which will be ignored " +
"(please use appxml attribute to " + m_archiveType + " task)";
getContext().warn( message );
}
else
{
super.zipFile( file, zOut, vPath );
m_descriptorAdded = true;
}
}
else
{
super.zipFile( file, zOut, vPath );
}
}
}

+ 0
- 286
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Expand.java View File

@@ -1,286 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.avalon.excalibur.io.IOUtil;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.FileSet;
import org.apache.myrmidon.framework.PatternSet;
import org.apache.myrmidon.framework.PatternUtil;
import org.apache.tools.todo.taskdefs.MatchingTask;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.tools.todo.types.ScannerUtil;

/**
* Unzip a file.
*
* @author costin@dnt.ro
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a>
*/
public abstract class Expand
extends MatchingTask
{
private boolean m_overwrite = true;
private ArrayList m_patternsets = new ArrayList();
private ArrayList m_filesets = new ArrayList();
private File m_dest;//req
private File m_src;

/**
* Set the destination directory. File will be unzipped into the destination
* directory.
*
* @param dest Path to the directory.
*/
public void setDest( final File dest )
{
m_dest = dest;
}

/**
* Should we overwrite files in dest, even if they are newer than the
* corresponding entries in the archive?
*
* @param overwrite The new Overwrite value
*/
public void setOverwrite( final boolean overwrite )
{
m_overwrite = overwrite;
}

/**
* Set the path to zip-file.
*
* @param src Path to zip-file.
*/
public void setSrc( final File src )
{
m_src = src;
}

/**
* Add a fileset
*
* @param set The feature to be added to the Fileset attribute
*/
public void addFileset( final FileSet set )
{
m_filesets.add( set );
}

/**
* Add a patternset
*
* @param set The feature to be added to the Patternset attribute
*/
public void addPatternset( final PatternSet set )
{
m_patternsets.add( set );
}

/**
* Do the work.
*
* @exception org.apache.myrmidon.api.TaskException Thrown in unrecoverable error.
*/
public void execute()
throws TaskException
{
validate();

if( m_src != null )
{
expandFile( m_src, m_dest );
}

final int size = m_filesets.size();
if( size > 0 )
{
for( int j = 0; j < size; j++ )
{
final FileSet fileSet = (FileSet)m_filesets.get( j );
final DirectoryScanner scanner = ScannerUtil.getDirectoryScanner( fileSet );
final File fromDir = fileSet.getDir();

final String[] files = scanner.getIncludedFiles();
for( int i = 0; i < files.length; ++i )
{
final File file = new File( fromDir, files[ i ] );
expandFile( file, m_dest );
}
}
}
}

private void validate()
throws TaskException
{
if( m_src == null && m_filesets.size() == 0 )
{
final String message = "src attribute and/or filesets must be specified";
throw new TaskException( message );
}

if( m_dest == null )
{
final String message = "Dest attribute must be specified";
throw new TaskException( message );
}

if( m_dest.exists() && !m_dest.isDirectory() )
{
final String message = "Dest must be a directory.";
throw new TaskException( message );
}

if( m_src != null && m_src.isDirectory() )
{
final String message = "Src must not be a directory." +
" Use nested filesets instead.";
throw new TaskException( message );
}
}

/*
* This method is to be overridden by extending unarchival tasks.
*/
protected void expandFile( final File src, final File dir )
throws TaskException
{
if( getContext().isInfoEnabled() )
{
final String message = "Expanding: " + src + " into " + dir;
getContext().info( message );
}

try
{
expandArchive( src, dir );
}
catch( final IOException ioe )
{
final String message = "Error while expanding " + src.getPath();
throw new TaskException( message, ioe );
}

if( getContext().isDebugEnabled() )
{
final String message = "expand complete";
getContext().debug( message );
}
}

protected abstract void expandArchive( final File src, final File dir )
throws IOException, TaskException;

protected void extractFile( final File dir,
final InputStream input,
final String entryName,
final Date date,
final boolean isDirectory )
throws IOException, TaskException
{

final int size = m_patternsets.size();
if( m_patternsets != null && size > 0 )
{
boolean included = false;
for( int i = 0; i < size; i++ )
{
PatternSet p = (PatternSet)m_patternsets.get( i );
final TaskContext context = getContext();
String[] incls = PatternUtil.getIncludePatterns( p, context );
if( incls != null )
{
for( int j = 0; j < incls.length; j++ )
{
boolean isIncl = ScannerUtil.match( incls[ j ], entryName );
if( isIncl )
{
included = true;
break;
}
}
}
final TaskContext context1 = getContext();
String[] excls = PatternUtil.getExcludePatterns( p, context1 );
if( excls != null )
{
for( int j = 0; j < excls.length; j++ )
{
boolean isExcl = ScannerUtil.match( excls[ j ], entryName );
if( isExcl )
{
included = false;
break;
}
}
}
}

if( !included )
{
//Do not process this file
return;
}
}

final File file = FileUtil.resolveFile( dir, entryName );
try
{
if( !m_overwrite && file.exists() &&
file.lastModified() >= date.getTime() )
{
final String message = "Skipping " + file + " as it is up-to-date";
getContext().debug( message );
return;
}

getContext().debug( "expanding " + entryName + " to " + file );

// create intermediary directories - sometimes zip don't add them
final File parent = file.getParentFile();
parent.mkdirs();

if( isDirectory )
{
file.mkdirs();
}
else
{
FileOutputStream fos = null;
try
{
fos = new FileOutputStream( file );
IOUtil.copy( input, fos );
}
finally
{
IOUtil.shutdownStream( fos );
}
}

file.setLastModified( date.getTime() );
}
catch( final FileNotFoundException fnfe )
{
final String message = "Unable to expand to file " + file.getPath();
getContext().warn( message );
}
}
}

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

@@ -1,395 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.Enumeration;
import java.util.zip.ZipFile;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.todo.taskdefs.manifest.Manifest;
import org.apache.tools.todo.taskdefs.manifest.ManifestException;
import org.apache.tools.todo.taskdefs.manifest.ManifestUtil;
import org.apache.tools.todo.types.FileScanner;
import org.apache.excalibur.zip.ZipOutputStream;

/**
* Creates a JAR archive.
*
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
*/
public class Jar
extends Zip
{
/**
* The index file name.
*/
private final static String INDEX_NAME = "META-INF/INDEX.LIST";

/**
* true if a manifest has been specified in the task
*/
private boolean buildFileManifest;

/**
* jar index is JDK 1.3+ only
*/
private boolean m_index;
private Manifest m_execManifest;
private Manifest m_manifest;
private File m_manifestFile;

/**
* constructor
*/
public Jar()
{
super();
m_archiveType = "jar";
m_emptyBehavior = "create";
setEncoding( "UTF8" );
}

/**
* Set whether or not to create an index list for classes to speed up
* classloading.
*
* @param flag The new Index value
*/
public void setIndex( boolean flag )
{
m_index = flag;
}

public void setManifest( File manifestFile )
throws TaskException
{
if( !manifestFile.exists() )
{
final String message = "Manifest file: " + manifestFile + " does not exist.";
throw new TaskException( message );
}

this.m_manifestFile = manifestFile;

Reader r = null;
try
{
r = new FileReader( manifestFile );
Manifest newManifest = ManifestUtil.buildManifest( r );
if( m_manifest == null )
{
m_manifest = ManifestUtil.getDefaultManifest();
}
m_manifest.merge( newManifest );
}
catch( ManifestException e )
{
final String message = "Manifest " + manifestFile + " is invalid: " + e.getMessage();
getContext().error( message );
throw new TaskException( message, e );
}
catch( IOException e )
{
final String message = "Unable to read manifest file: " + manifestFile;
throw new TaskException( message, e );
}
finally
{
if( r != null )
{
try
{
r.close();
}
catch( IOException e )
{
// do nothing
}
}
}
}

public void setWhenempty( WhenEmpty we )
{
final String message = "JARs are never empty, they contain at least a manifest file";
getContext().warn( message );
}

public void addManifest( Manifest newManifest )
throws ManifestException, TaskException
{
if( m_manifest == null )
{
m_manifest = ManifestUtil.getDefaultManifest();
}
m_manifest.merge( newManifest );
buildFileManifest = true;
}

public void addMetainf( ZipFileSet fs )
{
// We just set the prefix for this fileset, and pass it up.
fs.setPrefix( "META-INF/" );
super.addFileset( fs );
}

/**
* Check whether the archive is up-to-date;
*
* @param scanners list of prepared scanners containing files to archive
* @param zipFile intended archive file (may or may not exist)
* @return true if nothing need be done (may have done something already);
* false if archive creation should proceed
* @exception org.apache.myrmidon.api.TaskException if it likes
*/
protected boolean isUpToDate( FileScanner[] scanners, File zipFile )
throws TaskException
{
// need to handle manifest as a special check
if( buildFileManifest || m_manifestFile == null )
{
java.util.zip.ZipFile theZipFile = null;
try
{
theZipFile = new ZipFile( zipFile );
java.util.zip.ZipEntry entry = theZipFile.getEntry( "META-INF/MANIFEST.MF" );
if( entry == null )
{
getContext().debug( "Updating jar since the current jar has no manifest" );
return false;
}
Manifest currentManifest = ManifestUtil.buildManifest( new InputStreamReader( theZipFile.getInputStream( entry ) ) );
if( m_manifest == null )
{
m_manifest = ManifestUtil.getDefaultManifest();
}
if( !currentManifest.equals( m_manifest ) )
{
getContext().debug( "Updating jar since jar manifest has changed" );
return false;
}
}
catch( Exception e )
{
// any problems and we will rebuild
getContext().debug( "Updating jar since cannot read current jar manifest: " + e.getClass().getName() + e.getMessage() );
return false;
}
finally
{
if( theZipFile != null )
{
try
{
theZipFile.close();
}
catch( IOException e )
{
//ignore
}
}
}
}
else if( m_manifestFile.lastModified() > zipFile.lastModified() )
{
return false;
}
return super.isUpToDate( scanners, zipFile );
}

protected boolean createEmptyZip( File zipFile )
{
// Jar files always contain a manifest and can never be empty
return false;
}

protected void finalizeZipOutputStream( ZipOutputStream zOut )
throws IOException, TaskException
{
if( m_index )
{
createIndexList( zOut );
}
}

protected void initZipOutputStream( ZipOutputStream zOut )
throws IOException, TaskException
{
try
{
m_execManifest = ManifestUtil.getDefaultManifest();

if( m_manifest != null )
{
m_execManifest.merge( m_manifest );
}
/*
for( Iterator e = m_execManifest.getWarnings(); e.hasNext(); )
{
getLogger().warn( "Manifest warning: " + (String)e.next() );
}
*/

zipDir( null, zOut, "META-INF/" );
// time to write the manifest
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter writer = new PrintWriter( baos );
Manifest manifest = m_execManifest;
ManifestUtil.write( manifest, writer );
writer.flush();

ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
super.zipFile( bais, zOut, "META-INF/MANIFEST.MF", System.currentTimeMillis() );
super.initZipOutputStream( zOut );
}
catch( ManifestException e )
{
getContext().error( "Manifest is invalid: " + e.getMessage() );
throw new TaskException( "Invalid Manifest", e );
}
}

protected void zipFile( File file, ZipOutputStream zOut, String vPath )
throws IOException, TaskException
{
// If the file being added is META-INF/MANIFEST.MF, we warn if it's not the
// one specified in the "manifest" attribute - or if it's being added twice,
// meaning the same file is specified by the "manifeset" attribute and in
// a <fileset> element.
if( vPath.equalsIgnoreCase( "META-INF/MANIFEST.MF" ) )
{
final String message = "Warning: selected " + m_archiveType +
" files include a META-INF/MANIFEST.MF which will be ignored " +
"(please use manifest attribute to " + m_archiveType + " task)";
getContext().warn( message );
}
else
{
super.zipFile( file, zOut, vPath );
}

}

protected void zipFile( InputStream is, ZipOutputStream zOut, String vPath, long lastModified )
throws IOException, TaskException
{
// If the file being added is META-INF/MANIFEST.MF, we merge it with the
// current manifest
if( vPath.equalsIgnoreCase( "META-INF/MANIFEST.MF" ) )
{
try
{
zipManifestEntry( is );
}
catch( IOException e )
{
throw new TaskException( "Unable to read manifest file: ", e );
}
}
else
{
super.zipFile( is, zOut, vPath, lastModified );
}
}

/**
* Create the index list to speed up classloading. This is a JDK 1.3+
* specific feature and is enabled by default. {@link
* http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#JAR%20Index}
*
* @param zOut the zip stream representing the jar being built.
* @throws java.io.IOException thrown if there is an error while creating the index
* and adding it to the zip stream.
*/
private void createIndexList( ZipOutputStream zOut )
throws IOException, TaskException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// encoding must be UTF8 as specified in the specs.
PrintWriter writer = new PrintWriter( new OutputStreamWriter( baos, "UTF8" ) );

// version-info blankline
writer.println( "JarIndex-Version: 1.0" );
writer.println();

// header newline
writer.println( m_file.getName() );

// JarIndex is sorting the directories by ascending order.
// it's painful to do in JDK 1.1 and it has no value but cosmetic
// since it will be read into a hashtable by the classloader.
Enumeration enum = m_addedDirs.keys();
while( enum.hasMoreElements() )
{
String dir = (String)enum.nextElement();

// try to be smart, not to be fooled by a weird directory name
// @fixme do we need to check for directories starting by ./ ?
dir = dir.replace( '\\', '/' );
int pos = dir.lastIndexOf( '/' );
if( pos != -1 )
{
dir = dir.substring( 0, pos );
}

// looks like nothing from META-INF should be added
// and the check is not case insensitive.
// see sun.misc.JarIndex
if( dir.startsWith( "META-INF" ) )
{
continue;
}
// name newline
writer.println( dir );
}

writer.flush();
ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
super.zipFile( bais, zOut, INDEX_NAME, System.currentTimeMillis() );
}

/**
* Handle situation when we encounter a manifest file If we haven't been
* given one, we use this one. If we have, we merge the manifest in,
* provided it is a new file and not the old one from the JAR we are
* updating
*
* @param is Description of Parameter
* @exception java.io.IOException Description of Exception
*/
private void zipManifestEntry( InputStream is )
throws IOException, TaskException
{
try
{
if( m_execManifest == null )
{
m_execManifest = ManifestUtil.buildManifest( new InputStreamReader( is ) );
}
else if( isAddingNewFiles() )
{
final Manifest other = ManifestUtil.buildManifest( new InputStreamReader( is ) );
m_execManifest.merge( other );
}
}
catch( ManifestException e )
{
getContext().error( "Manifest is invalid: " + e.getMessage() );
throw new TaskException( "Invalid Manifest", e );
}
}
}

+ 0
- 306
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Tar.java View File

@@ -1,306 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.avalon.excalibur.io.IOUtil;
import org.apache.excalibur.tar.TarEntry;
import org.apache.excalibur.tar.TarOutputStream;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.todo.taskdefs.MatchingTask;
import org.apache.tools.todo.types.ScannerUtil;
import org.apache.tools.todo.types.SourceFileScanner;
import org.apache.tools.todo.util.mappers.MergingMapper;

/**
* Creates a TAR archive.
*
* @author Stefano Mazzocchi <a href="mailto:stefano@apache.org">
* stefano@apache.org</a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
*/
public class Tar
extends MatchingTask
{
private TarLongFileMode longFileMode = createMode();

private TarLongFileMode createMode()
{
try
{
return new TarLongFileMode();
}
catch( TaskException e )
{
throw new IllegalStateException( e.getMessage() );
}
}

ArrayList filesets = new ArrayList();
ArrayList fileSetFiles = new ArrayList();

/**
* Indicates whether the user has been warned about long files already.
*/
private boolean longWarningGiven = false;
File baseDir;

File tarFile;

/**
* This is the base directory to look in for things to tar.
*
* @param baseDir The new Basedir value
*/
public void setBasedir( File baseDir )
{
this.baseDir = baseDir;
}

/**
* Set how to handle long files. Allowable values are truncate - paths are
* truncated to the maximum length fail - paths greater than the maximim
* cause a build exception warn - paths greater than the maximum cause a
* warning and GNU is used gnu - GNU extensions are used for any paths
* greater than the maximum. omit - paths greater than the maximum are
* omitted from the archive
*
* @param mode The new Longfile value
*/
public void setLongfile( TarLongFileMode mode )
{
this.longFileMode = mode;
}

/**
* This is the name/location of where to create the tar file.
*
* @param tarFile The new Tarfile value
*/
public void setTarfile( File tarFile )
{
this.tarFile = tarFile;
}

public TarFileSet createTarFileSet()
{
TarFileSet fileset = new TarFileSet();
filesets.add( fileset );
return fileset;
}

public void execute()
throws TaskException
{
if( tarFile == null )
{
throw new TaskException( "tarfile attribute must be set!" );
}

if( tarFile.exists() && tarFile.isDirectory() )
{
throw new TaskException( "tarfile is a directory!" );
}

if( tarFile.exists() && !tarFile.canWrite() )
{
throw new TaskException( "Can not write to the specified tarfile!" );
}

if( baseDir != null )
{
if( !baseDir.exists() )
{
throw new TaskException( "basedir does not exist!" );
}

// add the main fileset to the list of filesets to process.
final TarFileSet mainFileSet = new TarFileSet( /*fileset*/ );
mainFileSet.setDir( baseDir );
filesets.add( mainFileSet );
}

if( filesets.size() == 0 )
{
throw new TaskException( "You must supply either a basdir attribute or some nested filesets." );
}

// check if tr is out of date with respect to each
// fileset
boolean upToDate = true;
for( Iterator e = filesets.iterator(); e.hasNext(); )
{
TarFileSet fs = (TarFileSet)e.next();
String[] files = ScannerUtil.getFiles( fs );

if( !archiveIsUpToDate( files ) )
{
upToDate = false;
}

for( int i = 0; i < files.length; ++i )
{
if( tarFile.equals( new File( fs.getDir(), files[ i ] ) ) )
{
throw new TaskException( "A tar file cannot include itself" );
}
}
}

if( upToDate )
{
getContext().info( "Nothing to do: " + tarFile.getAbsolutePath() + " is up to date." );
return;
}

getContext().info( "Building tar: " + tarFile.getAbsolutePath() );

TarOutputStream tOut = null;
try
{
tOut = new TarOutputStream( new FileOutputStream( tarFile ) );
if( longFileMode.isTruncateMode() )
{
tOut.setLongFileMode( TarOutputStream.LONGFILE_TRUNCATE );
}
else if( longFileMode.isFailMode() ||
longFileMode.isOmitMode() )
{
tOut.setLongFileMode( TarOutputStream.LONGFILE_ERROR );
}
else
{
// warn or GNU
tOut.setLongFileMode( TarOutputStream.LONGFILE_GNU );
}

longWarningGiven = false;
for( Iterator e = filesets.iterator(); e.hasNext(); )
{
TarFileSet fs = (TarFileSet)e.next();
String[] files = ScannerUtil.getFiles( fs );
for( int i = 0; i < files.length; i++ )
{
File f = new File( fs.getDir(), files[ i ] );
String name = files[ i ].replace( File.separatorChar, '/' );
tarFile( f, tOut, name, fs );
}
}
}
catch( IOException ioe )
{
String msg = "Problem creating TAR: " + ioe.getMessage();
throw new TaskException( msg, ioe );
}
finally
{
if( tOut != null )
{
try
{
// close up
tOut.close();
}
catch( IOException e )
{
}
}
}
}

private boolean archiveIsUpToDate( final String[] files )
throws TaskException
{
final SourceFileScanner scanner = new SourceFileScanner();
final MergingMapper mapper = new MergingMapper();
mapper.setTo( tarFile.getAbsolutePath() );
return scanner.restrict( files, baseDir, null, mapper, getContext() ).length == 0;
}

private void tarFile( final File file,
final TarOutputStream output,
final String path,
final TarFileSet tarFileSet )
throws IOException, TaskException
{
String storedPath = path;
// don't add "" to the archive
if( storedPath.length() <= 0 )
{
return;
}

if( file.isDirectory() && !storedPath.endsWith( "/" ) )
{
storedPath += "/";
}

if( storedPath.length() >= TarEntry.NAMELEN )
{
if( longFileMode.isOmitMode() )
{
final String message = "Omitting: " + storedPath;
getContext().info( message );
return;
}
else if( longFileMode.isWarnMode() )
{
final String message = "Entry: " + storedPath + " longer than " +
TarEntry.NAMELEN + " characters.";
getContext().warn( message );
if( !longWarningGiven )
{
final String message2 = "Resulting tar file can only be processed successfully"
+ " by GNU compatible tar commands";
getContext().warn( message2 );
longWarningGiven = true;
}
}
else if( longFileMode.isFailMode() )
{
final String message = "Entry: " + storedPath + " longer than " +
TarEntry.NAMELEN + "characters.";
throw new TaskException( message );
}
}

FileInputStream input = null;
try
{
final TarEntry entry = new TarEntry( storedPath );
entry.setModTime( file.lastModified() );
if( !file.isDirectory() )
{
entry.setSize( file.length() );
entry.setMode( tarFileSet.getMode() );
}
entry.setUserName( tarFileSet.getUserName() );
entry.setGroupName( tarFileSet.getGroup() );

output.putNextEntry( entry );

if( !file.isDirectory() )
{
input = new FileInputStream( file );
IOUtil.copy( input, output );
}

output.closeEntry();
}
finally
{
IOUtil.shutdownStream( input );
}
}
}

+ 0
- 48
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/TarFileSet.java View File

@@ -1,48 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import org.apache.myrmidon.framework.FileSet;

public class TarFileSet
extends FileSet
{
private int m_mode = 0100644;
private String m_userName = "";
private String m_groupName = "";

public void setGroup( final String groupName )
{
m_groupName = groupName;
}

public void setMode( final String octalString )
{
m_mode = 0100000 | Integer.parseInt( octalString, 8 );
}

public void setUserName( final String userName )
{
m_userName = userName;
}

protected String getGroup()
{
return m_groupName;
}

protected int getMode()
{
return m_mode;
}

protected String getUserName()
{
return m_userName;
}
}

+ 0
- 66
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/TarLongFileMode.java View File

@@ -1,66 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import org.apache.myrmidon.api.TaskException;
import org.apache.tools.todo.types.EnumeratedAttribute;

/**
* Valid Modes for LongFile attribute to Tar Task
*
* @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
*/
public class TarLongFileMode
extends EnumeratedAttribute
{
// permissable values for longfile attribute
public final static String WARN = "warn";
public final static String FAIL = "fail";
public final static String TRUNCATE = "truncate";
public final static String GNU = "gnu";
public final static String OMIT = "omit";

private final String[] validModes = {WARN, FAIL, TRUNCATE, GNU, OMIT};

public TarLongFileMode()
throws TaskException
{
super();
setValue( WARN );
}

public String[] getValues()
{
return validModes;
}

public boolean isFailMode()
{
return FAIL.equalsIgnoreCase( getValue() );
}

public boolean isGnuMode()
{
return GNU.equalsIgnoreCase( getValue() );
}

public boolean isOmitMode()
{
return OMIT.equalsIgnoreCase( getValue() );
}

public boolean isTruncateMode()
{
return TRUNCATE.equalsIgnoreCase( getValue() );
}

public boolean isWarnMode()
{
return WARN.equalsIgnoreCase( getValue() );
}
}

+ 0
- 53
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Untar.java View File

@@ -1,53 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.apache.avalon.excalibur.io.IOUtil;
import org.apache.excalibur.tar.TarEntry;
import org.apache.excalibur.tar.TarInputStream;
import org.apache.myrmidon.api.TaskException;

/**
* Untar a file. Heavily based on the Expand task.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a>
*/
public class Untar
extends Expand
{
protected void expandArchive( final File src, final File dir )
throws IOException, TaskException
{
TarInputStream input = null;
FileInputStream fileInput = null;
try
{
fileInput = new FileInputStream( src );
input = new TarInputStream( fileInput );

TarEntry entry = null;
while( ( entry = input.getNextEntry() ) != null )
{
extractFile( dir,
input,
entry.getName(),
entry.getModTime(),
entry.isDirectory() );
}
}
finally
{
IOUtil.shutdownStream( fileInput );
IOUtil.shutdownStream( input );
}
}
}

+ 0
- 54
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/Unzip.java View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.avalon.excalibur.io.IOUtil;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.todo.taskdefs.archive.Expand;

/**
* Untar a file. Heavily based on the Expand task.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a>
*/
public class Unzip
extends Expand
{
protected void expandArchive( final File src, final File dir )
throws IOException, TaskException
{
ZipInputStream zis = null;
try
{
// code from WarExpand
zis = new ZipInputStream( new FileInputStream( src ) );
ZipEntry ze = null;

while( ( ze = zis.getNextEntry() ) != null )
{
final Date date = new Date( ze.getTime() );
extractFile( dir,
zis,
ze.getName(),
date,
ze.isDirectory() );
}
}
finally
{
IOUtil.shutdownStream( zis );
}
}
}

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

@@ -1,109 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import java.io.File;
import java.io.IOException;
import org.apache.myrmidon.api.TaskException;
import org.apache.excalibur.zip.ZipOutputStream;

/**
* Creates a WAR archive.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class War
extends Jar
{
private File m_webxml;
private boolean m_descriptorAdded;

public War()
{
super();
m_archiveType = "war";
m_emptyBehavior = "create";
}

public void setWebxml( final File descr )
throws TaskException
{
m_webxml = descr;
if( !m_webxml.exists() )
{
final String message = "Deployment descriptor: " +
m_webxml + " does not exist.";
throw new TaskException( message );
}

addFileAs( descr, "WEB-INF/web.xml" );
}

public void addClasses( final ZipFileSet fs )
{
// We just set the prefix for this fileset, and pass it up.
fs.setPrefix( "WEB-INF/classes/" );
super.addFileset( fs );
}

public void addLib( final ZipFileSet fs )
{
// We just set the prefix for this fileset, and pass it up.
fs.setPrefix( "WEB-INF/lib/" );
super.addFileset( fs );
}

public void addWebinf( final ZipFileSet fs )
{
// We just set the prefix for this fileset, and pass it up.
fs.setPrefix( "WEB-INF/" );
super.addFileset( fs );
}

protected void initZipOutputStream( final ZipOutputStream zOut )
throws IOException, TaskException
{
// If no webxml file is specified, it's an error.
if( m_webxml == null && !isInUpdateMode() )
{
throw new TaskException( "webxml attribute is required" );
}

super.initZipOutputStream( zOut );
}

protected void zipFile( final File file,
final ZipOutputStream zOut,
final String vPath )
throws IOException, TaskException
{
// If the file being added is WEB-INF/web.xml, we warn if it's not the
// one specified in the "webxml" attribute - or if it's being added twice,
// meaning the same file is specified by the "webxml" attribute and in
// a <fileset> element.
if( vPath.equalsIgnoreCase( "WEB-INF/web.xml" ) )
{
if( m_webxml == null || !m_webxml.equals( file ) || m_descriptorAdded )
{
final String message = "Warning: selected " + m_archiveType +
" files include a WEB-INF/web.xml which will be ignored " +
"(please use webxml attribute to " + m_archiveType + " task)";
getContext().warn( message );
}
else
{
super.zipFile( file, zOut, vPath );
m_descriptorAdded = true;
}
}
else
{
super.zipFile( file, zOut, vPath );
}
}
}

+ 0
- 22
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/WhenEmpty.java View File

@@ -1,22 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import org.apache.tools.todo.types.EnumeratedAttribute;

/**
* Possible behaviors when there are no matching files for the task.
*/
public class WhenEmpty
extends EnumeratedAttribute
{
public String[] getValues()
{
return new String[]{"fail", "skip", "create"};
}
}

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

@@ -1,895 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Stack;
import java.util.zip.CRC32;
import java.util.zip.ZipInputStream;
import org.apache.avalon.excalibur.io.IOUtil;
import org.apache.excalibur.zip.ZipEntry;
import org.apache.excalibur.zip.ZipOutputStream;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.FileSet;
import org.apache.tools.todo.taskdefs.MatchingTask;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.tools.todo.types.FileScanner;
import org.apache.tools.todo.types.ScannerUtil;
import org.apache.tools.todo.types.SourceFileScanner;
import org.apache.tools.todo.util.mappers.MergingMapper;

/**
* Create a ZIP archive.
*
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Jon S. Stevens <a href="mailto:jon@clearink.com">jon@clearink.com</a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class Zip
extends MatchingTask
{
// For directories:
private final static long EMPTY_CRC = new CRC32().getValue();
private boolean m_compress = true;
private boolean m_update;
private boolean m_filesonly;
protected String m_archiveType = "zip";
protected String m_emptyBehavior = "skip";
private ArrayList m_filesets = new ArrayList();
protected Hashtable m_addedDirs = new Hashtable();
private ArrayList m_addedFiles = new ArrayList();
protected File m_file;

/**
* true when we are adding new files into the Zip file, as opposed to adding
* back the unchanged files
*/
private boolean m_addingNewFiles;
private File m_baseDir;

/**
* Encoding to use for filenames, defaults to the platform's default
* encoding.
*/
private String m_encoding;

private static String[][] grabFileNames( final FileScanner[] scanners )
throws TaskException
{
String[][] result = new String[ scanners.length ][];
for( int i = 0; i < scanners.length; i++ )
{
String[] files = scanners[ i ].getIncludedFiles();
String[] dirs = scanners[ i ].getIncludedDirectories();
result[ i ] = new String[ files.length + dirs.length ];
System.arraycopy( files, 0, result[ i ], 0, files.length );
System.arraycopy( dirs, 0, result[ i ], files.length, dirs.length );
}
return result;
}

private static File[] grabFiles( final FileScanner[] scanners,
final String[][] filenames )
{
final ArrayList files = new ArrayList();
for( int i = 0; i < filenames.length; i++ )
{
final File baseDir = scanners[ i ].getBasedir();
for( int j = 0; j < filenames[ i ].length; j++ )
{
files.add( new File( baseDir, filenames[ i ][ j ] ) );
}
}
final File[] toret = new File[ files.size() ];
return (File[])files.toArray( toret );
}

/**
* This is the base directory to look in for things to zip.
*
* @param baseDir The new Basedir value
*/
public void setBasedir( final File baseDir )
{
m_baseDir = baseDir;
}

/**
* Sets whether we want to compress the files or only store them.
*
* @param compress The new Compress value
*/
public void setCompress( final boolean compress )
{
m_compress = compress;
}

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

/**
* This is the name/location of where to create the .zip file.
*
* @param file The new File value
*/
public void setFile( final File file )
{
m_file = file;
}

/**
* Emulate Sun's jar utility by not adding parent dirs
*/
public void setFilesonly( final boolean filesonly )
{
m_filesonly = filesonly;
}

/**
* Sets whether we want to update the file (if it exists) or create a new
* one.
*/
public void setUpdate( final boolean update )
{
m_update = update;
}

/**
* Sets behavior of the task when no files match. Possible values are:
* <code>fail</code> (throw an exception and halt the build); <code>skip</code>
* (do not create any archive, but issue a warning); <code>create</code>
* (make an archive with no entries). Default for zip tasks is <code>skip</code>
* ; for jar tasks, <code>create</code>.
*
* @param we The new Whenempty value
*/
public void setWhenempty( final WhenEmpty we )
{
m_emptyBehavior = we.getValue();
}

/**
* Are we updating an existing archive?
*
* @return The InUpdateMode value
*/
protected final boolean isInUpdateMode()
{
return m_update;
}

/**
* Adds a set of files (nested fileset attribute).
*/
public void addFileset( final FileSet set )
{
m_filesets.add( set );
}

/**
* Adds a set of files (nested zipfileset attribute) that can be read from
* an archive and be given a prefix/fullpath.
*
* @param set The feature to be added to the Zipfileset attribute
*/
public void addZipfileset( final ZipFileSet set )
{
m_filesets.add( set );
}

public void execute()
throws TaskException
{
if( m_baseDir == null && m_filesets.size() == 0 &&
"zip".equals( m_archiveType ) )
{
final String message = "basedir attribute must be set, or at least " +
"one fileset must be given!";
throw new TaskException( message );
}

if( m_file == null )
{
final String message = "You must specify the " +
m_archiveType + " file to create!";
throw new TaskException( message );
}

// Renamed version of original file, if it exists
File renamedFile = null;
// Whether or not an actual update is required -
// we don't need to update if the original file doesn't exist

m_addingNewFiles = true;
m_update = m_update && m_file.exists();
if( m_update )
{
try
{
renamedFile = File.createTempFile( "zip", ".tmp",
m_file.getParentFile() );
}
catch( final IOException ioe )
{
throw new TaskException( ioe.toString(), ioe );
}

try
{
if( !m_file.renameTo( renamedFile ) )
{
throw new TaskException( "Unable to rename old file to temporary file" );
}
}
catch( SecurityException e )
{
throw new TaskException( "Not allowed to rename old file to temporary file" );
}
}

// Create the scanners to pass to isUpToDate().
ArrayList dss = new ArrayList();
if( m_baseDir != null )
{
dss.add( getDirectoryScanner( m_baseDir ) );
}
final int size = m_filesets.size();
for( int i = 0; i < size; i++ )
{
final FileSet fileSet = (FileSet)m_filesets.get( i );
final DirectoryScanner scanner = getScanner( fileSet );
dss.add( scanner );
}
int dssSize = dss.size();
FileScanner[] scanners = new FileScanner[ dssSize ];
scanners = (FileScanner[])dss.toArray( scanners );

// quick exit if the target is up to date
// can also handle empty archives
if( isUpToDate( scanners, m_file ) )
{
return;
}

String action = m_update ? "Updating " : "Building ";

getContext().info( action + m_archiveType + ": " + m_file.getAbsolutePath() );

boolean success = false;
try
{
ZipOutputStream zOut =
new ZipOutputStream( new FileOutputStream( m_file ) );
zOut.setEncoding( m_encoding );
try
{
if( m_compress )
{
zOut.setMethod( ZipOutputStream.DEFLATED );
}
else
{
zOut.setMethod( ZipOutputStream.STORED );
}
initZipOutputStream( zOut );

// Add the implicit fileset to the archive.
if( m_baseDir != null )
{
addFiles( getDirectoryScanner( m_baseDir ), zOut, "", "" );
}
// Add the explicit filesets to the archive.
addFiles( m_filesets, zOut );
if( m_update )
{
m_addingNewFiles = false;
ZipFileSet oldFiles = new ZipFileSet();
oldFiles.setSrc( renamedFile );

StringBuffer exclusionPattern = new StringBuffer();
final int addedFilesCount = m_addedFiles.size();
for( int i = 0; i < addedFilesCount; i++ )
{
if( i != 0 )
{
exclusionPattern.append( "," );
}
exclusionPattern.append( (String)m_addedFiles.get( i ) );
}
oldFiles.setExcludes( exclusionPattern.toString() );
ArrayList tmp = new ArrayList();
tmp.add( oldFiles );
addFiles( tmp, zOut );
}
finalizeZipOutputStream( zOut );
success = true;
}
finally
{
// Close the output stream.
try
{
if( zOut != null )
{
zOut.close();
}
}
catch( IOException ex )
{
// If we're in this finally clause because of an exception, we don't
// really care if there's an exception when closing the stream. E.g. if it
// throws "ZIP file must have at least one entry", because an exception happened
// before we added any files, then we must swallow this exception. Otherwise,
// the error that's reported will be the close() error, which is not the real
// cause of the problem.
if( success )
{
throw ex;
}
}
}
}
catch( IOException ioe )
{
String msg = "Problem creating " + m_archiveType + ": " + ioe.getMessage();

// delete a bogus ZIP file
if( !m_file.delete() )
{
msg += " (and the archive is probably corrupt but I could not delete it)";
}

if( m_update )
{
if( !renamedFile.renameTo( m_file ) )
{
msg += " (and I couldn't rename the temporary file " +
renamedFile.getName() + " back)";
}
}

throw new TaskException( msg, ioe );
}

// If we've been successful on an update, delete the temporary file
if( success && m_update )
{
if( !renamedFile.delete() )
{
final String message = "Warning: unable to delete temporary file " +
renamedFile.getName();
getContext().warn( message );
}
}
}

private DirectoryScanner getScanner( final FileSet fileSet )
throws TaskException
{
if( fileSet instanceof ZipFileSet )
{
final ZipFileSet zipFileSet = (ZipFileSet)fileSet;
return ScannerUtil.getZipScanner( zipFileSet );
}
else
{
return ScannerUtil.getDirectoryScanner( fileSet );
}
}

protected void addFileAs( final File file, final String name )
throws TaskException
{
// Create a ZipFileSet for this file, and pass it up.
final ZipFileSet fs = new ZipFileSet();
fs.setDir( file.getParentFile() );
fs.setIncludes( file.getName() );
fs.setFullpath( name );
addFileset( fs );
}

/**
* Indicates if the task is adding new files into the archive as opposed to
* copying back unchanged files from the backup copy
*
* @return The AddingNewFiles value
*/
protected final boolean isAddingNewFiles()
{
return m_addingNewFiles;
}

/**
* Check whether the archive is up-to-date; and handle behavior for empty
* archives.
*
* @param scanners list of prepared scanners containing files to archive
* @param zipFile intended archive file (may or may not exist)
* @return true if nothing need be done (may have done something already);
* false if archive creation should proceed
* @exception org.apache.myrmidon.api.TaskException if it likes
*/
protected boolean isUpToDate( FileScanner[] scanners, File zipFile )
throws TaskException
{
String[][] fileNames = grabFileNames( scanners );
File[] files = grabFiles( scanners, fileNames );
if( files.length == 0 )
{
if( m_emptyBehavior.equals( "skip" ) )
{
final String message = "Warning: skipping " + m_archiveType + " archive " + zipFile +
" because no files were included.";
getContext().warn( message );
return true;
}
else if( m_emptyBehavior.equals( "fail" ) )
{
throw new TaskException( "Cannot create " + m_archiveType + " archive " + zipFile +
": no files were included." );
}
else
{
// Create.
return createEmptyZip( zipFile );
}
}
else
{
for( int i = 0; i < files.length; ++i )
{
if( files[ i ].equals( zipFile ) )
{
throw new TaskException( "A zip file cannot include itself" );
}
}

if( !zipFile.exists() )
{
return false;
}

final SourceFileScanner scanner = new SourceFileScanner();
MergingMapper mm = new MergingMapper();
mm.setTo( zipFile.getAbsolutePath() );
for( int i = 0; i < scanners.length; i++ )
{
if( scanner.restrict( fileNames[ i ], scanners[ i ].getBasedir(), null,
mm, getContext() ).length > 0 )
{
return false;
}
}
return true;
}
}

/**
* Add all files of the given FileScanner to the ZipOutputStream prependig
* the given prefix to each filename. <p>
*
* Ensure parent directories have been added as well.
*
* @param scanner The feature to be added to the Files attribute
* @param zOut The feature to be added to the Files attribute
* @param prefix The feature to be added to the Files attribute
* @param fullpath The feature to be added to the Files attribute
* @exception IOException Description of Exception
*/
protected void addFiles( FileScanner scanner, ZipOutputStream zOut,
String prefix, String fullpath )
throws IOException, TaskException
{
if( prefix.length() > 0 && fullpath.length() > 0 )
{
throw new TaskException( "Both prefix and fullpath attributes may not be set on the same fileset." );
}

File thisBaseDir = scanner.getBasedir();

// directories that matched include patterns
String[] dirs = scanner.getIncludedDirectories();
if( dirs.length > 0 && fullpath.length() > 0 )
{
throw new TaskException( "fullpath attribute may only be specified for filesets that specify a single file." );
}
for( int i = 0; i < dirs.length; i++ )
{
final String dir = dirs[ i ];
if( "".equals( dir ) )
{
continue;
}
final String name = getName( dir );
addParentDirs( thisBaseDir, name, zOut, prefix );
}

// files that matched include patterns
String[] files = scanner.getIncludedFiles();
if( files.length > 1 && fullpath.length() > 0 )
{
throw new TaskException( "fullpath attribute may only be specified for filesets that specify a single file." );
}
for( int i = 0; i < files.length; i++ )
{
File f = new File( thisBaseDir, files[ i ] );
if( fullpath.length() > 0 )
{
// Add this file at the specified location.
addParentDirs( null, fullpath, zOut, "" );
zipFile( f, zOut, fullpath );
}
else
{
// Add this file with the specified prefix.
String name = files[ i ].replace( File.separatorChar, '/' );
addParentDirs( thisBaseDir, name, zOut, prefix );
zipFile( f, zOut, prefix + name );
}
}
}

private String getName( final String dir )
{
String name = dir.replace( File.separatorChar, '/' );
if( !name.endsWith( "/" ) )
{
name += "/";
}
return name;
}

/**
* Iterate over the given ArrayList of (zip)filesets and add all files to the
* ZipOutputStream using the given prefix or fullpath.
*
* @param filesets The feature to be added to the Files attribute
* @param zOut The feature to be added to the Files attribute
* @exception java.io.IOException Description of Exception
*/
protected void addFiles( ArrayList filesets, ZipOutputStream zOut )
throws IOException, TaskException
{
// Add each fileset in the ArrayList.
final int size = filesets.size();
for( int i = 0; i < size; i++ )
{
FileSet fs = (FileSet)filesets.get( i );
DirectoryScanner ds = getScanner( fs );

String prefix = "";
String fullpath = "";
if( fs instanceof ZipFileSet )
{
ZipFileSet zfs = (ZipFileSet)fs;
prefix = getPrefix( zfs.getPrefix() );
fullpath = zfs.getFullpath();
}


// Need to manually add either fullpath's parent directory, or
// the prefix directory, to the archive.
if( prefix.length() > 0 )
{
addParentDirs( null, prefix, zOut, "" );
zipDir( null, zOut, prefix );
}
else if( fullpath.length() > 0 )
{
addParentDirs( null, fullpath, zOut, "" );
}

if( fs instanceof ZipFileSet
&& ( (ZipFileSet)fs ).getSrc() != null )
{
addZipEntries( (ZipFileSet)fs, ds, zOut, prefix, fullpath );
}
else
{
// Add the fileset.
addFiles( ds, zOut, prefix, fullpath );
}
}
}

private String getPrefix( final String prefix )
{
String result = prefix;
if( result.length() > 0
&& !result.endsWith( "/" )
&& !result.endsWith( "\\" ) )
{
result += "/";
}
return result;
}

/**
* Ensure all parent dirs of a given entry have been added.
*
* @param baseDir The feature to be added to the ParentDirs attribute
* @param entry The feature to be added to the ParentDirs attribute
* @param zOut The feature to be added to the ParentDirs attribute
* @param prefix The feature to be added to the ParentDirs attribute
* @exception java.io.IOException Description of Exception
*/
protected void addParentDirs( File baseDir, String entry,
ZipOutputStream zOut, String prefix )
throws IOException
{
if( !m_filesonly )
{
Stack directories = new Stack();
int slashPos = entry.length();

while( ( slashPos = entry.lastIndexOf( '/', slashPos - 1 ) ) != -1 )
{
String dir = entry.substring( 0, slashPos + 1 );
if( m_addedDirs.get( prefix + dir ) != null )
{
break;
}
directories.push( dir );
}

while( !directories.isEmpty() )
{
String dir = (String)directories.pop();
File f = null;
if( baseDir != null )
{
f = new File( baseDir, dir );
}
else
{
f = new File( dir );
}
zipDir( f, zOut, prefix + dir );
}
}
}

protected void addZipEntries( ZipFileSet fs, DirectoryScanner ds,
ZipOutputStream zOut, String prefix, String fullpath )
throws IOException, TaskException
{
if( prefix.length() > 0 && fullpath.length() > 0 )
{
throw new TaskException( "Both prefix and fullpath attributes may not be set on the same fileset." );
}

ZipScanner zipScanner = (ZipScanner)ds;
File zipSrc = fs.getSrc();

ZipEntry entry;
java.util.zip.ZipEntry origEntry;
ZipInputStream in = null;
try
{
in = new ZipInputStream( new FileInputStream( zipSrc ) );

while( ( origEntry = in.getNextEntry() ) != null )
{
entry = new ZipEntry( origEntry );
String vPath = entry.getName();
if( zipScanner.match( vPath ) )
{
if( fullpath.length() > 0 )
{
addParentDirs( null, fullpath, zOut, "" );
zipFile( in, zOut, fullpath, entry.getTime() );
}
else
{
addParentDirs( null, vPath, zOut, prefix );
if( !entry.isDirectory() )
{
zipFile( in, zOut, prefix + vPath, entry.getTime() );
}
}
}
}
}
finally
{
if( in != null )
{
in.close();
}
}
}

/**
* Create an empty zip file
*
* @param zipFile Description of Parameter
* @return true if the file is then considered up to date.
*/
protected boolean createEmptyZip( File zipFile )
throws TaskException
{
// In this case using java.util.zip will not work
// because it does not permit a zero-entry archive.
// Must create it manually.
getContext().info( "Note: creating empty " + m_archiveType + " archive " + zipFile );
try
{
OutputStream os = new FileOutputStream( zipFile );
try
{
// Cf. PKZIP specification.
byte[] empty = new byte[ 22 ];
empty[ 0 ] = 80;// P
empty[ 1 ] = 75;// K
empty[ 2 ] = 5;
empty[ 3 ] = 6;
// remainder zeros
os.write( empty );
}
finally
{
os.close();
}
}
catch( IOException ioe )
{
throw new TaskException( "Could not create empty ZIP archive", ioe );
}
return true;
}

protected void finalizeZipOutputStream( ZipOutputStream zOut )
throws IOException, TaskException
{
}

protected void initZipOutputStream( ZipOutputStream zOut )
throws IOException, TaskException
{
}

protected void zipDir( File dir, ZipOutputStream zOut, String vPath )
throws IOException
{
if( m_addedDirs.get( vPath ) != null )
{
// don't add directories we've already added.
// no warning if we try, it is harmless in and of itself
return;
}
m_addedDirs.put( vPath, vPath );

ZipEntry ze = new ZipEntry( vPath );
if( dir != null && dir.exists() )
{
ze.setTime( dir.lastModified() );
}
else
{
ze.setTime( System.currentTimeMillis() );
}
ze.setSize( 0 );
ze.setMethod( ZipEntry.STORED );
// This is faintly ridiculous:
ze.setCrc( EMPTY_CRC );

// this is 040775 | MS-DOS directory flag in reverse byte order
ze.setExternalAttributes( 0x41FD0010L );

zOut.putNextEntry( ze );
}

protected void zipFile( final InputStream input,
final ZipOutputStream output,
final String path,
final long lastModified )
throws IOException, TaskException
{
final ZipEntry entry = new ZipEntry( path );
entry.setTime( lastModified );

/*
* XXX ZipOutputStream.putEntry expects the ZipEntry to know its
* size and the CRC sum before you start writing the data when using
* STORED mode.
*
* This forces us to process the data twice.
*
* I couldn't find any documentation on this, just found out by try
* and error.
*/

InputStream inputToStore = input;
if( !m_compress )
{
final CRC32 crc = new CRC32();
long size = 0;
if( !inputToStore.markSupported() )
{
// Store data into a byte[]
ByteArrayOutputStream bos = new ByteArrayOutputStream();

byte[] buffer = new byte[ 8 * 1024 ];
int count = 0;
do
{
size += count;
crc.update( buffer, 0, count );
bos.write( buffer, 0, count );
count = inputToStore.read( buffer, 0, buffer.length );
} while( count != -1 );
inputToStore = new ByteArrayInputStream( bos.toByteArray() );
}
else
{
inputToStore.mark( Integer.MAX_VALUE );
byte[] buffer = new byte[ 8 * 1024 ];
int count = 0;
do
{
size += count;
crc.update( buffer, 0, count );
count = inputToStore.read( buffer, 0, buffer.length );
} while( count != -1 );
inputToStore.reset();
}
entry.setSize( size );
entry.setCrc( crc.getValue() );
}

output.putNextEntry( entry );

IOUtil.copy( inputToStore, output );

m_addedFiles.add( path );
}

protected void zipFile( final File file,
final ZipOutputStream zOut,
final String vPath )
throws IOException, TaskException
{
if( file.equals( m_file ) )
{
final String message = "A zip file cannot include itself";
throw new TaskException( message );
}

final FileInputStream fIn = new FileInputStream( file );
try
{
zipFile( fIn, zOut, vPath, file.lastModified() );
}
finally
{
IOUtil.shutdownStream( fIn );
}
}
}

+ 0
- 98
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/ZipFileSet.java View File

@@ -1,98 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import java.io.File;
import org.apache.myrmidon.framework.FileSet;

/**
* A ZipFileSet is a FileSet with extra attributes useful in the context of
* Zip/Jar tasks. A ZipFileSet extends FileSets with the ability to extract a
* subset of the entries of a Zip file for inclusion in another Zip file. It
* also includes a prefix attribute which is prepended to each entry in the
* output Zip file. At present, ZipFileSets are not surfaced in the public API.
* FileSets nested in a Zip task are instantiated as ZipFileSets, and their
* attributes are only recognized in the context of the the Zip task. It is not
* possible to define a ZipFileSet outside of the Zip task and refer to it via a
* refid. However a standard FileSet may be included by reference in the Zip
* task, and attributes in the refering ZipFileSet can augment FileSet
* definition.
*
* @author <a href="mailto:don@bea.com">Don Ferguson</a>
*/
public class ZipFileSet
extends FileSet
{
private File m_src;
private String m_prefix = "";
private String m_fullpath = "";

/**
* Set the full pathname of the single entry in this fileset.
*
* @param fullpath The new Fullpath value
*/
public void setFullpath( final String fullpath )
{
m_fullpath = fullpath;
}

/**
* Prepend this prefix to the path for each zip entry. Does not perform
* reference test; the referenced file set can be augmented with a prefix.
*
* @param prefix The prefix to prepend to entries in the zip file.
*/
public void setPrefix( final String prefix )
{
m_prefix = prefix;
}

/**
* Set the source Zip file for the zipfileset. Prevents both "dir" and "src"
* from being specified.
*
* @param src The zip file from which to extract entries.
*/
public void setSrc( final File src )
{
m_src = src;
}

/**
* Return the full pathname of the single entry in this fileset.
*
* @return The Fullpath value
*/
public String getFullpath()
{
return m_fullpath;
}

/**
* Return the prefix prepended to entries in the zip file.
*
* @return The Prefix value
*/
public String getPrefix()
{
return m_prefix;
}

/**
* Get the zip file from which entries will be extracted. References are not
* followed, since it is not possible to have a reference to a ZipFileSet,
* only to a FileSet.
*
* @return The Src value
*/
public File getSrc()
{
return m_src;
}
}

+ 0
- 98
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/archive/ZipScanner.java View File

@@ -1,98 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.archive;

import java.io.File;
import org.apache.tools.todo.types.DirectoryScanner;

/**
* ZipScanner accesses the pattern matching algorithm in DirectoryScanner, which
* are protected methods that can only be accessed by subclassing. This
* implementation of FileScanner defines getIncludedFiles to return only the Zip
* File which is being scanned, not the matching Zip entries. Arguably, it
* should return the matching entries, however this would complicate existing
* code which assumes that FileScanners return a set of file system files that
* can be accessed directly.
*
* @author Don Ferguson <a href="mailto:don@bea.com">don@bea.com</a>
*/
public class ZipScanner
extends DirectoryScanner
{
/**
* The zip file which should be scanned.
*/
private File m_src;

/**
* Sets the srcFile for scanning. This is the jar or zip file that is
* scanned for matching entries.
*
* @param srcFile the (non-null) zip file name for scanning
*/
public void setSrc( final File srcFile )
{
m_src = srcFile;
}

/**
* Returns an empty list of directories to create.
*
* @return The IncludedDirectories value
*/
public String[] getIncludedDirectories()
{
return new String[ 0 ];
}

/**
* Returns the zip file itself, not the matching entries within the zip
* file. This keeps the uptodate test in the Zip task simple; otherwise we'd
* need to treat zip filesets specially.
*
* @return the source file from which entries will be extracted.
*/
public String[] getIncludedFiles()
{
final String[] result = new String[ 1 ];
result[ 0 ] = m_src.getAbsolutePath();
return result;
}

/**
* Initialize DirectoryScanner data structures.
*/
public void init()
{
if( getIncludes() == null )
{
// No includes supplied, so set it to 'matches all'
setIncludes( new String[ 1 ] );
getIncludes()[ 0 ] = "**";
}
if( getExcludes() == null )
{
setExcludes( new String[ 0 ] );
}
}

/**
* Matches a jar entry against the includes/excludes list, normalizing the
* path separator.
*
* @param path the (non-null) path name to test for inclusion
* @return <code>true</code> if the path should be included <code>false</code>
* otherwise.
*/
public boolean match( String path )
{
final String vpath =
path.replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
return isIncluded( vpath ) && !isExcluded( vpath );
}
}

+ 0
- 79
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/conditions/Http.java View File

@@ -1,79 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.conditions;

import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.conditions.Condition;

/**
* Condition to wait for a HTTP request to succeed. Its attribute(s) are: url -
* the URL of the request.
*
* @author <a href="mailto:denis@network365.com">Denis Hennessy</a>
*
* @ant.type type="condition" name="http"
*/
public class Http
implements Condition
{
String spec = null;

public void setUrl( String url )
{
spec = url;
}

/**
* Evaluates this condition.
*/
public boolean evaluate( final TaskContext context )
throws TaskException
{
if( spec == null )
{
throw new TaskException( "No url specified in HTTP task" );
}
context.debug( "Checking for " + spec );
try
{
URL url = new URL( spec );
try
{
URLConnection conn = url.openConnection();
if( conn instanceof HttpURLConnection )
{
HttpURLConnection http = (HttpURLConnection)conn;
int code = http.getResponseCode();
context.debug( "Result code for " + spec + " was " + code );
if( code > 0 && code < 500 )
{
return true;
}
else
{
return false;
}
}
}
catch( java.io.IOException e )
{
return false;
}
}
catch( MalformedURLException e )
{
throw new TaskException( "Badly formed URL: " + spec, e );
}
return true;
}
}

+ 0
- 66
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/conditions/Socket.java View File

@@ -1,66 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.conditions;

import java.io.IOException;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.conditions.Condition;

/**
* Condition to wait for a TCP/IP socket to have a listener. Its attribute(s)
* are: server - the name of the server. port - the port number of the socket.
*
* @author <a href="mailto:denis@network365.com">Denis Hennessy</a>
*
* @ant.type type="condition" name="socket"
*/
public class Socket
implements Condition
{
String server = null;
int port = 0;

public void setPort( int port )
{
this.port = port;
}

public void setServer( String server )
{
this.server = server;
}

/**
* Evaluates this condition.
*/
public boolean evaluate( TaskContext context )
throws TaskException
{
if( server == null )
{
throw new TaskException( "No server specified in Socket task" );
}
if( port == 0 )
{
throw new TaskException( "No port specified in Socket task" );
}
context.debug( "Checking for listener at " + server + ":" + port );
try
{
java.net.Socket socket = new java.net.Socket( server, port );
socket.close();
}
catch( IOException e )
{
return false;
}
return true;
}

}

+ 0
- 64
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/exec/ExecuteStreamHandler.java View File

@@ -1,64 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.exec;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.myrmidon.api.TaskException;

/**
* Used by <code>Execute</code> to handle input and output stream of
* subprocesses.
*
* @author thomas.haas@softwired-inc.com
*/
public interface ExecuteStreamHandler
{
/**
* Install a handler for the input stream of the subprocess.
*
* @param os output stream to write to the standard input stream of the
* subprocess
* @exception java.io.IOException Description of Exception
*/
void setProcessInputStream( OutputStream os )
throws IOException;

/**
* Install a handler for the error stream of the subprocess.
*
* @param is input stream to read from the error stream from the subprocess
* @exception java.io.IOException Description of Exception
*/
void setProcessErrorStream( InputStream is )
throws IOException;

/**
* Install a handler for the output stream of the subprocess.
*
* @param is input stream to read from the error stream from the subprocess
* @exception java.io.IOException Description of Exception
*/
void setProcessOutputStream( InputStream is )
throws TaskException, IOException;

/**
* Start handling of the streams.
*
* @exception java.io.IOException Description of Exception
*/
void start()
throws IOException;

/**
* Stop handling of the streams - will not be restarted.
*/
void stop()
throws TaskException;
}

+ 0
- 635
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/i18n/Translate.java View File

@@ -1,635 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.i18n;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Locale;
import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.FileSet;
import org.apache.tools.todo.taskdefs.MatchingTask;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.tools.todo.types.ScannerUtil;

/**
* Translates text embedded in files using Resource Bundle files.
*
* @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a>
*/
public class Translate
extends MatchingTask
{
/**
* ArrayList to hold source file sets.
*/
private ArrayList filesets = new ArrayList();
/**
* Holds key value pairs loaded from resource bundle file
*/
private Hashtable resourceMap = new Hashtable();
/**
* Last Modified Timestamp of resource bundle file being used.
*/
private long[] bundleLastModified = new long[ 7 ];
/**
* Has at least one file from the bundle been loaded?
*/
private boolean loaded = false;

/**
* Family name of resource bundle
*/
private String bundle;
/**
* Locale specific country of the resource bundle
*/
private String bundleCountry;
/**
* Resource Bundle file encoding scheme, defaults to srcEncoding
*/
private String bundleEncoding;
/**
* Locale specific language of the resource bundle
*/
private String bundleLanguage;
/**
* Locale specific variant of the resource bundle
*/
private String bundleVariant;
/**
* Destination file encoding scheme
*/
private String destEncoding;
/**
* Last Modified Timestamp of destination file being used.
*/
private long destLastModified;
/**
* Ending token to identify keys
*/
private String endToken;
/**
* Create new destination file? Defaults to false.
*/
private boolean forceOverwrite;

/**
* Source file encoding scheme
*/
private String srcEncoding;
/**
* Last Modified Timestamp of source file being used.
*/
private long srcLastModified;
/**
* Starting token to identify keys
*/
private String startToken;
/**
* Destination directory
*/
private File toDir;

/**
* Sets Family name of resource bundle
*
* @param bundle The new Bundle value
*/
public void setBundle( String bundle )
{
this.bundle = bundle;
}

/**
* Sets locale specific country of resource bundle
*
* @param bundleCountry The new BundleCountry value
*/
public void setBundleCountry( String bundleCountry )
{
this.bundleCountry = bundleCountry;
}

/**
* Sets Resource Bundle file encoding scheme
*
* @param bundleEncoding The new BundleEncoding value
*/
public void setBundleEncoding( String bundleEncoding )
{
this.bundleEncoding = bundleEncoding;
}

/**
* Sets locale specific language of resource bundle
*
* @param bundleLanguage The new BundleLanguage value
*/
public void setBundleLanguage( String bundleLanguage )
{
this.bundleLanguage = bundleLanguage;
}

/**
* Sets locale specific variant of resource bundle
*
* @param bundleVariant The new BundleVariant value
*/
public void setBundleVariant( String bundleVariant )
{
this.bundleVariant = bundleVariant;
}

/**
* Sets destination file encoding scheme. Defaults to source file encoding
*
* @param destEncoding The new DestEncoding value
*/
public void setDestEncoding( String destEncoding )
{
this.destEncoding = destEncoding;
}

/**
* Sets ending token to identify keys
*
* @param endToken The new EndToken value
*/
public void setEndToken( String endToken )
{
this.endToken = endToken;
}

/**
* Overwrite existing file irrespective of whether it is newer than the
* source file as well as the resource bundle file? Defaults to false.
*
* @param forceOverwrite The new ForceOverwrite value
*/
public void setForceOverwrite( boolean forceOverwrite )
{
this.forceOverwrite = forceOverwrite;
}

/**
* Sets source file encoding scheme
*
* @param srcEncoding The new SrcEncoding value
*/
public void setSrcEncoding( String srcEncoding )
{
this.srcEncoding = srcEncoding;
}

/**
* Sets starting token to identify keys
*
* @param startToken The new StartToken value
*/
public void setStartToken( String startToken )
{
this.startToken = startToken;
}

/**
* Sets Destination directory
*
* @param toDir The new ToDir value
*/
public void setToDir( File toDir )
{
this.toDir = toDir;
}

/**
* Adds a set of files (nested fileset attribute).
*
* @param set The feature to be added to the Fileset attribute
*/
public void addFileset( FileSet set )
{
filesets.add( set );
}

/**
* Check attributes values, load resource map and translate
*
* @exception TaskException Description of Exception
*/
public void execute()
throws TaskException
{
if( bundle == null )
{
throw new TaskException( "The bundle attribute must be set." );
}

if( startToken == null )
{
throw new TaskException( "The starttoken attribute must be set." );
}

if( startToken.length() != 1 )
{
throw new TaskException(
"The starttoken attribute must be a single character." );
}

if( endToken == null )
{
throw new TaskException( "The endtoken attribute must be set." );
}

if( endToken.length() != 1 )
{
throw new TaskException(
"The endtoken attribute must be a single character." );
}

if( bundleLanguage == null )
{
Locale l = Locale.getDefault();
bundleLanguage = l.getLanguage();
}

if( bundleCountry == null )
{
bundleCountry = Locale.getDefault().getCountry();
}

if( bundleVariant == null )
{
Locale l = new Locale( bundleLanguage, bundleCountry );
bundleVariant = l.getVariant();
}

if( toDir == null )
{
throw new TaskException( "The todir attribute must be set." );
}

if( !toDir.exists() )
{
toDir.mkdirs();
}
else
{
if( toDir.isFile() )
{
throw new TaskException( toDir + " is not a directory" );
}
}

if( srcEncoding == null )
{
srcEncoding = System.getProperty( "file.encoding" );
}

if( destEncoding == null )
{
destEncoding = srcEncoding;
}

if( bundleEncoding == null )
{
bundleEncoding = srcEncoding;
}

loadResourceMaps();

translate();
}

/**
* Load resourceMap with key value pairs. Values of existing keys are not
* overwritten. Bundle's encoding scheme is used.
*
* @param ins Description of Parameter
* @exception TaskException Description of Exception
*/
private void loadResourceMap( FileInputStream ins )
throws TaskException
{
try
{
BufferedReader in = null;
InputStreamReader isr = new InputStreamReader( ins, bundleEncoding );
in = new BufferedReader( isr );
String line = null;
while( ( line = in.readLine() ) != null )
{
//So long as the line isn't empty and isn't a comment...
if( line.trim().length() > 1 &&
( '#' != line.charAt( 0 ) || '!' != line.charAt( 0 ) ) )
{
//Legal Key-Value separators are :, = and white space.
int sepIndex = line.indexOf( '=' );
if( -1 == sepIndex )
{
sepIndex = line.indexOf( ':' );
}
if( -1 == sepIndex )
{
for( int k = 0; k < line.length(); k++ )
{
if( Character.isSpaceChar( line.charAt( k ) ) )
{
sepIndex = k;
break;
}
}
}
//Only if we do have a key is there going to be a value
if( -1 != sepIndex )
{
String key = line.substring( 0, sepIndex ).trim();
String value = line.substring( sepIndex + 1 ).trim();
//Handle line continuations, if any
while( value.endsWith( "\\" ) )
{
value = value.substring( 0, value.length() - 1 );
if( ( line = in.readLine() ) != null )
{
value = value + line.trim();
}
else
{
break;
}
}
if( key.length() > 0 )
{
//Has key already been loaded into resourceMap?
if( resourceMap.get( key ) == null )
{
resourceMap.put( key, value );
}
}
}
}
}
if( in != null )
{
in.close();
}
}
catch( IOException ioe )
{
throw new TaskException( ioe.getMessage() );
}
}

/**
* Load resource maps based on resource bundle encoding scheme. The resource
* bundle lookup searches for resource files with various suffixes on the
* basis of (1) the desired locale and (2) the default locale
* (basebundlename), in the following order from lower-level (more specific)
* to parent-level (less specific): basebundlename + "_" + language1 + "_" +
* country1 + "_" + variant1 basebundlename + "_" + language1 + "_" +
* country1 basebundlename + "_" + language1 basebundlename basebundlename +
* "_" + language2 + "_" + country2 + "_" + variant2 basebundlename + "_" +
* language2 + "_" + country2 basebundlename + "_" + language2 To the
* generated name, a ".properties" string is appeneded and once this file is
* located, it is treated just like a properties file but with bundle
* encoding also considered while loading.
*
* @exception TaskException Description of Exception
*/
private void loadResourceMaps()
throws TaskException
{
Locale locale = new Locale( bundleLanguage,
bundleCountry,
bundleVariant );
String language = locale.getLanguage().length() > 0 ?
"_" + locale.getLanguage() :
"";
String country = locale.getCountry().length() > 0 ?
"_" + locale.getCountry() :
"";
String variant = locale.getVariant().length() > 0 ?
"_" + locale.getVariant() :
"";
String bundleFile = bundle + language + country + variant;
processBundle( bundleFile, 0, false );

bundleFile = bundle + language + country;
processBundle( bundleFile, 1, false );

bundleFile = bundle + language;
processBundle( bundleFile, 2, false );

bundleFile = bundle;
processBundle( bundleFile, 3, false );

//Load default locale bundle files
//using default file encoding scheme.
locale = Locale.getDefault();

language = locale.getLanguage().length() > 0 ?
"_" + locale.getLanguage() :
"";
country = locale.getCountry().length() > 0 ?
"_" + locale.getCountry() :
"";
variant = locale.getVariant().length() > 0 ?
"_" + locale.getVariant() :
"";
bundleEncoding = System.getProperty( "file.encoding" );

bundleFile = bundle + language + country + variant;
processBundle( bundleFile, 4, false );

bundleFile = bundle + language + country;
processBundle( bundleFile, 5, false );

bundleFile = bundle + language;
processBundle( bundleFile, 6, true );
}

/**
* Process each file that makes up this bundle.
*
* @param bundleFile Description of Parameter
* @param i Description of Parameter
* @param checkLoaded Description of Parameter
* @exception TaskException Description of Exception
*/
private void processBundle( String bundleFile, int i,
boolean checkLoaded )
throws TaskException
{
bundleFile += ".properties";
FileInputStream ins = null;
try
{
ins = new FileInputStream( bundleFile );
loaded = true;
bundleLastModified[ i ] = new File( bundleFile ).lastModified();
getContext().debug( "Using " + bundleFile );
loadResourceMap( ins );
}
catch( IOException ioe )
{
getContext().debug( bundleFile + " not found." );
//if all resource files associated with this bundle
//have been scanned for and still not able to
//find a single resrouce file, throw exception
if( !loaded && checkLoaded )
{
throw new TaskException( ioe.getMessage() );
}
}
}

/**
* Reads source file line by line using the source encoding and searches for
* keys that are sandwiched between the startToken and endToken. The values
* for these keys are looked up from the hashtable and substituted. If the
* hashtable doesn't contain the key, they key itself is used as the value.
* Detination files and directories are created as needed. The destination
* file is overwritten only if the forceoverwritten attribute is set to true
* if the source file or any associated bundle resource file is newer than
* the destination file.
*
* @exception TaskException Description of Exception
*/
private void translate()
throws TaskException
{
for( int i = 0; i < filesets.size(); i++ )
{
FileSet fs = (FileSet)filesets.get( i );
DirectoryScanner ds = ScannerUtil.getDirectoryScanner( fs );
String[] srcFiles = ds.getIncludedFiles();
for( int j = 0; j < srcFiles.length; j++ )
{
try
{
File dest = FileUtil.resolveFile( toDir, srcFiles[ j ] );
//Make sure parent dirs exist, else, create them.
try
{
File destDir = new File( dest.getParent() );
if( !destDir.exists() )
{
destDir.mkdirs();
}
}
catch( Exception e )
{
getContext().debug( "Exception occured while trying to check/create " + " parent directory. " + e.getMessage() );
}
destLastModified = dest.lastModified();
srcLastModified = new File( srcFiles[ i ] ).lastModified();
//Check to see if dest file has to be recreated
if( forceOverwrite
|| destLastModified < srcLastModified
|| destLastModified < bundleLastModified[ 0 ]
|| destLastModified < bundleLastModified[ 1 ]
|| destLastModified < bundleLastModified[ 2 ]
|| destLastModified < bundleLastModified[ 3 ]
|| destLastModified < bundleLastModified[ 4 ]
|| destLastModified < bundleLastModified[ 5 ]
|| destLastModified < bundleLastModified[ 6 ] )
{
getContext().debug( "Processing " + srcFiles[ j ] );
FileOutputStream fos = new FileOutputStream( dest );
BufferedWriter out = new BufferedWriter(
new OutputStreamWriter( fos,
destEncoding ) );
FileInputStream fis = new FileInputStream( srcFiles[ j ] );
BufferedReader in = new BufferedReader(
new InputStreamReader( fis,
srcEncoding ) );
String line;
while( ( line = in.readLine() ) != null )
{
int startIndex = -1;
int endIndex = -1;
outer :
while( true )
{
startIndex = line.indexOf( startToken, endIndex + 1 );
if( startIndex < 0 ||
startIndex + 1 >= line.length() )
{
break;
}
endIndex = line.indexOf( endToken, startIndex + 1 );
if( endIndex < 0 )
{
break;
}
String matches = line.substring( startIndex + 1,
endIndex );
//If there is a white space or = or :, then
//it isn't to be treated as a valid key.
for( int k = 0; k < matches.length(); k++ )
{
char c = matches.charAt( k );
if( c == ':' ||
c == '=' ||
Character.isSpaceChar( c ) )
{
endIndex = endIndex - 1;
continue outer;
}
}
String replace = null;
replace = (String)resourceMap.get( matches );
//If the key hasn't been loaded into resourceMap,
//use the key itself as the value also.
if( replace == null )
{
getContext().debug( "Warning: The key: " + matches + " hasn't been defined." );
replace = matches;
}
line = line.substring( 0, startIndex )
+ replace
+ line.substring( endIndex + 1 );
endIndex = startIndex + replace.length() + 1;
if( endIndex + 1 >= line.length() )
{
break;
}
}
out.write( line );
out.newLine();
}
if( in != null )
{
in.close();
}
if( out != null )
{
out.close();
}
}
else
{
getContext().debug( "Skipping " + srcFiles[ j ] + " as destination file is up to date" );
}
}
catch( IOException ioe )
{
throw new TaskException( ioe.getMessage() );
}
}
}
}
}

+ 0
- 45
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/CompilerAdapter.java View File

@@ -1,45 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.TaskContext;

/**
* The interface that all compiler adapters must adher to. <p>
*
* A compiler adapter is an adapter that interprets the javac's parameters in
* preperation to be passed off to the compier this adapter represents. As all
* the necessary values are stored in the Javac task itself, the only thing all
* adapters need is the javac task, the execute command and a parameterless
* constructor (for reflection).</p>
*
* @author Jay Dickon Glanville <a href="mailto:jayglanville@home.com">
* jayglanville@home.com</a>
*/

public interface CompilerAdapter
{
void setTaskContext( TaskContext context );

/**
* Sets the compiler attributes, which are stored in the Javac task.
*
* @param attributes The new Javac value
*/
void setJavac( Javac attributes );

/**
* Executes the task.
*
* @return has the compilation been successful
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
boolean execute()
throws TaskException;
}

+ 0
- 155
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/CompilerAdapterFactory.java View File

@@ -1,155 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.todo.taskdefs.javac.CompilerAdapter;

/**
* Creates the necessary compiler adapter, given basic criteria.
*
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/
public class CompilerAdapterFactory
{

/**
* This is a singlton -- can't create instances!!
*/
private CompilerAdapterFactory()
{
}

/**
* Based on the parameter passed in, this method creates the necessary
* factory desired. The current mapping for compiler names are as follows:
*
* <ul>
* <li> jikes = jikes compiler
* <li> classic, javac1.1, javac1.2 = the standard compiler from JDK
* 1.1/1.2
* <li> modern, javac1.3 = the new compiler of JDK 1.3
* <li> jvc, microsoft = the command line compiler from Microsoft's SDK
* for Java / Visual J++
* <li> kjc = the kopi compiler</li>
* <li> gcj = the gcj compiler from gcc</li>
* <li> <i>a fully quallified classname</i> = the name of a compiler
* adapter
* </ul>
*
*
* @param compilerType either the name of the desired compiler, or the full
* classname of the compiler's adapter.
* @return The Compiler value
* @throws org.apache.myrmidon.api.TaskException if the compiler type could not be resolved into a
* compiler adapter.
*/
public static CompilerAdapter getCompiler( String compilerType,
TaskContext context )
throws TaskException
{
final CompilerAdapter adaptor = createAdaptor( compilerType, context );
adaptor.setTaskContext( context );
return adaptor;
}

private static CompilerAdapter createAdaptor( String compilerType, TaskContext context ) throws TaskException
{
/*
* If I've done things right, this should be the extent of the
* conditional statements required.
*/
if( compilerType.equalsIgnoreCase( "jikes" ) )
{
return new Jikes();
}
if( compilerType.equalsIgnoreCase( "extJavac" ) )
{
return new JavacExternal();
}
if( compilerType.equalsIgnoreCase( "classic" ) ||
compilerType.equalsIgnoreCase( "javac1.1" ) ||
compilerType.equalsIgnoreCase( "javac1.2" ) )
{
return new Javac12();
}
if( compilerType.equalsIgnoreCase( "modern" ) ||
compilerType.equalsIgnoreCase( "javac1.3" ) ||
compilerType.equalsIgnoreCase( "javac1.4" ) )
{
// does the modern compiler exist?
try
{
Class.forName( "com.sun.tools.javac.Main" );
}
catch( ClassNotFoundException cnfe )
{
final String message = "Modern compiler is not available - using "
+ "classic compiler";
context.warn( message );
return new Javac12();
}
return new Javac13();
}
if( compilerType.equalsIgnoreCase( "jvc" ) ||
compilerType.equalsIgnoreCase( "microsoft" ) )
{
return new Jvc();
}
if( compilerType.equalsIgnoreCase( "kjc" ) )
{
return new Kjc();
}
if( compilerType.equalsIgnoreCase( "gcj" ) )
{
return new Gcj();
}
if( compilerType.equalsIgnoreCase( "sj" ) ||
compilerType.equalsIgnoreCase( "symantec" ) )
{
return new Sj();
}
return resolveClassName( compilerType );
}

/**
* Tries to resolve the given classname into a compiler adapter. Throws a
* fit if it can't.
*
* @param className The fully qualified classname to be created.
* @return Description of the Returned Value
* @throws org.apache.myrmidon.api.TaskException This is the fit that is thrown if className isn't
* an instance of CompilerAdapter.
*/
private static CompilerAdapter resolveClassName( String className )
throws TaskException
{
try
{
Class c = Class.forName( className );
Object o = c.newInstance();
return (CompilerAdapter)o;
}
catch( ClassNotFoundException cnfe )
{
throw new TaskException( className + " can\'t be found.", cnfe );
}
catch( ClassCastException cce )
{
throw new TaskException( className + " isn\'t the classname of "
+ "a compiler adapter.", cce );
}
catch( Throwable t )
{
// for all other possibilities
throw new TaskException( className + " caused an interesting "
+ "exception.", t );
}
}
}

+ 0
- 468
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/DefaultCompilerAdapter.java View File

@@ -1,468 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import org.apache.avalon.excalibur.io.IOUtil;
import org.apache.avalon.excalibur.util.StringUtil;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.nativelib.Execute;
import org.apache.myrmidon.framework.FileSet;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.myrmidon.framework.nativelib.ArgumentList;
import org.apache.myrmidon.framework.file.Path;
import org.apache.myrmidon.framework.file.FileListUtil;
import org.apache.tools.todo.util.FileUtils;
import org.apache.aut.nativelib.PathUtil;

/**
* This is the default implementation for the CompilerAdapter interface.
* Currently, this is a cut-and-paste of the original javac task.
*
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com
* </a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/
public abstract class DefaultCompilerAdapter
implements CompilerAdapter
{
protected boolean m_debug;
protected boolean m_optimize;
protected boolean m_deprecation;
protected boolean m_depend;
protected boolean m_verbose;

protected Javac m_attributes;
protected Path m_bootclasspath;
protected Path m_compileClasspath;

protected File[] m_compileList;
protected File m_destDir;
protected String m_encoding;
protected Path m_extdirs;
protected boolean m_includeAntRuntime;
protected boolean m_includeJavaRuntime;
protected String m_memoryInitialSize;
protected String m_memoryMaximumSize;

/*
* jdg - TODO - all these attributes are currently protected, but they
* should probably be private in the near future.
*/
protected Path src;
protected String target;

private TaskContext m_taskContext;

public void setTaskContext( final TaskContext context )
{
m_taskContext = context;
}

protected final TaskContext getTaskContext()
{
return m_taskContext;
}

public void setJavac( Javac attributes )
{
m_attributes = attributes;
src = attributes.getSrcdir();
m_destDir = attributes.getDestdir();
m_encoding = attributes.getEncoding();
m_debug = attributes.getDebug();
m_optimize = attributes.isOptimize();
m_deprecation = attributes.getDeprecation();
m_depend = attributes.getDepend();
m_verbose = attributes.getVerbose();
target = attributes.getTarget();
m_bootclasspath = attributes.getBootclasspath();
m_extdirs = attributes.getExtdirs();
m_compileList = attributes.getFileList();
m_compileClasspath = attributes.getClasspath();
m_memoryInitialSize = attributes.getMemoryInitialSize();
m_memoryMaximumSize = attributes.getMemoryMaximumSize();
}

public Javac getJavac()
{
return m_attributes;
}

protected ArgumentList setupJavacCommand()
throws TaskException
{
return setupJavacCommand( false );
}

/**
* Does the command line argument processing for classic and adds the files
* to compile as well.
*
* @param debugLevelCheck Description of Parameter
* @return Description of the Returned Value
*/
protected ArgumentList setupJavacCommand( boolean debugLevelCheck )
throws TaskException
{
ArgumentList cmd = new ArgumentList();
setupJavacCommandlineSwitches( cmd, debugLevelCheck );
logFilesToCompile( cmd );
addFilesToCompile( cmd );
return cmd;
}

/**
* Does the command line argument processing common to classic and modern.
* Doesn't add the files to compile.
*
* @param cmd Description of Parameter
* @param useDebugLevel Description of Parameter
* @return Description of the Returned Value
*/
protected ArgumentList setupJavacCommandlineSwitches( ArgumentList cmd,
boolean useDebugLevel )
throws TaskException
{
Path classpath = new Path();
addCompileClasspath( classpath );
String memoryParameterPrefix = "-J-X";
if( m_memoryInitialSize != null )
{
if( !m_attributes.isForkedJavac() )
{
final String message = "Since fork is false, ignoring memoryInitialSize setting.";
getTaskContext().warn( message );
}
else
{
cmd.addArgument( memoryParameterPrefix + "ms" + m_memoryInitialSize );
}
}

if( m_memoryMaximumSize != null )
{
if( !m_attributes.isForkedJavac() )
{
final String message = "Since fork is false, ignoring memoryMaximumSize setting.";
getTaskContext().warn( message );
}
else
{
cmd.addArgument( memoryParameterPrefix + "mx" + m_memoryMaximumSize );
}
}

if( m_attributes.getNowarn() )
{
cmd.addArgument( "-nowarn" );
}

if( m_deprecation == true )
{
cmd.addArgument( "-deprecation" );
}

if( m_destDir != null )
{
cmd.addArgument( "-d" );
cmd.addArgument( m_destDir );
}

cmd.addArgument( "-classpath" );
cmd.addArgument( FileListUtil.formatPath( classpath, getTaskContext() ) );

cmd.addArgument( "-sourcepath" );
cmd.addArgument( FileListUtil.formatPath( src, getTaskContext() ) );

if( target != null )
{
cmd.addArgument( "-target" );
cmd.addArgument( target );
}

final String[] bootclasspath = m_bootclasspath.listFiles( getTaskContext() );
if( bootclasspath.length > 0 )
{
cmd.addArgument( "-bootclasspath" );
cmd.addArgument( PathUtil.formatPath( bootclasspath ) );
}

if( m_extdirs != null )
{
cmd.addArgument( "-extdirs" );
cmd.addArgument( FileListUtil.formatPath( m_extdirs, getTaskContext() ) );
}

if( m_encoding != null )
{
cmd.addArgument( "-encoding" );
cmd.addArgument( m_encoding );
}
if( m_debug )
{
if( useDebugLevel )
{
String debugLevel = m_attributes.getDebugLevel();
if( debugLevel != null )
{
cmd.addArgument( "-g:" + debugLevel );
}
else
{
cmd.addArgument( "-g" );
}
}
else
{
cmd.addArgument( "-g" );
}
}
else
{
cmd.addArgument( "-g:none" );
}
if( m_optimize )
{
cmd.addArgument( "-O" );
}

if( m_verbose )
{
cmd.addArgument( "-verbose" );
}

addCurrentCompilerArgs( cmd );

return cmd;
}

/**
* Does the command line argument processing for modern and adds the files
* to compile as well.
*
* @return Description of the Returned Value
*/
protected ArgumentList setupModernJavacCommand()
throws TaskException
{
ArgumentList cmd = new ArgumentList();
setupModernJavacCommandlineSwitches( cmd );

logFilesToCompile( cmd );
addFilesToCompile( cmd );
return cmd;
}

/**
* Does the command line argument processing for modern. Doesn't add the
* files to compile.
*
* @param cmd Description of Parameter
* @return Description of the Returned Value
*/
protected ArgumentList setupModernJavacCommandlineSwitches( ArgumentList cmd )
throws TaskException
{
setupJavacCommandlineSwitches( cmd, true );
if( m_attributes.getSource() != null )
{
cmd.addArgument( "-source" );
cmd.addArgument( m_attributes.getSource() );
}
return cmd;
}

/**
* Adds the compilation classpath to a path.
*/
protected void addCompileClasspath( final Path classpath )
throws TaskException
{
// add dest dir to classpath so that previously compiled and
// untouched classes are on classpath

if( m_destDir != null )
{
classpath.addLocation( m_destDir );
}

// add the classpath
if( m_compileClasspath != null )
{
classpath.add( m_compileClasspath );
}
}

/**
* Adds the command line arguments specifc to the current implementation.
*
* @param cmd The feature to be added to the CurrentCompilerArgs attribute
*/
protected void addCurrentCompilerArgs( ArgumentList cmd )
{
cmd.addArguments( getJavac().getCurrentCompilerArgs() );
}

/**
* Do the compile with the specified arguments.
*
* @param cmd - the command line, to which the names of the files to
* compile are added.
*/
protected boolean executeExternalCompile( final Commandline cmd )
throws TaskException
{
logFilesToCompile( cmd );

File tmpFile = null;

try
{
/*
* Many system have been reported to get into trouble with
* long command lines - no, not only Windows ;-).
*
* POSIX seems to define a lower limit of 4k, so use a temporary
* file.
*/
try
{
tmpFile = File.createTempFile( "javac", "", new File( "." ) );
final FileWriter fout = new FileWriter( tmpFile );
try
{
final PrintWriter out = new PrintWriter( fout );
for( int i = 0; i < m_compileList.length; i++ )
{
File file = m_compileList[i ];
out.println( file.getAbsolutePath() );
}
out.close();
}
finally
{
IOUtil.shutdownWriter( fout );
}
}
catch( final IOException ioe )
{
throw new TaskException( "Error creating temporary file", ioe );
}

cmd.addArgument( "@" + tmpFile.getAbsolutePath() );

final Execute exe = new Execute();
exe.setIgnoreReturnCode( true );
exe.setCommandline( cmd );
return exe.execute( getTaskContext() ) == 0;
}
finally
{
if( tmpFile != null )
{
tmpFile.delete();
}
}
}

/**
* Logs the compilation parameters, adds the files to compile and logs the
* &qout;niceSourceList&quot;
*
* @param cmd Description of Parameter
*/
protected void logFilesToCompile( final ArgumentList cmd )
throws TaskException
{
final String[] cmdline = cmd.getArguments();
getTaskContext().debug( "Compilation args: " + FileUtils.formatCommandLine( cmdline ) );

StringBuffer niceSourceList = new StringBuffer( "File" );
if( m_compileList.length != 1 )
{
niceSourceList.append( "s" );
}
niceSourceList.append( " to be compiled:" );

niceSourceList.append( StringUtil.LINE_SEPARATOR );

for( int i = 0; i < m_compileList.length; i++ )
{
String arg = m_compileList[ i ].getAbsolutePath();
niceSourceList.append( " " + arg + StringUtil.LINE_SEPARATOR );
}

getTaskContext().debug( niceSourceList.toString() );
}

/**
* Adds the files to compile to a command-line
*/
protected void addFilesToCompile( final ArgumentList cmd )
{
for( int i = 0; i < m_compileList.length; i++ )
{
File file = m_compileList[i ];
cmd.addArgument( file );
}
}

/**
* Emulation of extdirs feature in java >= 1.2. This method adds all files
* in the given directories (but not in sub-directories!) to the classpath,
* so that you don't have to specify them all one by one.
*/
protected void addExtdirs( Path path )
throws TaskException
{
if( m_extdirs == null )
{
String extProp = System.getProperty( "java.ext.dirs" );
if( extProp != null )
{
m_extdirs = new Path( extProp );
}
else
{
return;
}
}

addExtdirs( path, m_extdirs, getTaskContext() );
}

/**
* Adds the contents of a set of directories to a path.
*/
public static void addExtdirs( final Path toPath,
final Path extDirs,
final TaskContext context )
throws TaskException
{
final String[] dirs = extDirs.listFiles( context );
for( int i = 0; i < dirs.length; i++ )
{
final File dir = new File( dirs[ i ] );
if( dir.exists() && dir.isDirectory() )
{
final FileSet fileSet = new FileSet();
fileSet.setDir( dir );
fileSet.setIncludes( "*" );
toPath.addFileset( fileSet );
}
}
}
}


+ 0
- 107
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Gcj.java View File

@@ -1,107 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.myrmidon.framework.file.Path;
import org.apache.myrmidon.framework.file.FileListUtil;

/**
* The implementation of the gcj compiler. This is primarily a cut-and-paste
* from the jikes.
*
* @author <a href="mailto:tora@debian.org">Takashi Okamoto</a>
* @author tora@debian.org
*/
public class Gcj extends DefaultCompilerAdapter
{

/**
* Performs a compile using the gcj compiler.
*
* @return Description of the Returned Value
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
public boolean execute()
throws TaskException
{
Commandline cmd;
getTaskContext().debug( "Using gcj compiler" );
cmd = setupGCJCommand();

return executeExternalCompile( cmd );
}

protected Commandline setupGCJCommand()
throws TaskException
{
Commandline cmd = new Commandline();
Path classpath = new Path();

// gcj doesn't support bootclasspath dir (-bootclasspath)
// so we'll emulate it for compatibility and convenience.
final String[] bootclasspath = m_bootclasspath.listFiles( getTaskContext() );
classpath.add( bootclasspath );

// gcj doesn't support an extension dir (-extdir)
// so we'll emulate it for compatibility and convenience.
addExtdirs( classpath );

if( bootclasspath.length == 0 )
{
// no bootclasspath, therefore, get one from the java runtime
m_includeJavaRuntime = true;
}

addCompileClasspath( classpath );

// Gcj has no option for source-path so we
// will add it to classpath.
classpath.add( src );

cmd.setExecutable( "gcj" );

if( m_destDir != null )
{
cmd.addArgument( "-d" );
cmd.addArgument( m_destDir );

if( m_destDir.mkdirs() )
{
throw new TaskException( "Can't make output directories. Maybe permission is wrong. " );
}
;
}

cmd.addArgument( "-classpath" );
cmd.addArgument( FileListUtil.formatPath( classpath, getTaskContext() ) );

if( m_encoding != null )
{
cmd.addArgument( "--encoding=" + m_encoding );
}
if( m_debug )
{
cmd.addArgument( "-g1" );
}
if( m_optimize )
{
cmd.addArgument( "-O" );
}

/**
* gcj should be set for generate class.
*/
cmd.addArgument( "-C" );

addCurrentCompilerArgs( cmd );

return cmd;
}
}

+ 0
- 43
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/ImplementationSpecificArgument.java View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import org.apache.myrmidon.framework.nativelib.Argument;

/**
* Adds an "implementation" attribute to Commandline$Attribute used to
* filter command line attributes based on the current implementation.
*/
public class ImplementationSpecificArgument
extends Argument
{
private String m_impl;
private Javac m_javac;

public ImplementationSpecificArgument( Javac javac )
{
m_javac = javac;
}

public void setImplementation( String impl )
{
this.m_impl = impl;
}

public String[] getParts()
{
if( m_impl == null || m_impl.equals( m_javac.determineCompiler() ) )
{
return super.getParts();
}
else
{
return new String[ 0 ];
}
}
}

+ 0
- 753
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Javac.java View File

@@ -1,753 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.aut.nativelib.Os;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.JavaVersion;
import org.apache.tools.todo.taskdefs.MatchingTask;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.myrmidon.framework.file.Path;
import org.apache.tools.todo.types.SourceFileScanner;
import org.apache.tools.todo.util.mappers.GlobPatternMapper;

/**
* Task to compile Java source files. This task can take the following
* arguments:
* <ul>
* <li> sourcedir
* <li> destdir
* <li> deprecation
* <li> classpath
* <li> bootclasspath
* <li> extdirs
* <li> optimize
* <li> debug
* <li> encoding
* <li> target
* <li> depend
* <li> vebose
* <li> failonerror
* <li> includeantruntime
* <li> includejavaruntime
* <li> source
* </ul>
* Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required. <p>
*
* 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.
*
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com
* </a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/
public class Javac
extends MatchingTask
{
private final static String FAIL_MSG
= "Compile failed, messages should have been provided.";

private boolean m_debug;
private boolean m_optimize;
private boolean m_deprecation;
private boolean m_depend;
private boolean m_verbose;
private boolean m_includeAntRuntime = true;
private boolean m_includeJavaRuntime;
private boolean m_fork;
private String m_forkedExecutable;
private boolean m_nowarn;
private ArrayList m_implementationSpecificArgs = new ArrayList();

protected File[] m_compileList = new File[ 0 ];
private Path m_bootclasspath = new Path();
private Path m_compileClasspath;
private String m_debugLevel;
private File m_destDir;
private String m_encoding;
private Path m_extdirs;
private String m_memoryInitialSize;
private String m_memoryMaximumSize;
private String m_source;
private Path m_src;
private String m_target;

/**
* Adds an element to the bootclasspath that will be used to compile the
* classes against.
*/
public void addBootclasspath( final Path bootclasspath )
{
m_bootclasspath.add( bootclasspath );
}

/**
* Adds an element to the classpath to be used for this compilation.
*/
public void addClasspath( Path classpath )
{
if( m_compileClasspath == null )
{
m_compileClasspath = classpath;
}
else
{
m_compileClasspath.add( classpath );
}
}

/**
* Set the debug flag.
*/
public void setDebug( final boolean debug )
{
m_debug = debug;
}

/**
* Set the value of debugLevel.
*
* @param v Value to assign to debugLevel.
*/
public void setDebugLevel( String v )
{
m_debugLevel = v;
}

/**
* Set the depend flag.
*
* @param depend The new Depend value
*/
public void setDepend( boolean depend )
{
m_depend = depend;
}

/**
* Set the deprecation flag.
*
* @param deprecation The new Deprecation value
*/
public void setDeprecation( boolean deprecation )
{
m_deprecation = deprecation;
}

/**
* Set the destination directory into which the Java source files should be
* compiled.
*
* @param destDir The new Destdir value
*/
public void setDestdir( File destDir )
{
m_destDir = destDir;
}

/**
* Set the Java source file encoding name.
*
* @param encoding The new Encoding value
*/
public void setEncoding( String encoding )
{
m_encoding = encoding;
}

/**
* Adds an element to the extension directories that will be used during
* the compilation.
*
* @param extdirs The new Extdirs value
*/
public void addExtdirs( Path extdirs )
throws TaskException
{
if( m_extdirs == null )
{
m_extdirs = extdirs;
}
else
{
m_extdirs.add( extdirs );
}
}

/**
* Sets whether to fork the javac compiler.
*/
public void setFork( final boolean fork )
{
m_fork = fork;
if( fork )
{
m_forkedExecutable = getSystemJavac();
}
}

/**
* Include ant's own classpath in this task's classpath?
*
* @param include The new Includeantruntime value
*/
public void setIncludeantruntime( boolean include )
{
m_includeAntRuntime = include;
}

/**
* Sets whether or not to include the java runtime libraries to this task's
* classpath.
*
* @param include The new Includejavaruntime value
*/
public void setIncludejavaruntime( boolean include )
{
m_includeJavaRuntime = include;
}

/**
* Set the memoryInitialSize flag.
*
* @param memoryInitialSize The new MemoryInitialSize value
*/
public void setMemoryInitialSize( String memoryInitialSize )
{
m_memoryInitialSize = memoryInitialSize;
}

/**
* Set the memoryMaximumSize flag.
*
* @param memoryMaximumSize The new MemoryMaximumSize value
*/
public void setMemoryMaximumSize( String memoryMaximumSize )
{
m_memoryMaximumSize = memoryMaximumSize;
}

/**
* Sets whether the -nowarn option should be used.
*
* @param flag The new Nowarn value
*/
public void setNowarn( boolean flag )
{
m_nowarn = flag;
}

/**
* Set the optimize flag.
*
* @param optimize The new Optimize value
*/
public void setOptimize( boolean optimize )
{
m_optimize = optimize;
}

/**
* Set the value of source.
*
* @param v Value to assign to source.
*/
public void setSource( String v )
{
m_source = v;
}

/**
* Adds an element to the source dirs to find the source Java files.
*
* @param srcDir The new Srcdir value
*/
public void addSrcdir( Path srcDir )
throws TaskException
{
if( m_src == null )
{
m_src = srcDir;
}
else
{
m_src.add( srcDir );
}
}

/**
* Sets the target VM that the classes will be compiled for. Valid strings
* are "1.1", "1.2", and "1.3".
*
* @param target The new Target value
*/
public void setTarget( String target )
{
m_target = target;
}

/**
* Set the verbose flag.
*
* @param verbose The new Verbose value
*/
public void setVerbose( boolean verbose )
{
m_verbose = verbose;
}

/**
* Gets the bootclasspath that will be used to compile the classes against.
*
* @return The Bootclasspath value
*/
public Path getBootclasspath()
{
return m_bootclasspath;
}

/**
* Gets the classpath to be used for this compilation.
*
* @return The Classpath value
*/
public Path getClasspath()
{
return m_compileClasspath;
}

protected File getBaseDir()
{
return getBaseDirectory();
}

/**
* Get the additional implementation specific command line arguments.
*
* @return array of command line arguments, guaranteed to be non-null.
*/
public String[] getCurrentCompilerArgs()
{
ArrayList args = new ArrayList();
for( Iterator enum = m_implementationSpecificArgs.iterator();
enum.hasNext();
)
{
String[] curr =
( (ImplementationSpecificArgument)enum.next() ).getParts();
for( int i = 0; i < curr.length; i++ )
{
args.add( curr[ i ] );
}
}
final String[] res = new String[ args.size() ];
return (String[])args.toArray( res );
}

/**
* Gets the debug flag.
*
* @return The Debug value
*/
public boolean getDebug()
{
return m_debug;
}

/**
* Get the value of debugLevel.
*
* @return value of debugLevel.
*/
public String getDebugLevel()
{
return m_debugLevel;
}

/**
* Gets the depend flag.
*
* @return The Depend value
*/
public boolean getDepend()
{
return m_depend;
}

/**
* Gets the deprecation flag.
*
* @return The Deprecation value
*/
public boolean getDeprecation()
{
return m_deprecation;
}

/**
* Gets the destination directory into which the java source files should be
* compiled.
*
* @return The Destdir value
*/
public File getDestdir()
{
return m_destDir;
}

/**
* Gets the java source file encoding name.
*
* @return The Encoding value
*/
public String getEncoding()
{
return m_encoding;
}

/**
* Gets the extension directories that will be used during the compilation.
*
* @return The Extdirs value
*/
public Path getExtdirs()
{
return m_extdirs;
}

/**
* Gets the list of files to be compiled.
*
* @return The FileList value
*/
public File[] getFileList()
{
return m_compileList;
}

/**
* Gets whether or not the ant classpath is to be included in the task's
* classpath.
*
* @return The Includeantruntime value
*/
public boolean getIncludeantruntime()
{
return m_includeAntRuntime;
}

/**
* Gets whether or not the java runtime should be included in this task's
* classpath.
*
* @return The Includejavaruntime value
*/
public boolean getIncludejavaruntime()
{
return m_includeJavaRuntime;
}

/**
* The name of the javac executable to use in fork-mode.
*
* @return The JavacExecutable value
*/
public String getJavacExecutable()
{
if( m_forkedExecutable == null && isForkedJavac() )
{
m_forkedExecutable = getSystemJavac();
}
else if( m_forkedExecutable != null && !isForkedJavac() )
{
m_forkedExecutable = null;
}
return m_forkedExecutable;
}

/**
* Gets the memoryInitialSize flag.
*
* @return The MemoryInitialSize value
*/
public String getMemoryInitialSize()
{
return m_memoryInitialSize;
}

/**
* Gets the memoryMaximumSize flag.
*
* @return The MemoryMaximumSize value
*/
public String getMemoryMaximumSize()
{
return m_memoryMaximumSize;
}

/**
* Should the -nowarn option be used.
*
* @return The Nowarn value
*/
public boolean getNowarn()
{
return m_nowarn;
}

/**
* Gets the optimize flag.
*
* @return The Optimize value
*/
public boolean isOptimize()
{
return m_optimize;
}

/**
* Get the value of source.
*
* @return value of source.
*/
public String getSource()
{
return m_source;
}

/**
* Gets the source dirs to find the source java files.
*
* @return The Srcdir value
*/
public Path getSrcdir()
{
return m_src;
}

/**
* Gets the target VM that the classes will be compiled for.
*
* @return The Target value
*/
public String getTarget()
{
return m_target;
}

/**
* Gets the verbose flag.
*
* @return The Verbose value
*/
public boolean getVerbose()
{
return m_verbose;
}

/**
* Is this a forked invocation of JDK's javac?
*
* @return The ForkedJavac value
*/
public boolean isForkedJavac()
{
return m_fork;
}

/**
* Adds an implementation specific command line argument.
*/
public ImplementationSpecificArgument createCompilerArg()
{
final ImplementationSpecificArgument arg = new ImplementationSpecificArgument( this );
m_implementationSpecificArgs.add( arg );
return arg;
}

/**
* Executes the task.
*
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
public void execute()
throws TaskException
{
// first off, make sure that we've got a srcdir

if( m_src == null )
{
throw new TaskException( "srcdir attribute must be set!" );
}
String[] list = m_src.listFiles( getContext() );
if( list.length == 0 )
{
throw new TaskException( "srcdir attribute must be set!" );
}

if( m_destDir != null && !m_destDir.isDirectory() )
{
throw new TaskException( "destination directory \"" + m_destDir + "\" does not exist or is not a directory" );
}

// scan source directories and dest directory to build up
// compile lists
resetFileLists();
for( int i = 0; i < list.length; i++ )
{
final String filename = list[ i ];
File srcDir = (File)getContext().resolveFile( filename );
if( !srcDir.exists() )
{
throw new TaskException( "srcdir \"" + srcDir.getPath() + "\" does not exist!" );
}

DirectoryScanner ds = getDirectoryScanner( srcDir );

String[] files = ds.getIncludedFiles();

scanDir( srcDir, m_destDir != null ? m_destDir : srcDir, files );
}

// compile the source files

String compiler = determineCompiler();

if( m_compileList.length > 0 )
{

CompilerAdapter adapter =
CompilerAdapterFactory.getCompiler( compiler, getContext() );
final String message = "Compiling " + m_compileList.length + " source file" +
( m_compileList.length == 1 ? "" : "s" ) +
( m_destDir != null ? " to " + m_destDir : "" );
getContext().info( message );

// now we need to populate the compiler adapter
adapter.setJavac( this );

// finally, lets execute the compiler!!
if( !adapter.execute() )
{
throw new TaskException( FAIL_MSG );
}
}
}

protected String getSystemJavac()
{
// This is the most common extension case - exe for windows and OS/2,
// nothing for *nix.
String extension = Os.isFamily( Os.OS_FAMILY_DOS ) ? ".exe" : "";

// Look for java in the java.home/../bin directory. Unfortunately
// on Windows java.home doesn't always refer to the correct location,
// so we need to fall back to assuming java is somewhere on the
// PATH.
File jExecutable =
new File( System.getProperty( "java.home" ) +
"/../bin/javac" + extension );

if( jExecutable.exists() && !Os.isFamily( Os.OS_FAMILY_NETWARE ) )
{
return jExecutable.getAbsolutePath();
}
else
{
return "javac";
}
}

protected boolean isJdkCompiler( String compiler )
{
return "modern".equals( compiler ) ||
"classic".equals( compiler ) ||
"javac1.1".equals( compiler ) ||
"javac1.2".equals( compiler ) ||
"javac1.3".equals( compiler ) ||
"javac1.4".equals( compiler );
}

/**
* Clear the list of files to be compiled and copied..
*/
protected void resetFileLists()
{
m_compileList = new File[ 0 ];
}

/**
* Scans the directory looking for source files to be compiled. The results
* are returned in the class variable compileList
*
* @param srcDir Description of Parameter
* @param destDir Description of Parameter
* @param files Description of Parameter
*/
protected void scanDir( File srcDir, File destDir, String files[] )
throws TaskException
{
GlobPatternMapper m = new GlobPatternMapper();
m.setFrom( "*.java" );
m.setTo( "*.class" );
SourceFileScanner sfs = new SourceFileScanner();
File[] newFiles = sfs.restrictAsFiles( files, srcDir, destDir, m, getContext() );

if( newFiles.length > 0 )
{
File[] newCompileList = new File[ m_compileList.length +
newFiles.length ];
System.arraycopy( m_compileList, 0, newCompileList, 0,
m_compileList.length );
System.arraycopy( newFiles, 0, newCompileList,
m_compileList.length, newFiles.length );
m_compileList = newCompileList;
}
}

protected String determineCompiler()
{
Object compiler = getContext().getProperty( "build.compiler" );
if( compiler != null )
{
if( isJdkCompiler( compiler.toString() ) )
{
final String message = "Since fork is true, ignoring build.compiler setting.";
getContext().warn( message );
compiler = "extJavac";
}
else
{
getContext().warn( "Since build.compiler setting isn't classic or modern, ignoring fork setting." );
}
}
else
{
compiler = "extJavac";
}

if( compiler == null )
{
if( JavaVersion.JAVA1_2 != JavaVersion.getCurrentJavaVersion() )
{
compiler = "modern";
}
else
{
compiler = "classic";
}
}
return compiler.toString();
}
}

+ 0
- 69
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Javac12.java View File

@@ -1,69 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.myrmidon.framework.nativelib.ArgumentList;
import org.apache.tools.todo.taskdefs.javac.DefaultCompilerAdapter;

/**
* The implementation of the javac compiler for JDK 1.2 This is primarily a
* cut-and-paste from the original javac task before it was refactored.
*
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com
* </a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/
public class Javac12 extends DefaultCompilerAdapter
{

public boolean execute()
throws TaskException
{
getTaskContext().debug( "Using classic compiler" );
ArgumentList cmd = setupJavacCommand( true );

try
{
// Create an instance of the compiler, redirecting output to
// the project log
Class c = Class.forName( "sun.tools.javac.Main" );
Constructor cons = c.getConstructor( new Class[]{OutputStream.class, String.class} );
Object compiler = cons.newInstance( new Object[]{System.out, "javac"} );

// Call the compile() method
Method compile = c.getMethod( "compile", new Class[]{String[].class} );
Boolean ok = (Boolean)compile.invoke( compiler, new Object[]{cmd.getArguments()} );
return ok.booleanValue();
}
catch( ClassNotFoundException ex )
{
throw new TaskException( "Cannot use classic compiler, as it is not available" +
" A common solution is to set the environment variable" +
" JAVA_HOME to your jdk directory." );
}
catch( Exception ex )
{
if( ex instanceof TaskException )
{
throw (TaskException)ex;
}
else
{
throw new TaskException( "Error starting classic compiler: ", ex );
}
}
}
}

+ 0
- 64
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Javac13.java View File

@@ -1,64 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import java.lang.reflect.Method;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.myrmidon.framework.nativelib.ArgumentList;
import org.apache.tools.todo.taskdefs.javac.DefaultCompilerAdapter;

/**
* The implementation of the javac compiler for JDK 1.3 This is primarily a
* cut-and-paste from the original javac task before it was refactored.
*
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com
* </a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/
public class Javac13 extends DefaultCompilerAdapter
{

/**
* Integer returned by the "Modern" jdk1.3 compiler to indicate success.
*/
private final static int MODERN_COMPILER_SUCCESS = 0;

public boolean execute()
throws TaskException
{
getTaskContext().debug( "Using modern compiler" );
ArgumentList cmd = setupModernJavacCommand();

// Use reflection to be able to build on all JDKs >= 1.1:
try
{
Class c = Class.forName( "com.sun.tools.javac.Main" );
Object compiler = c.newInstance();
Method compile = c.getMethod( "compile",
new Class[]{( new String[]{} ).getClass()} );
int result = ( (Integer)compile.invoke
( compiler, new Object[]{cmd.getArguments()} ) ).intValue();
return ( result == MODERN_COMPILER_SUCCESS );
}
catch( Exception ex )
{
if( ex instanceof TaskException )
{
throw (TaskException)ex;
}
else
{
throw new TaskException( "Error starting modern compiler", ex );
}
}
}
}

+ 0
- 42
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/JavacExternal.java View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.tools.todo.taskdefs.javac.DefaultCompilerAdapter;

/**
* Performs a compile using javac externally.
*
* @author Brian Deitte
*/
public class JavacExternal extends DefaultCompilerAdapter
{

/**
* Performs a compile using the Javac externally.
*
* @return Description of the Returned Value
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
public boolean execute()
throws TaskException
{
getTaskContext().debug( "Using external javac compiler" );

Commandline cmd = new Commandline();
cmd.setExecutable( getJavac().getJavacExecutable() );
setupModernJavacCommandlineSwitches( cmd );

return executeExternalCompile( cmd );
}

}


+ 0
- 134
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Jikes.java View File

@@ -1,134 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.myrmidon.framework.file.Path;
import org.apache.myrmidon.framework.file.FileListUtil;

/**
* The implementation of the jikes compiler. This is primarily a cut-and-paste
* from the original javac task before it was refactored.
*
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com
* </a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
* @author skanthak@muehlheim.de
*/
public class Jikes
extends DefaultCompilerAdapter
{

/**
* 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
*
* @return Description of the Returned Value
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
public boolean execute()
throws TaskException
{
getTaskContext().debug( "Using jikes compiler" );

Path classpath = new Path();

// Jikes doesn't support bootclasspath dir (-bootclasspath)
// so we'll emulate it for compatibility and convenience.
final String[] bootclasspath = m_bootclasspath.listFiles( getTaskContext() );
classpath.add( bootclasspath );

// Jikes doesn't support an extension dir (-extdir)
// so we'll emulate it for compatibility and convenience.
addExtdirs( classpath );

if( bootclasspath.length == 0 )
{
// no bootclasspath, therefore, get one from the java runtime
m_includeJavaRuntime = true;
}
// Else, there is a bootclasspath stated. By default, the
// includeJavaRuntime is false. If the user has stated a
// bootclasspath and said to include the java runtime, it's on
// their head!

addCompileClasspath( classpath );

// Jikes has no option for source-path so we
// will add it to classpath.
classpath.add( src );

// if the user has set JIKESPATH we should add the contents as well
String jikesPath = System.getProperty( "jikes.class.path" );
if( jikesPath != null )
{
classpath.add( jikesPath );
}

Commandline cmd = new Commandline();
cmd.setExecutable( "jikes" );

if( m_deprecation == true )
{
cmd.addArgument( "-deprecation" );
}

if( m_destDir != null )
{
cmd.addArgument( "-d" );
cmd.addArgument( m_destDir );
}

cmd.addArgument( "-classpath" );
cmd.addArgument( FileListUtil.formatPath( classpath, getTaskContext() ) );

if( m_encoding != null )
{
cmd.addArgument( "-encoding" );
cmd.addArgument( m_encoding );
}
if( m_debug )
{
cmd.addArgument( "-g" );
}
if( m_optimize )
{
cmd.addArgument( "-O" );
}
if( m_verbose )
{
cmd.addArgument( "-verbose" );
}
if( m_depend )
{
cmd.addArgument( "-depend" );
}

if( m_attributes.getNowarn() )
{
/*
* FIXME later
*
* let the magic property win over the attribute for backwards
* compatibility
*/
cmd.addArgument( "-nowarn" );
}

addCurrentCompilerArgs( cmd );

return executeExternalCompile( cmd );
}

}

+ 0
- 97
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Jvc.java View File

@@ -1,97 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.myrmidon.framework.file.Path;
import org.apache.myrmidon.framework.file.FileListUtil;

/**
* The implementation of the jvc compiler from microsoft. This is primarily a
* cut-and-paste from the original javac task before it was refactored.
*
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com
* </a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/
public class Jvc extends DefaultCompilerAdapter
{

public boolean execute()
throws TaskException
{
getTaskContext().debug( "Using jvc compiler" );

Path classpath = new Path();

// jvc doesn't support bootclasspath dir (-bootclasspath)
// so we'll emulate it for compatibility and convenience.
final String[] bootclasspath = m_bootclasspath.listFiles( getTaskContext() );
classpath.add( bootclasspath );

// jvc doesn't support an extension dir (-extdir)
// so we'll emulate it for compatibility and convenience.
addExtdirs( classpath );

if( bootclasspath.length == 0 )
{
// no bootclasspath, therefore, get one from the java runtime
m_includeJavaRuntime = true;
}
// Else, there is a bootclasspath stated. By default, the
// includeJavaRuntime is false. If the user has stated a
// bootclasspath and said to include the java runtime, it's on
// their head!

addCompileClasspath( classpath );

// jvc has no option for source-path so we
// will add it to classpath.
classpath.add( src );

Commandline cmd = new Commandline();
cmd.setExecutable( "jvc" );

if( m_destDir != null )
{
cmd.addArgument( "/d" );
cmd.addArgument( m_destDir );
}

// Add the Classpath before the "internal" one.
cmd.addArgument( "/cp:p" );
cmd.addArgument( FileListUtil.formatPath( classpath, getTaskContext() ) );

// Enable MS-Extensions and ...
cmd.addArgument( "/x-" );
// ... do not display a Message about this.
cmd.addArgument( "/nomessage" );
// Do not display Logo
cmd.addArgument( "/nologo" );

if( m_debug )
{
cmd.addArgument( "/g" );
}
if( m_optimize )
{
cmd.addArgument( "/O" );
}
if( m_verbose )
{
cmd.addArgument( "/verbose" );
}

addCurrentCompilerArgs( cmd );

return executeExternalCompile( cmd );
}
}

+ 0
- 135
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Kjc.java View File

@@ -1,135 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import java.lang.reflect.Method;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.myrmidon.framework.nativelib.ArgumentList;
import org.apache.myrmidon.framework.file.Path;
import org.apache.myrmidon.framework.file.FileListUtil;

/**
* The implementation of the Java compiler for KJC. This is primarily a
* cut-and-paste from Jikes.java and DefaultCompilerAdapter.
*
* @author <a href="mailto:tora@debian.org">Takashi Okamoto</a> +
*/
public class Kjc extends DefaultCompilerAdapter
{

public boolean execute()
throws TaskException
{
getTaskContext().debug( "Using kjc compiler" );
ArgumentList cmd = setupKjcCommand();

try
{
Class c = Class.forName( "at.dms.kjc.Main" );

// Call the compile() method
Method compile = c.getMethod( "compile",
new Class[]{String[].class} );
Boolean ok = (Boolean)compile.invoke( null,
new Object[]{cmd.getArguments()} );
return ok.booleanValue();
}
catch( ClassNotFoundException ex )
{
throw new TaskException( "Cannot use kjc compiler, as it is not available" +
" A common solution is to set the environment variable" +
" CLASSPATH to your kjc archive (kjc.jar)." );
}
catch( Exception ex )
{
if( ex instanceof TaskException )
{
throw (TaskException)ex;
}
else
{
throw new TaskException( "Error starting kjc compiler: ", ex );
}
}
}

/**
* setup kjc command arguments.
*
* @return Description of the Returned Value
*/
protected ArgumentList setupKjcCommand()
throws TaskException
{
ArgumentList cmd = new Commandline();

// generate classpath, because kjc does't support sourcepath.
Path classpath = new Path();
addCompileClasspath( classpath );

if( m_deprecation == true )
{
cmd.addArgument( "-deprecation" );
}

if( m_destDir != null )
{
cmd.addArgument( "-d" );
cmd.addArgument( m_destDir );
}

// generate the clsspath
cmd.addArgument( "-classpath" );

Path cp = new Path();

// kjc don't have bootclasspath option.
cp.add( m_bootclasspath );

if( m_extdirs != null )
{
addExtdirs( cp );
}

cp.add( classpath );
cp.add( src );

cmd.addArgument( FileListUtil.formatPath( cp, getTaskContext() ) );

// kjc-1.5A doesn't support -encoding option now.
// but it will be supported near the feature.
if( m_encoding != null )
{
cmd.addArgument( "-encoding" );
cmd.addArgument( m_encoding );
}

if( m_debug )
{
cmd.addArgument( "-g" );
}

if( m_optimize )
{
cmd.addArgument( "-O2" );
}

if( m_verbose )
{
cmd.addArgument( "-verbose" );
}

addCurrentCompilerArgs( cmd );

logFilesToCompile( cmd );
addFilesToCompile( cmd );
return cmd;
}
}


+ 0
- 44
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javac/Sj.java View File

@@ -1,44 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javac;

import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.tools.todo.taskdefs.javac.DefaultCompilerAdapter;

/**
* The implementation of the sj compiler. Uses the defaults for
* DefaultCompilerAdapter
*
* @author <a href="mailto:don@bea.com">Don Ferguson</a>
*/
public class Sj extends DefaultCompilerAdapter
{

/**
* Performs a compile using the sj compiler from Symantec.
*
* @return Description of the Returned Value
* @exception org.apache.myrmidon.api.TaskException Description of Exception
* @author don@bea.com
*/
public boolean execute()
throws TaskException
{
getTaskContext().debug( "Using symantec java compiler" );

Commandline cmd = new Commandline();
setupJavacCommandlineSwitches( cmd, false );
cmd.setExecutable( "sj" );

return executeExternalCompile( cmd );
}

}


+ 0
- 175
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javacc/JJTree.java View File

@@ -1,175 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javacc;

import java.io.File;
import java.util.Enumeration;
import java.util.Hashtable;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.java.ExecuteJava;
import org.apache.myrmidon.framework.file.Path;

/**
* Taskdef for the JJTree compiler compiler.
*
* @author thomas.haas@softwired-inc.com
* @author Michael Saunders <a href="mailto:michael@amtec.com">michael@amtec.com
* </a>
*/
public class JJTree
extends AbstractTask
{
// keys to optional attributes
private final static String BUILD_NODE_FILES = "BUILD_NODE_FILES";
private final static String MULTI = "MULTI";
private final static String NODE_DEFAULT_VOID = "NODE_DEFAULT_VOID";
private final static String NODE_FACTORY = "NODE_FACTORY";
private final static String NODE_SCOPE_HOOK = "NODE_SCOPE_HOOK";
private final static String NODE_USES_PARSER = "NODE_USES_PARSER";
private final static String STATIC = "STATIC";
private final static String VISITOR = "VISITOR";

private final static String NODE_PACKAGE = "NODE_PACKAGE";
private final static String VISITOR_EXCEPTION = "VISITOR_EXCEPTION";
private final static String NODE_PREFIX = "NODE_PREFIX";

private final Hashtable optionalAttrs = new Hashtable();

// required attributes
private File outputDirectory = null;
private File target = null;
private File javaccHome = null;

public void setBuildnodefiles( boolean buildNodeFiles )
{
optionalAttrs.put( BUILD_NODE_FILES, new Boolean( buildNodeFiles ) );
}

public void setJavacchome( File javaccHome )
{
this.javaccHome = javaccHome;
}

public void setMulti( boolean multi )
{
optionalAttrs.put( MULTI, new Boolean( multi ) );
}

public void setNodedefaultvoid( boolean nodeDefaultVoid )
{
optionalAttrs.put( NODE_DEFAULT_VOID, new Boolean( nodeDefaultVoid ) );
}

public void setNodefactory( boolean nodeFactory )
{
optionalAttrs.put( NODE_FACTORY, new Boolean( nodeFactory ) );
}

public void setNodepackage( String nodePackage )
{
optionalAttrs.put( NODE_PACKAGE, new String( nodePackage ) );
}

public void setNodeprefix( String nodePrefix )
{
optionalAttrs.put( NODE_PREFIX, new String( nodePrefix ) );
}

public void setNodescopehook( boolean nodeScopeHook )
{
optionalAttrs.put( NODE_SCOPE_HOOK, new Boolean( nodeScopeHook ) );
}

public void setNodeusesparser( boolean nodeUsesParser )
{
optionalAttrs.put( NODE_USES_PARSER, new Boolean( nodeUsesParser ) );
}

public void setOutputdirectory( File outputDirectory )
{
this.outputDirectory = outputDirectory;
}

public void setStatic( boolean staticParser )
{
optionalAttrs.put( STATIC, new Boolean( staticParser ) );
}

public void setTarget( File target )
{
this.target = target;
}

public void setVisitor( boolean visitor )
{
optionalAttrs.put( VISITOR, new Boolean( visitor ) );
}

public void setVisitorException( String visitorException )
{
optionalAttrs.put( VISITOR_EXCEPTION, new String( visitorException ) );
}

public void execute()
throws TaskException
{
final ExecuteJava exe = new ExecuteJava();
exe.setClassName( "COM.sun.labs.jjtree.Main" );

// load command line with optional attributes
Enumeration iter = optionalAttrs.keys();
while( iter.hasMoreElements() )
{
String name = (String)iter.nextElement();
Object value = optionalAttrs.get( name );
exe.getArguments().addArgument( "-" + name + ":" + value.toString() );
}

if( target == null || !target.isFile() )
{
throw new TaskException( "Invalid target: " + target );
}

// use the directory containing the target as the output directory
if( outputDirectory == null )
{
outputDirectory = target.getParentFile();
}
if( !outputDirectory.isDirectory() )
{
throw new TaskException( "'outputdirectory' " + outputDirectory + " is not a directory." );
}

// convert backslashes to slashes, otherwise jjtree will put this as
// comments and this seems to confuse javacc
exe.getArguments().addArgument( "-OUTPUT_DIRECTORY:" + outputDirectory.getAbsolutePath().replace( '\\', '/' ) );

String targetName = target.getName();
final File javaFile = new File( outputDirectory,
targetName.substring( 0, targetName.indexOf( ".jjt" ) ) + ".jj" );
if( javaFile.exists() && target.lastModified() < javaFile.lastModified() )
{
getContext().verbose( "Target is already built - skipping (" + target + ")" );
return;
}
exe.getArguments().addArgument( target );

if( javaccHome == null || !javaccHome.isDirectory() )
{
throw new TaskException( "Javacchome not set." );
}
final Path classpath = exe.getClassPath();
classpath.addLocation( new File( javaccHome, "JavaCC.zip" ) );

exe.setMaxMemory( "140M" );
exe.getSysProperties().addVariable( "install.root", javaccHome.getAbsolutePath() );

exe.executeForked( getContext() );
}
}

+ 0
- 269
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javacc/JavaCC.java View File

@@ -1,269 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javacc;

import java.io.File;
import java.util.Enumeration;
import java.util.Hashtable;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.java.ExecuteJava;
import org.apache.myrmidon.framework.file.Path;

/**
* Taskdef for the JavaCC compiler compiler.
*
* @author thomas.haas@softwired-inc.com
* @author Michael Saunders <a href="mailto:michael@amtec.com">michael@amtec.com
* </a>
*/
public class JavaCC
extends AbstractTask
{

// keys to optional attributes
private final static String LOOKAHEAD = "LOOKAHEAD";
private final static String CHOICE_AMBIGUITY_CHECK = "CHOICE_AMBIGUITY_CHECK";
private final static String OTHER_AMBIGUITY_CHECK = "OTHER_AMBIGUITY_CHECK";

private final static String STATIC = "STATIC";
private final static String DEBUG_PARSER = "DEBUG_PARSER";
private final static String DEBUG_LOOKAHEAD = "DEBUG_LOOKAHEAD";
private final static String DEBUG_TOKEN_MANAGER = "DEBUG_TOKEN_MANAGER";
private final static String OPTIMIZE_TOKEN_MANAGER = "OPTIMIZE_TOKEN_MANAGER";
private final static String ERROR_REPORTING = "ERROR_REPORTING";
private final static String JAVA_UNICODE_ESCAPE = "JAVA_UNICODE_ESCAPE";
private final static String UNICODE_INPUT = "UNICODE_INPUT";
private final static String IGNORE_CASE = "IGNORE_CASE";
private final static String COMMON_TOKEN_ACTION = "COMMON_TOKEN_ACTION";
private final static String USER_TOKEN_MANAGER = "USER_TOKEN_MANAGER";
private final static String USER_CHAR_STREAM = "USER_CHAR_STREAM";
private final static String BUILD_PARSER = "BUILD_PARSER";
private final static String BUILD_TOKEN_MANAGER = "BUILD_TOKEN_MANAGER";
private final static String SANITY_CHECK = "SANITY_CHECK";
private final static String FORCE_LA_CHECK = "FORCE_LA_CHECK";
private final static String CACHE_TOKENS = "CACHE_TOKENS";

private final Hashtable optionalAttrs = new Hashtable();

// required attributes
private File outputDirectory = null;
private File target = null;
private File javaccHome = null;

public void setBuildparser( boolean buildParser )
{
optionalAttrs.put( BUILD_PARSER, new Boolean( buildParser ) );
}

public void setBuildtokenmanager( boolean buildTokenManager )
{
optionalAttrs.put( BUILD_TOKEN_MANAGER, new Boolean( buildTokenManager ) );
}

public void setCachetokens( boolean cacheTokens )
{
optionalAttrs.put( CACHE_TOKENS, new Boolean( cacheTokens ) );
}

public void setChoiceambiguitycheck( int choiceAmbiguityCheck )
{
optionalAttrs.put( CHOICE_AMBIGUITY_CHECK, new Integer( choiceAmbiguityCheck ) );
}

public void setCommontokenaction( boolean commonTokenAction )
{
optionalAttrs.put( COMMON_TOKEN_ACTION, new Boolean( commonTokenAction ) );
}

public void setDebuglookahead( boolean debugLookahead )
{
optionalAttrs.put( DEBUG_LOOKAHEAD, new Boolean( debugLookahead ) );
}

public void setDebugparser( boolean debugParser )
{
optionalAttrs.put( DEBUG_PARSER, new Boolean( debugParser ) );
}

public void setDebugtokenmanager( boolean debugTokenManager )
{
optionalAttrs.put( DEBUG_TOKEN_MANAGER, new Boolean( debugTokenManager ) );
}

public void setErrorreporting( boolean errorReporting )
{
optionalAttrs.put( ERROR_REPORTING, new Boolean( errorReporting ) );
}

public void setForcelacheck( boolean forceLACheck )
{
optionalAttrs.put( FORCE_LA_CHECK, new Boolean( forceLACheck ) );
}

public void setIgnorecase( boolean ignoreCase )
{
optionalAttrs.put( IGNORE_CASE, new Boolean( ignoreCase ) );
}

public void setJavacchome( File javaccHome )
{
this.javaccHome = javaccHome;
}

public void setJavaunicodeescape( boolean javaUnicodeEscape )
{
optionalAttrs.put( JAVA_UNICODE_ESCAPE, new Boolean( javaUnicodeEscape ) );
}

public void setLookahead( int lookahead )
{
optionalAttrs.put( LOOKAHEAD, new Integer( lookahead ) );
}

public void setOptimizetokenmanager( boolean optimizeTokenManager )
{
optionalAttrs.put( OPTIMIZE_TOKEN_MANAGER, new Boolean( optimizeTokenManager ) );
}

public void setOtherambiguityCheck( int otherAmbiguityCheck )
{
optionalAttrs.put( OTHER_AMBIGUITY_CHECK, new Integer( otherAmbiguityCheck ) );
}

public void setOutputdirectory( File outputDirectory )
{
this.outputDirectory = outputDirectory;
}

public void setSanitycheck( boolean sanityCheck )
{
optionalAttrs.put( SANITY_CHECK, new Boolean( sanityCheck ) );
}

public void setStatic( boolean staticParser )
{
optionalAttrs.put( STATIC, new Boolean( staticParser ) );
}

public void setTarget( File target )
{
this.target = target;
}

public void setUnicodeinput( boolean unicodeInput )
{
optionalAttrs.put( UNICODE_INPUT, new Boolean( unicodeInput ) );
}

public void setUsercharstream( boolean userCharStream )
{
optionalAttrs.put( USER_CHAR_STREAM, new Boolean( userCharStream ) );
}

public void setUsertokenmanager( boolean userTokenManager )
{
optionalAttrs.put( USER_TOKEN_MANAGER, new Boolean( userTokenManager ) );
}

public void execute()
throws TaskException
{
// check the target is a file
if( target == null || !target.isFile() )
{
throw new TaskException( "Invalid target: " + target );
}

// use the directory containing the target as the output directory
if( outputDirectory == null )
{
outputDirectory = target.getParentFile();
}
if( !outputDirectory.isDirectory() )
{
throw new TaskException( "Outputdir not a directory." );
}

if( javaccHome == null || !javaccHome.isDirectory() )
{
throw new TaskException( "Javacchome not set." );
}

// determine if the generated java file is up-to-date
final File javaFile = getOutputJavaFile( outputDirectory, target );
if( javaFile.exists() && target.lastModified() < javaFile.lastModified() )
{
getContext().debug( "Target is already built - skipping (" + target + ")" );
return;
}

ExecuteJava exe = new ExecuteJava();
exe.setClassName( "COM.sun.labs.javacc.Main" );

// load command line with optional attributes
Enumeration iter = optionalAttrs.keys();
while( iter.hasMoreElements() )
{
String name = (String)iter.nextElement();
Object value = optionalAttrs.get( name );
exe.getArguments().addArgument( "-" + name + ":" + value.toString() );
}

exe.getArguments().addArgument( "-OUTPUT_DIRECTORY:" + outputDirectory.getAbsolutePath() );

exe.getArguments().addArgument( target );

final Path classpath = exe.getClassPath();
classpath.addLocation( new File( javaccHome, "JavaCC.zip" ) );

exe.setMaxMemory( "140M" );
exe.getSysProperties().addVariable( "install.root", javaccHome.getAbsolutePath() );

exe.executeForked( getContext() );
}

/**
* Determines the output Java file to be generated by the given grammar
* file.
*
* @param outputdir Description of Parameter
* @param srcfile Description of Parameter
* @return The OutputJavaFile value
*/
private File getOutputJavaFile( File outputdir, File srcfile )
{
String path = srcfile.getPath();

// Extract file's base-name
int startBasename = path.lastIndexOf( File.separator );
if( startBasename != -1 )
{
path = path.substring( startBasename + 1 );
}

// Replace the file's extension with '.java'
int startExtn = path.lastIndexOf( '.' );
if( startExtn != -1 )
{
path = path.substring( 0, startExtn ) + ".java";
}
else
{
path += ".java";
}

// Change the directory
if( outputdir != null )
{
path = outputdir + File.separator + path;
}

return new File( path );
}
}

+ 0
- 21
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/AccessType.java View File

@@ -1,21 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javadoc;

import org.apache.tools.todo.types.EnumeratedAttribute;

public class AccessType
extends EnumeratedAttribute
{
public String[] getValues()
{
// Protected first so if any GUI tool offers a default
// based on enum #0, it will be right.
return new String[]{"protected", "public", "package", "private"};
}
}

+ 0
- 73
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/DocletInfo.java View File

@@ -1,73 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javadoc;

import java.util.ArrayList;
import java.util.Iterator;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.file.Path;

public class DocletInfo
{
private ArrayList m_params = new ArrayList();
private String m_name;
private Path m_path;

public void setName( final String name )
{
m_name = name;
}

public void setPath( final Path path )
throws TaskException
{
if( m_path == null )
{
m_path = path;
}
else
{
m_path.add( path );
}
}

public String getName()
{
return m_name;
}

public Iterator getParams()
{
return m_params.iterator();
}

public Path getPath()
{
return m_path;
}

public DocletParam createParam()
{
final DocletParam param = new DocletParam();
m_params.add( param );
return param;
}

public Path createPath()
throws TaskException
{
if( m_path == null )
{
m_path = new Path();
}
Path path1 = m_path;
final Path path = new Path();
path1.add( path );
return path;
}
}

+ 0
- 34
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/DocletParam.java View File

@@ -1,34 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javadoc;

public class DocletParam
{
private String m_name;
private String m_value;

public void setName( final String name )
{
this.m_name = name;
}

public void setValue( final String value )
{
this.m_value = value;
}

public String getName()
{
return m_name;
}

public String getValue()
{
return m_value;
}
}

+ 0
- 65
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/GroupArgument.java View File

@@ -1,65 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javadoc;

import java.util.ArrayList;
import java.util.StringTokenizer;

public class GroupArgument
{
private ArrayList m_packages = new ArrayList( 3 );
private Html m_title;

public void setPackages( final String src )
{
final StringTokenizer tok = new StringTokenizer( src, "," );
while( tok.hasMoreTokens() )
{
final String p = tok.nextToken();
final PackageName pn = new PackageName();
pn.setName( p );
addPackage( pn );
}
}

public void setTitle( final String src )
{
final Html h = new Html();
h.addContent( src );
addTitle( h );
}

public String getPackages()
{
final StringBuffer p = new StringBuffer();
for( int i = 0; i < m_packages.size(); i++ )
{
if( i > 0 )
{
p.append( ":" );
}
p.append( m_packages.get( i ).toString() );
}
return p.toString();
}

public String getTitle()
{
return m_title != null ? m_title.getText() : null;
}

public void addPackage( final PackageName pn )
{
m_packages.add( pn );
}

public void addTitle( final Html text )
{
m_title = text;
}
}

+ 0
- 23
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/Html.java View File

@@ -1,23 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javadoc;

public class Html
{
private StringBuffer m_text = new StringBuffer();

public String getText()
{
return m_text.toString();
}

public void addContent( final String text )
{
m_text.append( text );
}
}

+ 0
- 1020
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/Javadoc.java
File diff suppressed because it is too large
View File


+ 0
- 47
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/LinkArgument.java View File

@@ -1,47 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javadoc;

import java.io.File;

public class LinkArgument
{
private boolean m_offline;
private String m_href;
private File m_packagelistLoc;

public void setHref( String hr )
{
m_href = hr;
}

public void setOffline( boolean offline )
{
this.m_offline = offline;
}

public void setPackagelistLoc( File src )
{
m_packagelistLoc = src;
}

public String getHref()
{
return m_href;
}

public File getPackagelistLoc()
{
return m_packagelistLoc;
}

public boolean isLinkOffline()
{
return m_offline;
}
}

+ 0
- 28
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/PackageName.java View File

@@ -1,28 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javadoc;

public class PackageName
{
private String m_name;

public void setName( final String name )
{
m_name = name;
}

public String getName()
{
return m_name;
}

public String toString()
{
return getName();
}
}

+ 0
- 25
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/javadoc/SourceFile.java View File

@@ -1,25 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.javadoc;

import java.io.File;

public class SourceFile
{
private File m_file;

public void setFile( File file )
{
this.m_file = file;
}

public File getFile()
{
return m_file;
}
}

+ 0
- 21
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jdepend/FormatAttribute.java View File

@@ -1,21 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.jdepend;

import org.apache.tools.todo.types.EnumeratedAttribute;

public class FormatAttribute
extends EnumeratedAttribute
{
private String[] m_formats = new String[]{"xml", "text"};

public String[] getValues()
{
return m_formats;
}
}

+ 0
- 261
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jdepend/JDependTask.java View File

@@ -1,261 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.jdepend;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.java.ExecuteJava;
import org.apache.myrmidon.framework.file.Path;

/**
* Ant task to run JDepend tests. <p>
*
* JDepend is a tool to generate design quality metrics for each Java package.
* It has been initially created by Mike Clark. JDepend can be found at <a
* href="http://www.clarkware.com/software/JDepend.html">
* http://www.clarkware.com/software/JDepend.html</a> . The current
* implementation spawn a new Java VM.
*
* @author <a href="mailto:Jerome@jeromelacoste.com">Jerome Lacoste</a>
* @author <a href="mailto:roxspring@yahoo.com">Rob Oxspring</a>
*/
public class JDependTask
extends AbstractTask
{
private boolean m_fork;
private String m_jvm;
private String m_format = "text";
private Path m_compileClasspath = new Path();
private File m_dir;
private File m_outputFile;
private Path m_sourcesPath;

/**
* Set the classpath to be used for this compilation.
*/
public void setClasspath( final Path classpath )
throws TaskException
{
addClasspath( classpath );
}

/**
* The directory to invoke the VM in. Ignored if no JVM is forked.
*
* @param dir the directory to invoke the JVM from.
* @see #setFork(boolean)
*/
public void setDir( final File dir )
{
m_dir = dir;
}

/**
* Tells whether a JVM should be forked for the task. Default: false.
*
* @param fork <tt>true</tt> if a JVM should be forked, otherwise <tt>false
* <tt>
*/
public void setFork( final boolean fork )
{
m_fork = fork;
}

public void setFormat( final FormatAttribute format )
{
m_format = format.getValue();
}

/**
* Set a new VM to execute the task. Default is <tt>java</tt> . Ignored if
* no JVM is forked.
*
* @param jvm the new VM to use instead of <tt>java</tt>
* @see #setFork(boolean)
*/
public void setJvm( final String jvm )
{
m_jvm = jvm;
}

/*
* public void setTimeout(Integer value) {
* _timeout = value;
* }
* public Integer getTimeout() {
* return _timeout;
* }
*/
public void setOutputFile( final File outputFile )
{
m_outputFile = outputFile;
}

/**
* Adds a nested classpath element.
*/
public void addClasspath( final Path path )
{
m_compileClasspath.add( path );
}

/**
* Maybe creates a nested classpath element.
*/
public Path createSourcespath()
{
if( m_sourcesPath == null )
{
m_sourcesPath = new Path();
}
Path path1 = m_sourcesPath;
final Path path = new Path();
path1.add( path );
return path;
}

public void execute()
throws TaskException
{
if( m_sourcesPath == null )
{
throw new TaskException( "Missing Sourcepath required argument" );
}

// execute the test and get the return code
if( !m_fork )
{
executeInVM();
}
else
{
executeAsForked();
}
}


/**
* Execute the task by forking a new JVM. The command will block until it
* finishes. To know if the process was destroyed or not, use the <tt>
* killedProcess()</tt> method of the watchdog class.
*/
// JL: comment extracted from JUnitTask (and slightly modified)
private void executeAsForked()
throws TaskException
{
final ExecuteJava exe = new ExecuteJava();
exe.setWorkingDirectory( m_dir );

if( "text".equals( m_format ) )
{
exe.setClassName( "jdepend.textui.JDepend" );
}
else
{
exe.setClassName( "jdepend.xmlui.JDepend" );
}

if( m_jvm != null )
{
exe.setJvm( m_jvm );
}

exe.getClassPath().add( m_compileClasspath );

if( m_outputFile != null )
{
// having a space between the file and its path causes commandline to add quotes "
// around the argument thus making JDepend not taking it into account. Thus we split it in two
exe.getArguments().addArgument( "-file" );
exe.getArguments().addArgument( m_outputFile );
getContext().info( "Output to be stored in " + m_outputFile.getPath() );
}

final String[] elements = m_sourcesPath.listFiles( getContext() );
for( int i = 0; i < elements.length; i++ )
{
File f = new File( elements[ i ] );

// not necessary as JDepend would fail, but why loose some time?
if( !f.exists() || !f.isDirectory() )
{
throw new TaskException( "\"" + f.getPath() + "\" does not represent a valid directory. JDepend would fail." );
}
exe.getArguments().addArgument( f );
}

exe.executeForked( getContext() );
}


// this comment extract from JUnit Task may also apply here
// "in VM is not very nice since it could probably hang the
// whole build. IMHO this method should be avoided and it would be best
// to remove it in future versions. TBD. (SBa)"

/**
* Execute inside VM.
*/
private void executeInVM()
throws TaskException
{
jdepend.textui.JDepend jdepend;

if( "xml".equals( m_format ) )
{
jdepend = new jdepend.xmlui.JDepend();
}
else
{
jdepend = new jdepend.textui.JDepend();
}

if( m_outputFile != null )
{
FileWriter fw;
try
{
fw = new FileWriter( m_outputFile.getPath() );
}
catch( IOException e )
{
String msg = "JDepend Failed when creating the output file: " + e.getMessage();
throw new TaskException( msg );
}
jdepend.setWriter( new PrintWriter( fw ) );
getContext().info( "Output to be stored in " + m_outputFile.getPath() );
}

final String[] elements = m_sourcesPath.listFiles( getContext() );
for( int i = 0; i < elements.length; i++ )
{
File f = new File( elements[ i ] );

// not necessary as JDepend would fail, but why loose some time?
if( !f.exists() || !f.isDirectory() )
{
String msg = "\"" + f.getPath() + "\" does not represent a valid directory. JDepend would fail.";
throw new TaskException( msg );
}
try
{
jdepend.addDirectory( f.getPath() );
}
catch( IOException e )
{
String msg = "JDepend Failed when adding a source directory: " + e.getMessage();
throw new TaskException( msg );
}
}
jdepend.analyze();
}
}

+ 0
- 484
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/JspC.java View File

@@ -1,484 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.jsp;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.todo.taskdefs.MatchingTask;
import org.apache.tools.todo.taskdefs.jsp.compilers.CompilerAdapter;
import org.apache.tools.todo.taskdefs.jsp.compilers.CompilerAdapterFactory;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.myrmidon.framework.file.Path;

/**
* Ant task to run the jsp compiler. <p>
*
* This task takes the given jsp files and compiles them into java files. It is
* then up to the user to compile the java files into classes. <p>
*
* The task requires the srcdir and destdir attributes to be set. This Task is a
* MatchingTask, so the files to be compiled can be specified using
* includes/excludes attributes or nested include/exclude elements. Optional
* attributes are verbose (set the verbosity level passed to jasper), package
* (name of the destination package for generated java classes and classpath
* (the classpath to use when running the jsp compiler). <p>
*
* This task supports the nested elements classpath (A Path) and classpathref (A
* Reference) which can be used in preference to the attribute classpath, if the
* jsp compiler is not already in the ant classpath. <p>
*
* <h4>Notes</h4> <p>
*
* At present, this task only supports the jasper compiler. In future, other
* compilers will be supported by setting the jsp.compiler property. <p>
*
* <h4>Usage</h4> <pre>
* &lt;jspc srcdir="${basedir}/src/war"
* destdir="${basedir}/gensrc"
* package="com.i3sp.jsp"
* verbose="9"&gt;
* &lt;include name="**\/*.jsp" /&gt;
* &lt;/jspc&gt;
* </pre>
*
* @author <a href="mailto:mattw@i3sp.com">Matthew Watson</a> <p>
*
* Large Amount of cutting and pasting from the Javac task...
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com
* </a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
* @version $Revision$ $Date$
*/
public class JspC extends MatchingTask
{

private final static String FAIL_MSG
= "Compile failed, messages should have been provided.";
private int verbose = 0;
protected ArrayList compileList = new ArrayList();
protected boolean failOnError = true;
/*
* ------------------------------------------------------------
*/
private Path classpath;
private File destDir;
private String iepluginid;
private boolean mapped;
private String packageName;
private Path src;

/**
* -uribase <dir>The uri directory compilations should be relative to
* (Default is "/")
*/

private File uribase;

/**
* -uriroot <dir>The root directory that uri files should be resolved
* against,
*/
private File uriroot;


/*
* ------------------------------------------------------------
*/
/**
* Set the classpath to be used for this compilation
*
* @param cp The new Classpath value
*/
public void setClasspath( Path cp )
throws TaskException
{
if( classpath == null )
{
classpath = cp;
}
else
{
classpath.add( cp );
}
}

/**
* Set the destination directory into which the JSP source files should be
* compiled.
*
* @param destDir The new Destdir value
*/
public void setDestdir( File destDir )
{
this.destDir = destDir;
}

/*
* ------------------------------------------------------------
*/
/**
* Throw a TaskException if compilation fails
*
* @param fail The new Failonerror value
*/
public void setFailonerror( boolean fail )
{
failOnError = fail;
}

/**
* Set the ieplugin id
*
* @param iepluginid_ The new Ieplugin value
*/
public void setIeplugin( String iepluginid_ )
{
iepluginid = iepluginid_;
}

/**
* set the mapped flag
*
* @param mapped_ The new Mapped value
*/
public void setMapped( boolean mapped_ )
{
mapped = mapped_;
}

/*
* ------------------------------------------------------------
*/
/**
* Set the name of the package the compiled jsp files should be in
*
* @param pkg The new Package value
*/
public void setPackage( String pkg )
{
this.packageName = pkg;
}

/*
* ------------------------------------------------------------
*/
/**
* Set the source dirs to find the source JSP files.
*
* @param srcDir The new Srcdir value
*/
public void setSrcdir( Path srcDir )
throws TaskException
{
if( src == null )
{
src = srcDir;
}
else
{
src.add( srcDir );
}
}

/**
* -uribase. the uri context of relative URI references in the JSP pages. If
* it does not exist then it is derived from the location of the file
* relative to the declared or derived value of -uriroot.
*
* @param uribase The new Uribase value
*/
public void setUribase( File uribase )
{
this.uribase = uribase;
}

/**
* -uriroot <dir>The root directory that uri files should be resolved
* against, (Default is the directory jspc is invoked from)
*
* @param uriroot The new Uribase value
*/
public void setUriroot( File uriroot )
{
this.uriroot = uriroot;
}

/*
* ------------------------------------------------------------
*/
/**
* Set the verbose level of the compiler
*
* @param i The new Verbose value
*/
public void setVerbose( int i )
{
verbose = i;
}

public Path getClasspath()
{
return classpath;
}

/*
* ------------------------------------------------------------
*/
public ArrayList getCompileList()
{
return compileList;
}

public File getDestdir()
{
return destDir;
}

/**
* Gets the failonerror flag.
*
* @return The Failonerror value
*/
public boolean getFailonerror()
{
return failOnError;
}

/*
* ------------------------------------------------------------
*/
public String getIeplugin()
{
return iepluginid;
}

public String getPackage()
{
return packageName;
}

public Path getSrcDir()
{
return src;
}

public File getUribase()
{
return uriroot;
}

public File getUriroot()
{
return uriroot;
}

public int getVerbose()
{
return verbose;
}

/*
* ------------------------------------------------------------
*/
public boolean isMapped()
{
return mapped;
}

/**
* Maybe creates a nested classpath element.
*
* @return Description of the Returned Value
*/
public Path createClasspath()
throws TaskException
{
if( classpath == null )
{
classpath = new Path();
}
Path path1 = classpath;
final Path path = new Path();
path1.add( path );
return path;
}

/*
* ------------------------------------------------------------
*/
public void execute()
throws TaskException
{
// first off, make sure that we've got a srcdir
if( src == null )
{
throw new TaskException( "srcdir attribute must be set!" );
}
String[] list = src.listFiles( getContext() );
if( list.length == 0 )
{
throw new TaskException( "srcdir attribute must be set!" );
}

if( destDir != null && !destDir.isDirectory() )
{
throw new
TaskException( "destination directory \"" + destDir +
"\" does not exist or is not a directory" );
}

// calculate where the files will end up:
File dest = null;
if( packageName == null )
{
dest = destDir;
}
else
{
String path = destDir.getPath() + File.separatorChar +
packageName.replace( '.', File.separatorChar );
dest = new File( path );
}

// scan source directories and dest directory to build up both copy
// lists and compile lists
resetFileLists();
int filecount = 0;
for( int i = 0; i < list.length; i++ )
{
final String filename = list[ i ];
File srcDir = (File)getContext().resolveFile( filename );
if( !srcDir.exists() )
{
throw new TaskException( "srcdir \"" + srcDir.getPath() +
"\" does not exist!" );
}

DirectoryScanner ds = this.getDirectoryScanner( srcDir );

String[] files = ds.getIncludedFiles();
filecount = files.length;
scanDir( srcDir, dest, files );
}

// compile the source files

Object compiler = getContext().getProperty( "jsp.compiler" );
if( compiler == null )
{
compiler = "jasper";
}
getContext().debug( "compiling " + compileList.size() + " files" );

if( compileList.size() > 0 )
{
CompilerAdapter adapter =
CompilerAdapterFactory.getCompiler( compiler.toString(), getContext() );
getContext().info( "Compiling " + compileList.size() +
" source file"
+ ( compileList.size() == 1 ? "" : "s" )
+ ( destDir != null ? " to " + destDir : "" ) );

// now we need to populate the compiler adapter
adapter.setJspc( this );

// finally, lets execute the compiler!!
if( !adapter.execute() )
{
if( failOnError )
{
throw new TaskException( FAIL_MSG );
}
else
{
getContext().error( FAIL_MSG );
}
}
}
else
{
if( filecount == 0 )
{
getContext().verbose( "there were no files to compile" );
}
else
{
getContext().verbose( "all files are up to date" );
}
}
}

/*
* ------------------------------------------------------------
*/
/**
* Clear the list of files to be compiled and copied..
*/
protected void resetFileLists()
{
compileList.clear();
}

/*
* ------------------------------------------------------------
*/
/**
* Scans the directory looking for source files to be compiled. The results
* are returned in the class variable compileList
*
* @param srcDir Description of Parameter
* @param destDir Description of Parameter
* @param files Description of Parameter
*/
protected void scanDir( File srcDir, File destDir, String files[] )
{

long now = ( new Date() ).getTime();

for( int i = 0; i < files.length; i++ )
{
File srcFile = new File( srcDir, files[ i ] );
if( files[ i ].endsWith( ".jsp" ) )
{
// drop leading path (if any)
int fileStart =
files[ i ].lastIndexOf( File.separatorChar ) + 1;
File javaFile = new File( destDir, files[ i ].substring( fileStart,
files[ i ].indexOf( ".jsp" ) ) + ".java" );

if( srcFile.lastModified() > now )
{
final String message =
"Warning: file modified in the future: " + files[ i ];
getContext().warn( message );
}

if( !javaFile.exists() ||
srcFile.lastModified() > javaFile.lastModified() )
{
if( !javaFile.exists() )
{
getContext().debug( "Compiling " + srcFile.getPath() + " because java file " + javaFile.getPath() + " does not exist" );
}
else
{
getContext().debug( "Compiling " + srcFile.getPath() + " because it is out of date with respect to " + javaFile.getPath() );
}
compileList.add( srcFile.getAbsolutePath() );
}
}
}
}
/*
* ------------------------------------------------------------
*/
}

+ 0
- 294
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/WLJspc.java View File

@@ -1,294 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.jsp;//java imports

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.StringTokenizer;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.java.ExecuteJava;
import org.apache.tools.todo.taskdefs.MatchingTask;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.myrmidon.framework.file.Path;
import org.apache.myrmidon.framework.file.FileListUtil;

/**
* Class to precompile JSP's using weblogic's jsp compiler (weblogic.jspc)
*
* @author <a href="mailto:avik@aviksengupta.com">Avik Sengupta</a>
* http://www.webteksoftware.com Tested only on Weblogic 4.5.1 - NT4.0 and
* Solaris 5.7 required attributes src : root of source tree for JSP, ie,
* the document root for your weblogic server dest : root of destination
* directory, what you have set as WorkingDir in the weblogic properties
* package : start package name under which your JSP's would be compiled
* other attributes classpath A classpath should be set which contains the
* weblogic classes as well as all application classes referenced by the
* JSP. The system classpath is also appended when the jspc is called, so
* you may choose to put everything in the classpath while calling Ant.
* However, since presumably the JSP's will reference classes being build
* by Ant, it would be better to explicitly add the classpath in the task
* The task checks timestamps on the JSP's and the generated classes, and
* compiles only those files that have changed. It follows the weblogic
* naming convention of putting classes in <b> _dirName/_fileName.class for
* dirname/fileName.jsp </b> Limitation: It compiles the files thru the
* Classic compiler only. Limitation: Since it is my experience that
* weblogic jspc throws out of memory error on being given too many files
* at one go, it is called multiple times with one jsp file each. <pre>
* example
* &lt;target name="jspcompile" depends="compile"&gt;
* &lt;wljspc src="c:\\weblogic\\myserver\\public_html" dest="c:\\weblogic\\myserver\\serverclasses" package="myapp.jsp"&gt;
* &lt;classpath&gt;
* &lt;pathelement location="${weblogic.classpath}" /&gt;
* &lt;pathelement path="${compile.dest}" /&gt;
* &lt;/classpath&gt;
*
* &lt;/wljspc&gt;
* &lt;/target&gt;
* </pre>
*/

public class WLJspc extends MatchingTask
{//classpath used to compile the jsp files.
//private String compilerPath; //fully qualified name for the compiler executable

private String pathToPackage = "";
private ArrayList filesToDo = new ArrayList();//package under which resultant classes will reside
private Path compileClasspath;
//TODO Test on other versions of weblogic
//TODO add more attributes to the task, to take care of all jspc options
//TODO Test on Unix

private File destinationDirectory;// root of source files tree
private String destinationPackage;//root of compiled files tree
private File sourceDirectory;

/**
* Set the classpath to be used for this compilation.
*
* @param classpath The new Classpath value
*/
public void setClasspath( Path classpath )
throws TaskException
{
if( compileClasspath == null )
{
compileClasspath = classpath;
}
else
{
compileClasspath.add( classpath );
}
}

/**
* Set the directory containing the source jsp's
*
* @param dirName the directory containg the source jsp's
*/
public void setDest( File dirName )
{
destinationDirectory = dirName;
}

/**
* Set the package under which the compiled classes go
*
* @param packageName the package name for the clases
*/
public void setPackage( String packageName )
{

destinationPackage = packageName;
}

/**
* Set the directory containing the source jsp's
*
* @param dirName the directory containg the source jsp's
*/
public void setSrc( File dirName )
{

sourceDirectory = dirName;
}

/**
* Maybe creates a nested classpath element.
*
* @return Description of the Returned Value
*/
public Path createClasspath()
{
if( compileClasspath == null )
{
compileClasspath = new Path();
}
return compileClasspath;
}

public void execute()
throws TaskException
{
if( !destinationDirectory.isDirectory() )
{
throw new TaskException( "destination directory " + destinationDirectory.getPath() +
" is not valid" );
}

if( !sourceDirectory.isDirectory() )
{
throw new TaskException( "src directory " + sourceDirectory.getPath() +
" is not valid" );
}

if( destinationPackage == null )
{
throw new TaskException( "package attribute must be present." );
}

pathToPackage = this.destinationPackage.replace( '.', File.separatorChar );
// get all the files in the sourceDirectory
DirectoryScanner ds = super.getDirectoryScanner( sourceDirectory );

//use the systemclasspath as well, to include the ant jar
if( compileClasspath == null )
{
compileClasspath = new Path();
}

// TODO - make sure tools.jar ends up in the classpath
//compileClasspath.append( Path.systemClasspath );

String[] files = ds.getIncludedFiles();

//Weblogic.jspc calls System.exit() ... have to fork
// Therefore, takes loads of time
// Can pass directories at a time (*.jsp) but easily runs out of memory on hefty dirs
// (even on a Sun)
String[] args = new String[ 12 ];

File jspFile = null;
String parents = "";
int j = 0;
//XXX this array stuff is a remnant of prev trials.. gotta remove.
args[ j++ ] = "-d";
args[ j++ ] = destinationDirectory.getAbsolutePath().trim();
args[ j++ ] = "-docroot";
args[ j++ ] = sourceDirectory.getAbsolutePath().trim();
args[ j++ ] = "-keepgenerated";//TODO: Parameterise ??
//Call compiler as class... dont want to fork again
//Use classic compiler -- can be parameterised?
args[ j++ ] = "-compilerclass";
args[ j++ ] = "sun.tools.javac.Main";
//Weblogic jspc does not seem to work unless u explicitly set this...
// Does not take the classpath from the env....
// Am i missing something about the Java task??
args[ j++ ] = "-classpath";
args[ j++ ] = FileListUtil.formatPath( compileClasspath, getContext() );

this.scanDir( files );
getContext().info( "Compiling " + filesToDo.size() + " JSP files" );

for( int i = 0; i < filesToDo.size(); i++ )
{
//XXX
// All this to get package according to weblogic standards
// Can be written better... this is too hacky!
// Careful.. similar code in scanDir , but slightly different!!
jspFile = new File( (String)filesToDo.get( i ) );
args[ j ] = "-package";
parents = jspFile.getParent();
if( ( parents != null ) && ( !( "" ).equals( parents ) ) )
{
parents = this.replaceString( parents, File.separator, "_." );
args[ j + 1 ] = destinationPackage + "." + "_" + parents;
}
else
{
args[ j + 1 ] = destinationPackage;
}

args[ j + 2 ] = sourceDirectory + File.separator + (String)filesToDo.get( i );

ExecuteJava helperTask = new ExecuteJava();
helperTask.setClassName( "weblogic.jspc" );
helperTask.getArguments().addArguments( args );
helperTask.getClassPath().add( compileClasspath );
helperTask.executeForked( getContext() );
}
}

protected String replaceString( String inpString, String escapeChars, String replaceChars )
{
String localString = "";
int numTokens = 0;
StringTokenizer st = new StringTokenizer( inpString, escapeChars, true );
numTokens = st.countTokens();
for( int i = 0; i < numTokens; i++ )
{
String test = st.nextToken();
test = ( test.equals( escapeChars ) ? replaceChars : test );
localString += test;
}
return localString;
}

protected void scanDir( String files[] )
{

long now = ( new Date() ).getTime();
File jspFile = null;
String parents = null;
String pack = "";
for( int i = 0; i < files.length; i++ )
{
File srcFile = new File( this.sourceDirectory, files[ i ] );
//XXX
// All this to convert source to destination directory according to weblogic standards
// Can be written better... this is too hacky!
jspFile = new File( files[ i ] );
parents = jspFile.getParent();

if( ( parents != null ) && ( !( "" ).equals( parents ) ) )
{
parents = this.replaceString( parents, File.separator, "_/" );
pack = pathToPackage + File.separator + "_" + parents;
}
else
{
pack = pathToPackage;
}

String filePath = pack + File.separator + "_";
int startingIndex
= files[ i ].lastIndexOf( File.separator ) != -1 ? files[ i ].lastIndexOf( File.separator ) + 1 : 0;
int endingIndex = files[ i ].indexOf( ".jsp" );
if( endingIndex == -1 )
{
break;
}

filePath += files[ i ].substring( startingIndex, endingIndex );
filePath += ".class";
File classFile = new File( this.destinationDirectory, filePath );

if( srcFile.lastModified() > now )
{
final String message = "Warning: file modified in the future: " + files[ i ];
getContext().warn( message );
}
if( srcFile.lastModified() > classFile.lastModified() )
{
//log("Files are" + srcFile.getAbsolutePath()+" " +classFile.getAbsolutePath());
filesToDo.add( files[ i ] );
getContext().debug( "Recompiling File " + files[ i ] );
}
}
}
}

+ 0
- 46
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/compilers/CompilerAdapter.java View File

@@ -1,46 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.jsp.compilers;

import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.TaskContext;
import org.apache.tools.todo.taskdefs.jsp.JspC;

/**
* The interface that all jsp compiler adapters must adher to. <p>
*
* A compiler adapter is an adapter that interprets the jspc's parameters in
* preperation to be passed off to the compier this adapter represents. As all
* the necessary values are stored in the Jspc task itself, the only thing all
* adapters need is the jsp task, the execute command and a parameterless
* constructor (for reflection).</p>
*
* @author Jay Dickon Glanville <a href="mailto:jayglanville@home.com">
* jayglanville@home.com</a>
* @author Matthew Watson <a href="mailto:mattw@i3sp.com">mattw@i3sp.com</a>
*/
public interface CompilerAdapter
{
void setTaskContext( TaskContext context );

/**
* Sets the compiler attributes, which are stored in the Jspc task.
*
* @param attributes The new Jspc value
*/
void setJspc( JspC attributes );

/**
* Executes the task.
*
* @return has the compilation been successful
* @exception TaskException Description of Exception
*/
boolean execute()
throws TaskException;
}

+ 0
- 103
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/compilers/CompilerAdapterFactory.java View File

@@ -1,103 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.jsp.compilers;

import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.TaskContext;

/**
* Creates the necessary compiler adapter, given basic criteria.
*
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
* @author Matthew Watson <a href="mailto:mattw@i3sp.com">mattw@i3sp.com</a>
*/
public class CompilerAdapterFactory
{
/**
* This is a singlton -- can't create instances!!
*/
private CompilerAdapterFactory()
{
}

/**
* Based on the parameter passed in, this method creates the necessary
* factory desired. The current mapping for compiler names are as follows:
*
* <ul>
* <li> jasper = jasper compiler (the default)
* <li> <i>a fully quallified classname</i> = the name of a jsp compiler
* adapter
* </ul>
*
*
* @param compilerType either the name of the desired compiler, or the full
* classname of the compiler's adapter.
* @return The Compiler value
* @throws TaskException if the compiler type could not be resolved into a
* compiler adapter.
*/
public static CompilerAdapter getCompiler( String compilerType, TaskContext context )
throws TaskException
{
final CompilerAdapter adapter = createAdapter( compilerType );
adapter.setTaskContext( context );
return adapter;
}

private static CompilerAdapter createAdapter( String compilerType )
throws TaskException
{
/*
* If I've done things right, this should be the extent of the
* conditional statements required.
*/
if( compilerType.equalsIgnoreCase( "jasper" ) )
{
return new JasperC();
}
return resolveClassName( compilerType );
}

/**
* Tries to resolve the given classname into a compiler adapter. Throws a
* fit if it can't.
*
* @param className The fully qualified classname to be created.
* @return Description of the Returned Value
* @throws TaskException This is the fit that is thrown if className isn't
* an instance of CompilerAdapter.
*/
private static CompilerAdapter resolveClassName( String className )
throws TaskException
{
try
{
Class c = Class.forName( className );
Object o = c.newInstance();
return (CompilerAdapter)o;
}
catch( ClassNotFoundException cnfe )
{
throw new TaskException( className + " can\'t be found.", cnfe );
}
catch( ClassCastException cce )
{
throw new TaskException( className + " isn\'t the classname of "
+ "a compiler adapter.", cce );
}
catch( Throwable t )
{
// for all other possibilities
throw new TaskException( className + " caused an interesting "
+ "exception.", t );
}
}

}

+ 0
- 91
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/compilers/DefaultCompilerAdapter.java View File

@@ -1,91 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.jsp.compilers;

import java.util.ArrayList;
import java.util.Iterator;
import org.apache.avalon.excalibur.util.StringUtil;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.todo.taskdefs.jsp.JspC;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.myrmidon.framework.nativelib.ArgumentList;
import org.apache.tools.todo.util.FileUtils;

/**
* This is the default implementation for the CompilerAdapter interface. This is
* currently very light on the ground since only one compiler type is supported.
*
* @author Matthew Watson <a href="mailto:mattw@i3sp.com">mattw@i3sp.com</a>
*/
public abstract class DefaultCompilerAdapter
implements CompilerAdapter
{
private JspC m_attributes;
private TaskContext m_taskContext;

public void setTaskContext( final TaskContext context )
{
m_taskContext = context;
}

protected final TaskContext getTaskContext()
{
return m_taskContext;
}

public void setJspc( final JspC attributes )
{
this.m_attributes = attributes;
}

public JspC getJspc()
{
return m_attributes;
}

/*
* ------------------------------------------------------------
*/
/**
* Logs the compilation parameters, adds the files to compile and logs the
* &qout;niceSourceList&quot;
*
* @param jspc Description of Parameter
* @param compileList Description of Parameter
* @param cmd Description of Parameter
*/
protected void logAndAddFilesToCompile( JspC jspc,
ArrayList compileList,
ArgumentList cmd )
throws TaskException
{
final String[] args = cmd.getArguments();
getTaskContext().debug( "Compilation args: " + FileUtils.formatCommandLine( args ) );

StringBuffer niceSourceList = new StringBuffer( "File" );
if( compileList.size() != 1 )
{
niceSourceList.append( "s" );
}
niceSourceList.append( " to be compiled:" );

niceSourceList.append( StringUtil.LINE_SEPARATOR );

Iterator enum = compileList.iterator();
while( enum.hasNext() )
{
String arg = (String)enum.next();
cmd.addArgument( arg );
niceSourceList.append( " " + arg + StringUtil.LINE_SEPARATOR );
}

getTaskContext().debug( niceSourceList.toString() );
}
}


+ 0
- 90
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/jsp/compilers/JasperC.java View File

@@ -1,90 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.jsp.compilers;

import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.java.ExecuteJava;
import org.apache.tools.todo.taskdefs.jsp.JspC;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.myrmidon.framework.nativelib.ArgumentList;

/**
* The implementation of the jasper compiler. This is a cut-and-paste of the
* original Jspc task.
*
* @author Matthew Watson <a href="mailto:mattw@i3sp.com">mattw@i3sp.com</a>
*/
public class JasperC
extends DefaultCompilerAdapter
{
/*
* ------------------------------------------------------------
*/
public boolean execute()
throws TaskException
{
getTaskContext().debug( "Using jasper compiler" );

final ExecuteJava exe = new ExecuteJava();
exe.setClassName( "org.apache.jasper.JspC" );
if( getJspc().getClasspath() != null )
{
exe.getClassPath().add( getJspc().getClasspath() );
}

setupJasperCommand( exe.getArguments() );

// Create an instance of the compiler, redirecting output to
// the project log
exe.execute( getTaskContext() );
return true;
}

/*
* ------------------------------------------------------------
*/
private void setupJasperCommand( final ArgumentList cmd )
throws TaskException
{
JspC jspc = getJspc();
if( jspc.getDestdir() != null )
{
cmd.addArgument( "-d" );
cmd.addArgument( jspc.getDestdir() );
}
if( jspc.getPackage() != null )
{
cmd.addArgument( "-p" );
cmd.addArgument( jspc.getPackage() );
}
if( jspc.getVerbose() != 0 )
{
cmd.addArgument( "-v" + jspc.getVerbose() );
}
if( jspc.isMapped() )
{
cmd.addArgument( "-mapped" );
}
if( jspc.getIeplugin() != null )
{
cmd.addArgument( "-ieplugin" );
cmd.addArgument( jspc.getIeplugin() );
}
if( jspc.getUriroot() != null )
{
cmd.addArgument( "-uriroot" );
cmd.addArgument( jspc.getUriroot().toString() );
}
if( jspc.getUribase() != null )
{
cmd.addArgument( "-uribase" );
cmd.addArgument( jspc.getUribase().toString() );
}
logAndAddFilesToCompile( getJspc(), getJspc().getCompileList(), cmd );
}
}

+ 0
- 230
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/AggregateTransformer.java View File

@@ -1,230 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.todo.types.EnumeratedAttribute;
import org.w3c.dom.Document;

/**
* Transform a JUnit xml report. The default transformation generates an html
* report in either framed or non-framed style. The non-framed style is
* convenient to have a concise report via mail, the framed report is much more
* convenient if you want to browse into different packages or testcases since
* it is a Javadoc like report.
*
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
*/
public class AggregateTransformer
{
public final static String FRAMES = "frames";

public final static String NOFRAMES = "noframes";

/**
* XML Parser factory
*/
private final static DocumentBuilderFactory c_dbfactory = DocumentBuilderFactory.newInstance();

/**
* the xml document to process
*/
private Document m_document;

/**
* the format to use for the report. Must be <tt>FRAMES</tt> or <tt>NOFRAMES
* </tt>
*/
private String m_format;

/**
* the style directory. XSLs should be read from here if necessary
*/
private File m_styleDir;

private TaskContext m_context;

/**
* the destination directory, this is the root from where html should be
* generated
*/
private File m_toDir;

public AggregateTransformer( TaskContext context )
{
m_context = context;
}

public void setFormat( Format format )
{
m_format = format.getValue();
}

/**
* set the style directory. It is optional and will override the default xsl
* used.
*
* @param styledir the directory containing the xsl files if the user would
* like to override with its own style.
*/
public void setStyledir( File styledir )
{
m_styleDir = styledir;
}

/**
* set the destination directory
*
* @param todir The new Todir value
*/
public void setTodir( File todir )
{
m_toDir = todir;
}

public void setXmlDocument( Document doc )
{
m_document = doc;
}

public void transform()
throws TaskException
{
checkOptions();
try
{
XalanExecutor executor = XalanExecutor.newInstance( this );
executor.execute();
}
catch( Exception e )
{
throw new TaskException( "Errors while applying transformations", e );
}
//task.getLogger().info( "Transform time: " + dt + "ms" );
}

/**
* Set the xml file to be processed. This is a helper if you want to set the
* file directly. Much more for testing purposes.
*
* @param xmlfile xml file to be processed
* @exception TaskException Description of Exception
*/
protected void setXmlfile( File xmlfile )
throws TaskException
{
try
{
DocumentBuilder builder = c_dbfactory.newDocumentBuilder();
InputStream in = new FileInputStream( xmlfile );
try
{
Document doc = builder.parse( in );
setXmlDocument( doc );
}
finally
{
in.close();
}
}
catch( Exception e )
{
throw new TaskException( "Error while parsing document: " + xmlfile, e );
}
}

/**
* Get the systemid of the appropriate stylesheet based on its name and
* styledir. If no styledir is defined it will load it as a java resource in
* the xsl child package, otherwise it will get it from the given directory.
*
* @return The StylesheetSystemId value
* @throws IOException thrown if the requested stylesheet does not exist.
*/
protected String getStylesheetSystemId()
throws IOException
{
String xslname = "junit-frames.xsl";
if( NOFRAMES.equals( m_format ) )
{
xslname = "junit-noframes.xsl";
}
URL url = null;
if( m_styleDir == null )
{
url = getClass().getResource( "xsl/" + xslname );
if( url == null )
{
throw new FileNotFoundException( "Could not find jar resource " + xslname );
}
}
else
{
File file = new File( m_styleDir, xslname );
if( !file.exists() )
{
throw new FileNotFoundException( "Could not find file '" + file + "'" );
}
url = new URL( "file", "", file.getAbsolutePath() );
}
return url.toExternalForm();
}

/**
* check for invalid options
*
* @exception TaskException Description of Exception
*/
protected void checkOptions()
throws TaskException
{
// set the destination directory relative from the project if needed.
if( m_toDir == null )
{
m_toDir = FileUtil.resolveFile( m_context.getBaseDirectory(), "." );
}
else if( !m_toDir.isAbsolute() )
{
m_toDir = FileUtil.resolveFile( m_context.getBaseDirectory(), m_toDir.getPath() );
}
}

protected Document getDocument()
{
return m_document;
}

protected String getFormat()
{
return m_format;
}

protected File getToDir()
{
return m_toDir;
}

public static class Format extends EnumeratedAttribute
{
public String[] getValues()
{
return new String[]{FRAMES, NOFRAMES};
}
}

}

+ 0
- 133
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/BaseTest.java View File

@@ -1,133 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.File;
import java.util.ArrayList;

/**
* Baseclass for BatchTest and JUnitTest.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a>
*/
public abstract class BaseTest
{
protected boolean m_haltOnError = false;
protected boolean m_haltOnFail = false;
protected boolean m_filtertrace = true;
protected boolean fork = false;
protected String ifProperty = null;
protected String unlessProperty = null;
protected ArrayList formatters = new ArrayList();
/**
* destination directory
*/
protected File destDir = null;
protected String errorProperty;

protected String failureProperty;

public void setErrorProperty( String errorProperty )
{
this.errorProperty = errorProperty;
}

public void setFailureProperty( String failureProperty )
{
this.failureProperty = failureProperty;
}

public void setFiltertrace( boolean value )
{
m_filtertrace = value;
}

public void setFork( boolean value )
{
fork = value;
}

public void setHaltonerror( boolean value )
{
m_haltOnError = value;
}

public void setHaltonfailure( boolean value )
{
m_haltOnFail = value;
}

public void setIf( String propertyName )
{
ifProperty = propertyName;
}

/**
* Sets the destination directory.
*
* @param destDir The new Todir value
*/
public void setTodir( File destDir )
{
this.destDir = destDir;
}

public void setUnless( String propertyName )
{
unlessProperty = propertyName;
}

public java.lang.String getErrorProperty()
{
return errorProperty;
}

public java.lang.String getFailureProperty()
{
return failureProperty;
}

public boolean getFiltertrace()
{
return m_filtertrace;
}

public boolean getFork()
{
return fork;
}

public boolean getHaltonerror()
{
return m_haltOnError;
}

public boolean getHaltonfailure()
{
return m_haltOnFail;
}

/**
* @return the destination directory as an absolute path if it exists
* otherwise return <tt>null</tt>
*/
public String getTodir()
{
if( destDir != null )
{
return destDir.getAbsolutePath();
}
return null;
}

public void addFormatter( FormatterElement elem )
{
formatters.add( elem );
}
}

+ 0
- 187
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/BatchTest.java View File

@@ -1,187 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.FileSet;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.tools.todo.types.ScannerUtil;

/**
* <p>
*
* Create then run <code>JUnitTest</code>'s based on the list of files given by
* the fileset attribute. <p>
*
* Every <code>.java</code> or <code>.class</code> file in the fileset is
* assumed to be a testcase. A <code>JUnitTest</code> is created for each of
* these named classes with basic setup inherited from the parent <code>BatchTest</code>
* .
*
* @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a>
* @see JUnitTest
*/
public final class BatchTest extends BaseTest
{
/**
* the list of filesets containing the testcase filename rules
*/
private ArrayList filesets = new ArrayList();

/**
* Convenient method to convert a pathname without extension to a fully
* qualified classname. For example <tt>org/apache/Whatever</tt> will be
* converted to <tt>org.apache.Whatever</tt>
*
* @param filename the filename to "convert" to a classname.
* @return the classname matching the filename.
*/
public static final String javaToClass( String filename )
{
return filename.replace( File.separatorChar, '.' );
}

/**
* Return all <tt>JUnitTest</tt> instances obtain by applying the fileset
* rules.
*
* @return an enumeration of all elements of this batchtest that are a <tt>
* JUnitTest</tt> instance.
*/
public final Iterator iterator()
throws TaskException
{
final JUnitTest[] tests = createAllJUnitTest();
return Arrays.asList( tests ).iterator();
}

/**
* Add a new fileset instance to this batchtest. Whatever the fileset is,
* only filename that are <tt>.java</tt> or <tt>.class</tt> will be
* considered as 'candidates'.
*
* @param fs the new fileset containing the rules to get the testcases.
*/
public void addFileSet( FileSet fs )
{
filesets.add( fs );
}

/**
* Convenient method to merge the <tt>JUnitTest</tt> s of this batchtest to
* a <tt>ArrayList</tt> .
*
* @param v the vector to which should be added all individual tests of this
* batch test.
*/
final void addTestsTo( ArrayList v )
throws TaskException
{
final JUnitTest[] tests = createAllJUnitTest();
v.ensureCapacity( v.size() + tests.length );
for( int i = 0; i < tests.length; i++ )
{
v.add( tests[ i ] );
}
}

/**
* Iterate over all filesets and return the filename of all files that end
* with <tt>.java</tt> or <tt>.class</tt> . This is to avoid wrapping a <tt>
* JUnitTest</tt> over an xml file for example. A Testcase is obviously a
* java file (compiled or not).
*
* @return an array of filenames without their extension. As they should
* normally be taken from their root, filenames should match their
* fully qualified class name (If it is not the case it will fail when
* running the test). For the class <tt>org/apache/Whatever.class</tt>
* it will return <tt>org/apache/Whatever</tt> .
*/
private String[] getFilenames()
throws TaskException
{
ArrayList v = new ArrayList();
final int size = this.filesets.size();
for( int j = 0; j < size; j++ )
{
FileSet fs = (FileSet)filesets.get( j );
DirectoryScanner ds = ScannerUtil.getDirectoryScanner( fs );
ds.scan();
String[] f = ds.getIncludedFiles();
for( int k = 0; k < f.length; k++ )
{
String pathname = f[ k ];
if( pathname.endsWith( ".java" ) )
{
v.add( pathname.substring( 0, pathname.length() - ".java".length() ) );
}
else if( pathname.endsWith( ".class" ) )
{
v.add( pathname.substring( 0, pathname.length() - ".class".length() ) );
}
}
}

return (String[])v.toArray( new String[ v.size() ] );
}

/**
* Create all <tt>JUnitTest</tt> s based on the filesets. Each instance is
* configured to match this instance properties.
*
* @return the array of all <tt>JUnitTest</tt> s that belongs to this batch.
*/
private JUnitTest[] createAllJUnitTest()
throws TaskException
{
String[] filenames = getFilenames();
JUnitTest[] tests = new JUnitTest[ filenames.length ];
for( int i = 0; i < tests.length; i++ )
{
String classname = javaToClass( filenames[ i ] );
tests[ i ] = createJUnitTest( classname );
}
return tests;
}

/**
* Create a <tt>JUnitTest</tt> that has the same property as this <tt>
* BatchTest</tt> instance.
*
* @param classname the name of the class that should be run as a <tt>
* JUnitTest</tt> . It must be a fully qualified name.
* @return the <tt>JUnitTest</tt> over the given classname.
*/
private JUnitTest createJUnitTest( String classname )
{
JUnitTest test = new JUnitTest();
test.setName( classname );
test.setHaltonerror( this.m_haltOnError );
test.setHaltonfailure( this.m_haltOnFail );
test.setFiltertrace( this.m_filtertrace );
test.setFork( this.fork );
test.setIf( this.ifProperty );
test.setUnless( this.unlessProperty );
test.setTodir( this.destDir );
test.setFailureProperty( failureProperty );
test.setErrorProperty( errorProperty );
Iterator list = this.formatters.iterator();
while( list.hasNext() )
{
test.addFormatter( (FormatterElement)list.next() );
}
return test;
}

}

+ 0
- 272
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/BriefJUnitResultFormatter.java View File

@@ -1,272 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import junit.framework.AssertionFailedError;
import junit.framework.Test;
import org.apache.avalon.excalibur.util.StringUtil;
import org.apache.myrmidon.api.TaskException;

/**
* Prints plain text output of the test to a specified Writer. Inspired by the
* PlainJUnitResultFormatter.
*
* @author <a href="mailto:robertdw@bigpond.net.au">Robert Watkins</a>
* @see FormatterElement
* @see PlainJUnitResultFormatter
*/
public class BriefJUnitResultFormatter implements JUnitResultFormatter
{

/**
* Formatter for timings.
*/
private java.text.NumberFormat m_numberFormat = java.text.NumberFormat.getInstance();

/**
* Output suite has written to System.out
*/
private String systemOutput = null;

/**
* Output suite has written to System.err
*/
private String systemError = null;

/**
* Where to write the log to.
*/
private java.io.OutputStream m_out;

/**
* Used for writing the results.
*/
private java.io.PrintWriter m_output;

/**
* Used for writing formatted results to.
*/
private java.io.PrintWriter m_resultWriter;

/**
* Used as part of formatting the results.
*/
private java.io.StringWriter m_results;

public BriefJUnitResultFormatter()
{
m_results = new java.io.StringWriter();
m_resultWriter = new java.io.PrintWriter( m_results );
}

/**
* Sets the stream the formatter is supposed to write its results to.
*
* @param out The new Output value
*/
public void setOutput( java.io.OutputStream out )
{
m_out = out;
m_output = new java.io.PrintWriter( out );
}

public void setSystemError( String err )
{
systemError = err;
}

public void setSystemOutput( String out )
{
systemOutput = out;
}

/**
* A test caused an error.
*
* @param test The feature to be added to the Error attribute
* @param error The feature to be added to the Error attribute
*/
public void addError( Test test, Throwable error )
{
formatError( "\tCaused an ERROR", test, error );
}

/**
* Interface TestListener for JUnit &lt;= 3.4. <p>
*
* A Test failed.
*
* @param test The feature to be added to the Failure attribute
* @param t The feature to be added to the Failure attribute
*/
public void addFailure( Test test, Throwable t )
{
formatError( "\tFAILED", test, t );
}

/**
* Interface TestListener for JUnit &gt; 3.4. <p>
*
* A Test failed.
*
* @param test The feature to be added to the Failure attribute
* @param t The feature to be added to the Failure attribute
*/
public void addFailure( Test test, AssertionFailedError t )
{
addFailure( test, (Throwable)t );
}

/**
* A test ended.
*
* @param test Description of Parameter
*/
public void endTest( Test test )
{
}

/**
* The whole testsuite ended.
*
* @param suite Description of Parameter
* @exception TaskException Description of Exception
*/
public void endTestSuite( JUnitTest suite )
throws TaskException
{
final StringBuffer sb = new StringBuffer( "Testsuite: " );
sb.append( suite.getName() );
sb.append( StringUtil.LINE_SEPARATOR );
sb.append( "Tests run: " );
sb.append( suite.runCount() );
sb.append( ", Failures: " );
sb.append( suite.failureCount() );
sb.append( ", Errors: " );
sb.append( suite.errorCount() );
sb.append( ", Time elapsed: " );
sb.append( m_numberFormat.format( suite.getRunTime() / 1000.0 ) );
sb.append( " sec" );
sb.append( StringUtil.LINE_SEPARATOR );
sb.append( StringUtil.LINE_SEPARATOR );

// append the err and output streams to the log
if( systemOutput != null && systemOutput.length() > 0 )
{
sb.append( "------------- Standard Output ---------------" )
.append( StringUtil.LINE_SEPARATOR )
.append( systemOutput )
.append( "------------- ---------------- ---------------" )
.append( StringUtil.LINE_SEPARATOR );
}

if( systemError != null && systemError.length() > 0 )
{
sb.append( "------------- Standard Error -----------------" )
.append( StringUtil.LINE_SEPARATOR )
.append( systemError )
.append( "------------- ---------------- ---------------" )
.append( StringUtil.LINE_SEPARATOR );
}

if( output() != null )
{
try
{
output().write( sb.toString() );
resultWriter().close();
output().write( m_results.toString() );
output().flush();
}
finally
{
if( m_out != (Object)System.out &&
m_out != (Object)System.err )
{
try
{
m_out.close();
}
catch( java.io.IOException e )
{
}
}
}
}
}

/**
* A test started.
*
* @param test Description of Parameter
*/
public void startTest( Test test )
{
}

/**
* The whole testsuite started.
*
* @param suite Description of Parameter
* @exception TaskException Description of Exception
*/
public void startTestSuite( JUnitTest suite )
throws TaskException
{
}

/**
* Format an error and print it.
*
* @param type Description of Parameter
* @param test Description of Parameter
* @param error Description of Parameter
*/
protected synchronized void formatError( String type, Test test,
Throwable error )
{
if( test != null )
{
endTest( test );
}

resultWriter().println( formatTest( test ) + type );
resultWriter().println( error.getMessage() );
String strace = JUnitTestRunner.getFilteredTrace( error );
resultWriter().println( strace );
resultWriter().println( "" );
}

/**
* Format the test for printing..
*
* @param test Description of Parameter
* @return Description of the Returned Value
*/
protected String formatTest( Test test )
{
if( test == null )
{
return "Null Test: ";
}
else
{
return "Testcase: " + test.toString() + ":";
}
}

protected java.io.PrintWriter output()
{
return m_output;
}

protected java.io.PrintWriter resultWriter()
{
return m_resultWriter;
}
}

+ 0
- 100
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/CompoundIterator.java View File

@@ -1,100 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
* Convenient enumeration over an array of enumeration. For example: <pre>
* Iterator e1 = v1.iterator();
* while (e1.hasNext()){
* // do something
* }
* Iterator e2 = v2.iterator();
* while (e2.hasNext()){
* // do the same thing
* }
* </pre> can be written as: <pre>
* Iterator[] enums = { v1.iterator(), v2.iterator() };
* Iterator e = Iterators.fromCompound(enums);
* while (e.hasNext()){
* // do something
* }
* </pre> Note that the enumeration will skip null elements in the array. The
* following is thus possible: <pre>
* Iterator[] enums = { v1.iterator(), null, v2.iterator() }; // a null enumeration in the array
* Iterator e = Iterators.fromCompound(enums);
* while (e.hasNext()){
* // do something
* }
* </pre>
*
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a>
*/
class CompoundIterator
implements Iterator
{
/**
* index in the enums array
*/
private int index = 0;

/**
* enumeration array
*/
private Iterator[] enumArray;

public CompoundIterator( Iterator[] enumarray )
{
this.enumArray = enumarray;
}

/**
* Tests if this enumeration contains more elements.
*
* @return <code>true</code> if and only if this enumeration object contains
* at least one more element to provide; <code>false</code> otherwise.
*/
public boolean hasNext()
{
while( index < enumArray.length )
{
if( enumArray[ index ] != null && enumArray[ index ].hasNext() )
{
return true;
}
index++;
}
return false;
}

/**
* Returns the next element of this enumeration if this enumeration object
* has at least one more element to provide.
*
* @return the next element of this enumeration.
* @throws NoSuchElementException if no more elements exist.
*/
public Object next()
throws NoSuchElementException
{
if( hasNext() )
{
return enumArray[ index ].next();
}
throw new NoSuchElementException();
}

public void remove()
throws UnsupportedOperationException
{
throw new UnsupportedOperationException();
}
}


+ 0
- 239
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/DOMElementWriter.java View File

@@ -1,239 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.IOException;
import java.io.Writer;
import org.apache.avalon.excalibur.util.StringUtil;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
* Writes a DOM tree to a given Writer. <p>
*
* Utility class used by {@link org.apache.tools.ant.XmlLogger XmlLogger} and
* org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter
* XMLJUnitResultFormatter}.</p>
*
* @author The original author of XmlLogger
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</tt>
*/
public class DOMElementWriter
{
private StringBuffer sb = new StringBuffer();

/**
* Don't try to be too smart but at least recognize the predefined entities.
*/
protected String[] knownEntities = {"gt", "amp", "lt", "apos", "quot"};

/**
* Is the given argument a character or entity reference?
*
* @param ent Description of Parameter
* @return The Reference value
*/
public boolean isReference( String ent )
{
if( !( ent.charAt( 0 ) == '&' ) || !ent.endsWith( ";" ) )
{
return false;
}

if( ent.charAt( 1 ) == '#' )
{
if( ent.charAt( 2 ) == 'x' )
{
try
{
Integer.parseInt( ent.substring( 3, ent.length() - 1 ), 16 );
return true;
}
catch( NumberFormatException nfe )
{
return false;
}
}
else
{
try
{
Integer.parseInt( ent.substring( 2, ent.length() - 1 ) );
return true;
}
catch( NumberFormatException nfe )
{
return false;
}
}
}

String name = ent.substring( 1, ent.length() - 1 );
for( int i = 0; i < knownEntities.length; i++ )
{
if( name.equals( knownEntities[ i ] ) )
{
return true;
}
}
return false;
}

/**
* Escape &lt;, &gt; &amp; &apos; and &quot; as their entities.
*
* @param value Description of Parameter
* @return Description of the Returned Value
*/
public String encode( String value )
{
sb.setLength( 0 );
for( int i = 0; i < value.length(); i++ )
{
char c = value.charAt( i );
switch( c )
{
case '<':
sb.append( "&lt;" );
break;
case '>':
sb.append( "&gt;" );
break;
case '\'':
sb.append( "&apos;" );
break;
case '\"':
sb.append( "&quot;" );
break;
case '&':
int nextSemi = value.indexOf( ";", i );
if( nextSemi < 0
|| !isReference( value.substring( i, nextSemi + 1 ) ) )
{
sb.append( "&amp;" );
}
else
{
sb.append( '&' );
}
break;
default:
sb.append( c );
break;
}
}
return sb.toString();
}

/**
* Writes a DOM tree to a stream.
*
* @param element the Root DOM element of the tree
* @param out where to send the output
* @param indent number of
* @param indentWith strings, that should be used to indent the
* corresponding tag.
* @exception IOException Description of Exception
*/
public void write( Element element, Writer out, int indent,
String indentWith )
throws IOException
{

// Write indent characters
for( int i = 0; i < indent; i++ )
{
out.write( indentWith );
}

// Write element
out.write( "<" );
out.write( element.getTagName() );

// Write attributes
NamedNodeMap attrs = element.getAttributes();
for( int i = 0; i < attrs.getLength(); i++ )
{
Attr attr = (Attr)attrs.item( i );
out.write( " " );
out.write( attr.getName() );
out.write( "=\"" );
out.write( encode( attr.getValue() ) );
out.write( "\"" );
}
out.write( ">" );

// Write child elements and text
boolean hasChildren = false;
NodeList children = element.getChildNodes();
for( int i = 0; i < children.getLength(); i++ )
{
Node child = children.item( i );

switch( child.getNodeType() )
{

case Node.ELEMENT_NODE:
if( !hasChildren )
{
out.write( StringUtil.LINE_SEPARATOR );
hasChildren = true;
}
write( (Element)child, out, indent + 1, indentWith );
break;
case Node.TEXT_NODE:
out.write( encode( child.getNodeValue() ) );
break;
case Node.CDATA_SECTION_NODE:
out.write( "<![CDATA[" );
out.write( ( (Text)child ).getData() );
out.write( "]]>" );
break;
case Node.ENTITY_REFERENCE_NODE:
out.write( '&' );
out.write( child.getNodeName() );
out.write( ';' );
break;
case Node.PROCESSING_INSTRUCTION_NODE:
out.write( "<?" );
out.write( child.getNodeName() );
String data = child.getNodeValue();
if( data != null && data.length() > 0 )
{
out.write( ' ' );
out.write( data );
}
out.write( "?>" );
break;
}
}

// If we had child elements, we need to indent before we close
// the element, otherwise we're on the same line and don't need
// to indent
if( hasChildren )
{
for( int i = 0; i < indent; i++ )
{
out.write( indentWith );
}
}

// Write element close
out.write( "</" );
out.write( element.getTagName() );
out.write( ">" );
out.write( StringUtil.LINE_SEPARATOR );
out.flush();
}
}

+ 0
- 226
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/DOMUtil.java View File

@@ -1,226 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;

/**
* Some utilities that might be useful when manipulating DOM trees.
*
* @author <a href="bailliez@noos.fr">Stephane Bailliez</a>
*/
public final class DOMUtil
{

/**
* unused constructor
*/
private DOMUtil()
{
}

/**
* Iterate over the children of a given node and return the first node that
* has a specific name.
*
* @param parent the node to search child from. Can be <tt>null</tt> .
* @param tagname the child name we are looking for. Cannot be <tt>null</tt>
* .
* @return the first child that matches the given name or <tt>null</tt> if
* the parent is <tt>null</tt> or if a child does not match the given
* name.
*/
public static Element getChildByTagName( Node parent, String tagname )
{
if( parent == null )
{
return null;
}
NodeList childList = parent.getChildNodes();
final int len = childList.getLength();
for( int i = 0; i < len; i++ )
{
Node child = childList.item( i );
if( child != null && child.getNodeType() == Node.ELEMENT_NODE &&
child.getNodeName().equals( tagname ) )
{
return (Element)child;
}
}
return null;
}

/**
* return the attribute value of an element.
*
* @param node the node to get the attribute from.
* @param name the name of the attribute we are looking for the value.
* @return the value of the requested attribute or <tt>null</tt> if the
* attribute was not found or if <tt>node</tt> is not an <tt>Element
* </tt>.
*/
public static String getNodeAttribute( Node node, String name )
{
if( node instanceof Element )
{
Element element = (Element)node;
return element.getAttribute( name );
}
return null;
}

/**
* Simple tree walker that will clone recursively a node. This is to avoid
* using parser-specific API such as Sun's <tt>changeNodeOwner</tt> when we
* are dealing with DOM L1 implementations since <tt>cloneNode(boolean)</tt>
* will not change the owner document. <tt>changeNodeOwner</tt> is much
* faster and avoid the costly cloning process. <tt>importNode</tt> is in
* the DOM L2 interface.
*
* @param parent the node parent to which we should do the import to.
* @param child the node to clone recursively. Its clone will be appended to
* <tt>parent</tt> .
* @return the cloned node that is appended to <tt>parent</tt>
*/
public static final Node importNode( Node parent, Node child )
{
Node copy = null;
final Document doc = parent.getOwnerDocument();

switch( child.getNodeType() )
{
case Node.CDATA_SECTION_NODE:
copy = doc.createCDATASection( ( (CDATASection)child ).getData() );
break;
case Node.COMMENT_NODE:
copy = doc.createComment( ( (Comment)child ).getData() );
break;
case Node.DOCUMENT_FRAGMENT_NODE:
copy = doc.createDocumentFragment();
break;
case Node.ELEMENT_NODE:
final Element elem = doc.createElement( ( (Element)child ).getTagName() );
copy = elem;
final NamedNodeMap attributes = child.getAttributes();
if( attributes != null )
{
final int size = attributes.getLength();
for( int i = 0; i < size; i++ )
{
final Attr attr = (Attr)attributes.item( i );
elem.setAttribute( attr.getName(), attr.getValue() );
}
}
break;
case Node.ENTITY_REFERENCE_NODE:
copy = doc.createEntityReference( child.getNodeName() );
break;
case Node.PROCESSING_INSTRUCTION_NODE:
final ProcessingInstruction pi = (ProcessingInstruction)child;
copy = doc.createProcessingInstruction( pi.getTarget(), pi.getData() );
break;
case Node.TEXT_NODE:
copy = doc.createTextNode( ( (Text)child ).getData() );
break;
default:
// this should never happen
throw new IllegalStateException( "Invalid node type: " + child.getNodeType() );
}

// okay we have a copy of the child, now the child becomes the parent
// and we are iterating recursively over its children.
try
{
final NodeList children = child.getChildNodes();
if( children != null )
{
final int size = children.getLength();
for( int i = 0; i < size; i++ )
{
final Node newChild = children.item( i );
if( newChild != null )
{
importNode( copy, newChild );
}
}
}
}
catch( DOMException ignored )
{
}

// bingo append it. (this should normally not be done here)
parent.appendChild( copy );
return copy;
}

/**
* list a set of node that match a specific filter. The list can be made
* recursively or not.
*
* @param parent the parent node to search from
* @param filter the filter that children should match.
* @param recurse <tt>true</tt> if you want the list to be made recursively
* otherwise <tt>false</tt> .
* @return Description of the Returned Value
*/
public static NodeList listChildNodes( Node parent, NodeFilter filter, boolean recurse )
{
NodeListImpl matches = new NodeListImpl();
NodeList children = parent.getChildNodes();
if( children != null )
{
final int len = children.getLength();
for( int i = 0; i < len; i++ )
{
Node child = children.item( i );
if( filter.accept( child ) )
{
matches.add( child );
}
if( recurse )
{
NodeList recmatches = listChildNodes( child, filter, recurse );
final int reclength = matches.getLength();
for( int j = 0; j < reclength; j++ )
{
matches.add( recmatches.item( i ) );
}
}
}
}
return matches;
}

/**
* Filter interface to be applied when iterating over a DOM tree. Just think
* of it like a <tt>FileFilter</tt> clone.
*
* @author RT
*/
public interface NodeFilter
{
/**
* @param node the node to check for acceptance.
* @return <tt>true</tt> if the node is accepted by this filter,
* otherwise <tt>false</tt>
*/
boolean accept( Node node );
}

}

+ 0
- 244
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/FormatterElement.java View File

@@ -1,244 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.todo.types.EnumeratedAttribute;

/**
* <p>
*
* A wrapper for the implementations of <code>JUnitResultFormatter</code>. In
* particular, used as a nested <code>&lt;formatter&gt;</code> element in a
* <code>&lt;junit&gt;</code> task. <p>
*
* For example, <code><pre>
* &lt;junit printsummary="no" haltonfailure="yes" fork="false"&gt;
* &lt;formatter type="plain" usefile="false" /&gt;
* &lt;test name="org.apache.ecs.InternationalCharTest" /&gt;
* &lt;/junit&gt;</pre></code> adds a <code>plain</code> type
* implementation (<code>PlainJUnitResultFormatter</code>) to display the
* results of the test. <p>
*
* Either the <code>type</code> or the <code>classname</code> attribute must be
* set.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @see JUnitTask
* @see XMLJUnitResultFormatter
* @see BriefJUnitResultFormatter
* @see PlainJUnitResultFormatter
* @see JUnitResultFormatter
*/
public class FormatterElement
{
private OutputStream out = System.out;
private boolean useFile = true;

private String classname;
private String extension;
private File outFile;

/**
* <p>
*
* Set name of class to be used as the formatter. <p>
*
* This class must implement <code>JUnitResultFormatter</code>
*
* @param classname The new Classname value
*/
public void setClassname( String classname )
{
this.classname = classname;
}

public void setExtension( String ext )
{
this.extension = ext;
}

/**
* <p>
*
* Set output stream for formatter to use. <p>
*
* Defaults to standard out.
*
* @param out The new Output value
*/
public void setOutput( OutputStream out )
{
this.out = out;
}

/**
* <p>
*
* Quick way to use a standard formatter. <p>
*
* At the moment, there are three supported standard formatters.
* <ul>
* <li> The <code>xml</code> type uses a <code>XMLJUnitResultFormatter</code>
* .
* <li> The <code>brief</code> type uses a <code>BriefJUnitResultFormatter</code>
* .
* <li> The <code>plain</code> type (the default) uses a <code>PlainJUnitResultFormatter</code>
* .
* </ul>
* <p>
*
* Sets <code>classname</code> attribute - so you can't use that attribute
* if you use this one.
*
* @param type The new Type value
*/
public void setType( TypeAttribute type )
{
if( "xml".equals( type.getValue() ) )
{
setClassname( "org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter" );
setExtension( ".xml" );
}
else
{
if( "brief".equals( type.getValue() ) )
{
setClassname( "org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter" );
}
else
{// must be plain, ensured by TypeAttribute
setClassname( "org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter" );
}
setExtension( ".txt" );
}
}

/**
* Set whether the formatter should log to file.
*
* @param useFile The new UseFile value
*/
public void setUseFile( boolean useFile )
{
this.useFile = useFile;
}

/**
* Get name of class to be used as the formatter.
*
* @return The Classname value
*/
public String getClassname()
{
return classname;
}

public String getExtension()
{
return extension;
}

/**
* <p>
*
* Set the file which the formatte should log to. <p>
*
* Note that logging to file must be enabled .
*
* @param out The new Outfile value
*/
void setOutfile( File out )
{
this.outFile = out;
}

/**
* Get whether the formatter should log to file.
*
* @return The UseFile value
*/
boolean getUseFile()
{
return useFile;
}

JUnitResultFormatter createFormatter()
throws TaskException
{
if( classname == null )
{
throw new TaskException( "you must specify type or classname" );
}

Class f = null;
try
{
f = Class.forName( classname );
}
catch( ClassNotFoundException e )
{
throw new TaskException( "Error", e );
}

Object o = null;
try
{
o = f.newInstance();
}
catch( InstantiationException e )
{
throw new TaskException( "Error", e );
}
catch( IllegalAccessException e )
{
throw new TaskException( "Error", e );
}

if( !( o instanceof JUnitResultFormatter ) )
{
throw new TaskException( classname + " is not a JUnitResultFormatter" );
}

JUnitResultFormatter r = (JUnitResultFormatter)o;

if( useFile && outFile != null )
{
try
{
out = new FileOutputStream( outFile );
}
catch( java.io.IOException e )
{
throw new TaskException( "Error", e );
}
}
r.setOutput( out );
return r;
}

/**
* <p>
*
* Enumerated attribute with the values "plain", "xml" and "brief". <p>
*
* Use to enumerate options for <code>type</code> attribute.
*
* @author RT
*/
public static class TypeAttribute extends EnumeratedAttribute
{
public String[] getValues()
{
return new String[]{"plain", "xml", "brief"};
}
}
}

+ 0
- 59
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitResultFormatter.java View File

@@ -1,59 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.OutputStream;
import junit.framework.TestListener;
import org.apache.myrmidon.api.TaskException;

/**
* This Interface describes classes that format the results of a JUnit testrun.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public interface JUnitResultFormatter extends TestListener
{
/**
* The whole testsuite started.
*
* @param suite Description of Parameter
* @exception TaskException Description of Exception
*/
void startTestSuite( JUnitTest suite )
throws TaskException;

/**
* The whole testsuite ended.
*
* @param suite Description of Parameter
* @exception TaskException Description of Exception
*/
void endTestSuite( JUnitTest suite )
throws TaskException;

/**
* Sets the stream the formatter is supposed to write its results to.
*
* @param out The new Output value
*/
void setOutput( OutputStream out );

/**
* This is what the test has written to System.out
*
* @param out The new SystemOutput value
*/
void setSystemOutput( String out );

/**
* This is what the test has written to System.err
*
* @param err The new SystemError value
*/
void setSystemError( String err );
}

+ 0
- 717
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitTask.java View File

@@ -1,717 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Properties;
import java.util.Random;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.file.Path;
import org.apache.myrmidon.framework.file.FileListUtil;
import org.apache.myrmidon.framework.java.ExecuteJava;
import org.apache.myrmidon.framework.nativelib.Argument;
import org.apache.myrmidon.framework.nativelib.Commandline;
import org.apache.tools.todo.types.EnumeratedAttribute;
import org.apache.myrmidon.framework.nativelib.EnvironmentData;
import org.apache.myrmidon.framework.nativelib.EnvironmentVariable;
import org.apache.tools.todo.types.SysProperties;
import org.apache.myrmidon.framework.nativelib.ArgumentList;

/**
* Ant task to run JUnit tests. <p>
*
* JUnit is a framework to create unit test. It has been initially created by
* Erich Gamma and Kent Beck. JUnit can be found at <a
* href="http://www.junit.org">http://www.junit.org</a> . <p>
*
* <code>JUnitTask</code> can run a single specific <code>JUnitTest</code> using
* the <code>test</code> element. For example, the following target <code><pre>
* &lt;target name="test-int-chars" depends="jar-test"&gt;
* &lt;echo message="testing international characters"/&gt;
* &lt;junit printsummary="no" haltonfailure="yes" fork="false"&gt;
* &lt;classpath refid="classpath"/&gt;
* &lt;formatter type="plain" usefile="false" /&gt;
* &lt;test name="org.apache.ecs.InternationalCharTest" /&gt;
* &lt;/junit&gt;
* &lt;/target&gt;
* </pre></code> runs a single junit test (<code>org.apache.ecs.InternationalCharTest</code>
* ) in the current VM using the path with id <code>classpath</code> as
* classpath and presents the results formatted using the standard <code>plain</code>
* formatter on the command line. <p>
*
* This task can also run batches of tests. The <code>batchtest</code> element
* creates a <code>BatchTest</code> based on a fileset. This allows, for
* example, all classes found in directory to be run as testcases. For example,
* <code><pre>
* &lt;target name="run-tests" depends="dump-info,compile-tests" if="junit.present"&gt;
* &lt;junit printsummary="no" haltonfailure="yes" fork="${junit.fork}"&gt;
* &lt;jvmarg value="-classic"/&gt;
* &lt;classpath refid="tests-classpath"/&gt;
* &lt;sysproperty key="build.tests" value="${build.tests}"/&gt;
* &lt;formatter type="brief" usefile="false" /&gt;
* &lt;batchtest&gt;
* &lt;fileset dir="${tests.dir}"&gt;
* &lt;include name="**&#047;*Test*" /&gt;
* &lt;/fileset&gt;
* &lt;/batchtest&gt;
* &lt;/junit&gt;
* &lt;/target&gt;
* </pre></code> this target finds any classes with a <code>test</code>
* directory anywhere in their path (under the top <code>${tests.dir}</code>, of
* course) and creates <code>JUnitTest</code>'s for each one. <p>
*
* Of course, <code>&lt;junit&gt;</code> and <code>&lt;batch&gt;</code> elements
* can be combined for more complex tests. For an example, see the ant <code>build.xml</code>
* target <code>run-tests</code> (the second example is an edited version). <p>
*
* To spawn a new Java VM to prevent interferences between different testcases,
* you need to enable <code>fork</code>. A number of attributes and elements
* allow you to set up how this JVM runs.
* <ul>
* <li> {@link #setTimeout} property sets the maximum time allowed before a
* test is 'timed out'
* <li> {@link #setMaxmemory} property sets memory assignment for the forked
* jvm
* <li> {@link #setJvm} property allows the jvm to be specified
* <li> The <code>&lt;jvmarg&gt;</code> element sets arguements to be passed
* to the forked jvm
* </ul>
*
*
* @author Thomas Haas
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a>
* @author <a href="mailto:Gerrit.Riessen@web.de">Gerrit Riessen</a>
* @author <a href="mailto:ehatcher@apache.org">Erik Hatcher</a>
* @see JUnitTest
* @see BatchTest
*/
public class JUnitTask extends AbstractTask
{
private ArrayList tests = new ArrayList();
private ArrayList batchTests = new ArrayList();
private ArrayList formatters = new ArrayList();

private Integer timeout = null;
private boolean summary = false;
private String summaryValue = "";
private JUnitTestRunner runner = null;
private File dir;
private String jvm;
private String maxMem;
private EnvironmentData sysProperties = new EnvironmentData();
private Path classPath = new Path();
private ArgumentList vmArgs = new Commandline();

/**
* The directory to invoke the VM in. Ignored if no JVM is forked.
*
* @param dir the directory to invoke the JVM from.
* @see #setFork(boolean)
*/
public void setDir( final File dir )
{
this.dir = dir;
}

/**
* Tells this task to set the named property to "true" when there is a error
* in a test. This property is applied on all BatchTest (batchtest) and
* JUnitTest (test), however, it can possibly be overriden by their own
* properties.
*
* @param propertyName The new ErrorProperty value
*/
public void setErrorProperty( String propertyName )
{
Iterator enum = allTests();
while( enum.hasNext() )
{
BaseTest test = (BaseTest)enum.next();
test.setErrorProperty( propertyName );
}
}

/**
* Tells this task to set the named property to "true" when there is a
* failure in a test. This property is applied on all BatchTest (batchtest)
* and JUnitTest (test), however, it can possibly be overriden by their own
* properties.
*
* @param propertyName The new FailureProperty value
*/
public void setFailureProperty( String propertyName )
{
Iterator enum = allTests();
while( enum.hasNext() )
{
BaseTest test = (BaseTest)enum.next();
test.setFailureProperty( propertyName );
}
}

/**
* Tells this task whether to smartly filter the stack frames of JUnit
* testcase errors and failures before reporting them. This property is
* applied on all BatchTest (batchtest) and JUnitTest (test) however it can
* possibly be overridden by their own properties.
*
* @param value <tt>false</tt> if it should not filter, otherwise <tt>true
* <tt>
*/
public void setFiltertrace( boolean value )
{
Iterator enum = allTests();
while( enum.hasNext() )
{
BaseTest test = (BaseTest)enum.next();
test.setFiltertrace( value );
}
}

/**
* Tells whether a JVM should be forked for each testcase. It avoids
* interference between testcases and possibly avoids hanging the build.
* this property is applied on all BatchTest (batchtest) and JUnitTest
* (test) however it can possibly be overridden by their own properties.
*
* @param value <tt>true</tt> if a JVM should be forked, otherwise <tt>false
* </tt>
* @see #setTimeout
*/
public void setFork( boolean value )
{
Iterator enum = allTests();
while( enum.hasNext() )
{
BaseTest test = (BaseTest)enum.next();
test.setFork( value );
}
}

/**
* Tells this task to halt when there is an error in a test. this property
* is applied on all BatchTest (batchtest) and JUnitTest (test) however it
* can possibly be overridden by their own properties.
*
* @param value <tt>true</tt> if it should halt, otherwise <tt>false</tt>
*/
public void setHaltonerror( boolean value )
{
Iterator enum = allTests();
while( enum.hasNext() )
{
BaseTest test = (BaseTest)enum.next();
test.setHaltonerror( value );
}
}

/**
* Tells this task to halt when there is a failure in a test. this property
* is applied on all BatchTest (batchtest) and JUnitTest (test) however it
* can possibly be overridden by their own properties.
*
* @param value <tt>true</tt> if it should halt, otherwise <tt>false</tt>
*/
public void setHaltonfailure( boolean value )
{
Iterator enum = allTests();
while( enum.hasNext() )
{
BaseTest test = (BaseTest)enum.next();
test.setHaltonfailure( value );
}
}

/**
* Set a new VM to execute the testcase. Default is <tt>java</tt> . Ignored
* if no JVM is forked.
*
* @param value the new VM to use instead of <tt>java</tt>
* @see #setFork(boolean)
*/
public void setJvm( final String value )
{
jvm = value;
}

/**
* Set the maximum memory to be used by all forked JVMs.
*
* @param max the value as defined by <tt>-mx</tt> or <tt>-Xmx</tt> in the
* java command line options.
*/
public void setMaxmemory( final String max )
{
maxMem = max;
}

/**
* Tells whether the task should print a short summary of the task.
*
* @param value <tt>true</tt> to print a summary, <tt>withOutAndErr</tt> to
* include the test&apos;s output as well, <tt>false</tt> otherwise.
* @see SummaryJUnitResultFormatter
*/
public void setPrintsummary( SummaryAttribute value )
{
summaryValue = value.getValue();
summary = value.asBoolean();
}

/**
* Set the timeout value (in milliseconds). If the test is running for more
* than this value, the test will be canceled. (works only when in 'fork'
* mode).
*
* @param value the maximum time (in milliseconds) allowed before declaring
* the test as 'timed-out'
* @see #setFork(boolean)
*/
public void setTimeout( Integer value )
{
timeout = value;
}

/**
* Add a new formatter to all tests of this task.
*
* @param fe The feature to be added to the Formatter attribute
*/
public void addFormatter( FormatterElement fe )
{
formatters.add( fe );
}

/**
* Add a nested sysproperty element. This might be useful to tranfer Ant
* properties to the testcases when JVM forking is not enabled.
*
* @param sysp The feature to be added to the Sysproperty attribute
*/
public void addSysproperty( EnvironmentVariable sysp )
{
sysProperties.addVariable( sysp );
}

/**
* Add a new single testcase.
*
* @param test a new single testcase
* @see JUnitTest
*/
public void addTest( JUnitTest test )
{
tests.add( test );
}

/**
* Create a new set of testcases (also called ..batchtest) and add it to the
* list.
*/
public void addBatchTest( final BatchTest test )
{
batchTests.add( test );
}

/**
* <code>&lt;classpath&gt;</code> allows classpath to be set for tests.
*/
public void addClasspath( final Path path )
{
classPath.add( path );
}

/**
* Create a new JVM argument. Ignored if no JVM is forked.
*
* @see #setFork(boolean)
*/
public void addJvmarg( final Argument argument )
{
vmArgs.addArgument( argument );
}

/**
* Runs the testcase.
*
* @exception TaskException Description of Exception
*/
public void execute()
throws TaskException
{

/*
* Adds the jars or directories containing Ant, this task and JUnit to the
* classpath - this should make the forked JVM work without having to
* specify them directly.
*/
addClasspathEntry( "/junit/framework/TestCase.class" );
addClasspathEntry( "/org/apache/tools/ant/Task.class" );
addClasspathEntry( "/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.class" );

Iterator list = getIndividualTests();
while( list.hasNext() )
{
JUnitTest test = (JUnitTest)list.next();
final TaskContext context = getContext();
if( test.shouldRun( context ) )
{
execute( test );
}
}
}

/**
* Merge all individual tests from the batchtest with all individual tests
* and return an enumeration over all <tt>JUnitTest</tt> .
*
* @return The IndividualTests value
*/
protected Iterator getIndividualTests()
throws TaskException
{
Iterator[] enums = new Iterator[ batchTests.size() + 1 ];
for( int i = 0; i < batchTests.size(); i++ )
{
BatchTest batchtest = (BatchTest)batchTests.get( i );
enums[ i ] = batchtest.iterator();
}
enums[ enums.length - 1 ] = tests.iterator();
return new CompoundIterator( enums );
}

/**
* return the file or null if does not use a file
*
* @param fe Description of Parameter
* @param test Description of Parameter
* @return The Output value
*/
protected File getOutput( FormatterElement fe, JUnitTest test )
throws TaskException
{
if( fe.getUseFile() )
{
String filename = test.getOutfile() + fe.getExtension();
File destFile = new File( test.getTodir(), filename );
final String absFilename = destFile.getAbsolutePath();
return getContext().resolveFile( absFilename );
}
return null;
}

/**
* Search for the given resource and add the directory or archive that
* contains it to the classpath. <p>
*
* Doesn't work for archives in JDK 1.1 as the URL returned by getResource
* doesn't contain the name of the archive.</p>
*
* @param resource The feature to be added to the ClasspathEntry attribute
*/
protected void addClasspathEntry( String resource )
{
URL url = getClass().getResource( resource );
if( url != null )
{
String u = url.toString();
if( u.startsWith( "jar:file:" ) )
{
int pling = u.indexOf( "!" );
String jarName = u.substring( 9, pling );
getContext().debug( "Implicitly adding " + jarName + " to classpath" );
classPath.addLocation( new File( jarName ) );
}
else if( u.startsWith( "file:" ) )
{
int tail = u.indexOf( resource );
String dirName = u.substring( 5, tail );
getContext().debug( "Implicitly adding " + dirName + " to classpath" );
classPath.addLocation( new File( dirName ) );
}
else
{
getContext().debug( "Don\'t know how to handle resource URL " + u );
}
}
else
{
getContext().debug( "Couldn\'t find " + resource );
}
}

protected Iterator allTests()
{
Iterator[] enums = {tests.iterator(), batchTests.iterator()};
return new CompoundIterator( enums );
}

/**
* Run the tests.
*
* @param test Description of Parameter
* @exception TaskException Description of Exception
*/
protected void execute( final JUnitTest test )
throws TaskException
{
// set the default values if not specified
//@todo should be moved to the test class instead.
if( test.getTodir() == null )
{
test.setTodir( getBaseDirectory() );
}

if( test.getOutfile() == null )
{
test.setOutfile( "TEST-" + test.getName() );
}

// execute the test and get the return code
int exitValue = JUnitTestRunner.ERRORS;
boolean wasKilled = false;
if( !test.getFork() )
{
exitValue = executeInVM( test );
}
else
{
exitValue = executeAsForked( test );
}

// if there is an error/failure and that it should halt, stop everything otherwise
// just log a statement
boolean errorOccurredHere = exitValue == JUnitTestRunner.ERRORS;
boolean failureOccurredHere = exitValue != JUnitTestRunner.SUCCESS;
if( errorOccurredHere || failureOccurredHere )
{
if( errorOccurredHere && test.getHaltonerror()
|| failureOccurredHere && test.getHaltonfailure() )
{
throw new TaskException( "Test " + test.getName() + " failed"
+ ( wasKilled ? " (timeout)" : "" ) );
}
else
{
final String message = "TEST " + test.getName() + " FAILED" +
( wasKilled ? " (timeout)" : "" );
getContext().error( message );
if( errorOccurredHere && test.getErrorProperty() != null )
{
final String name = test.getErrorProperty();
getContext().setProperty( name, "true" );
}
if( failureOccurredHere && test.getFailureProperty() != null )
{
final String name = test.getFailureProperty();
getContext().setProperty( name, "true" );
}
}
}
}

protected void handleErrorOutput( String line )
{
if( runner != null )
{
runner.handleErrorOutput( line );
}
else
{
//super.handleErrorOutput( line );
}
}

// in VM is not very nice since it could probably hang the
// whole build. IMHO this method should be avoided and it would be best
// to remove it in future versions. TBD. (SBa)


protected void handleOutput( String line )
{
if( runner != null )
{
runner.handleOutput( line );
}
else
{
//super.handleOutput( line );
}
}

/**
* Execute a testcase by forking a new JVM. The command will block until it
* finishes. To know if the process was destroyed or not, use the <tt>
* killedProcess()</tt> method of the watchdog class.
*
* @param test the testcase to execute.
*/
private int executeAsForked( JUnitTest test )
throws TaskException
{
ExecuteJava cmd = new ExecuteJava();
cmd.setJvm( jvm );
cmd.setIgnoreReturnCode( true );
cmd.setWorkingDirectory( dir );
cmd.setMaxMemory( maxMem );
cmd.getClassPath().add( classPath );
cmd.getVmArguments().addArguments( vmArgs );
cmd.getSysProperties().addVariables( sysProperties );

cmd.setClassName( "org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" );
cmd.getArguments().addArgument( test.getName() );
cmd.getArguments().addArgument( "filtertrace=" + test.getFiltertrace() );
cmd.getArguments().addArgument( "haltOnError=" + test.getHaltonerror() );
cmd.getArguments().addArgument( "haltOnFailure=" + test.getHaltonfailure() );
if( summary )
{
getContext().info( "Running " + test.getName() );
cmd.getArguments().addArgument( "formatter=org.apache.tools.ant.taskdefs.optional.junit.SummaryJUnitResultFormatter" );
}

StringBuffer formatterArg = new StringBuffer( 128 );
final FormatterElement[] feArray = mergeFormatters( test );
for( int i = 0; i < feArray.length; i++ )
{
FormatterElement fe = feArray[ i ];
formatterArg.append( "formatter=" );
formatterArg.append( fe.getClassname() );
File outFile = getOutput( fe, test );
if( outFile != null )
{
formatterArg.append( "," );
formatterArg.append( outFile );
}
cmd.getArguments().addArgument( formatterArg.toString() );
formatterArg.setLength( 0 );
}

// Create a temporary file to pass the Ant properties to the forked test
File propsFile = new File( "junit" + ( new Random( System.currentTimeMillis() ) ).nextLong() + ".properties" );
cmd.getArguments().addArgument( "propsfile=" + propsFile.getAbsolutePath() );
Properties props = new Properties();
props.putAll( getContext().getProperties() );
try
{
final FileOutputStream outstream = new FileOutputStream( propsFile );
props.store( outstream, "Ant JUnitTask generated properties file" );
outstream.close();
}
catch( IOException ioe )
{
throw new TaskException( "Error creating temporary properties file.", ioe );
}

try
{
return cmd.executeForked( getContext() );
}
finally
{
if( !propsFile.delete() )
{
throw new TaskException( "Could not delete temporary properties file." );
}
}
}

/**
* Execute inside VM.
*/
private int executeInVM( JUnitTest test )
throws TaskException
{
test.setProperties( getContext().getProperties() );

SysProperties.setSystem( sysProperties );

try
{
getContext().debug( "Using System properties " + System.getProperties() );
final ClassLoader classLoader = FileListUtil.createClassLoader( classPath, getContext() );

runner = new JUnitTestRunner( test,
test.getHaltonerror(),
test.getFiltertrace(),
test.getHaltonfailure(),
classLoader );
if( summary )
{
getContext().info( "Running " + test.getName() );

SummaryJUnitResultFormatter f =
new SummaryJUnitResultFormatter();
f.setWithOutAndErr( "withoutanderr".equalsIgnoreCase( summaryValue ) );
f.setOutput( System.out );
runner.addFormatter( f );
}

final FormatterElement[] feArray = mergeFormatters( test );
for( int i = 0; i < feArray.length; i++ )
{
FormatterElement fe = feArray[ i ];
File outFile = getOutput( fe, test );
if( outFile != null )
{
fe.setOutfile( outFile );
}
else
{
fe.setOutput( System.out );
}
runner.addFormatter( fe.createFormatter() );
}

runner.run();
return runner.getRetCode();
}
finally
{
SysProperties.restoreSystem();
}
}

private FormatterElement[] mergeFormatters( JUnitTest test )
{
final ArrayList feArrayList = (ArrayList)formatters.clone();
test.addFormattersTo( feArrayList );
return (FormatterElement[])feArrayList.toArray( new FormatterElement[ feArrayList.size() ] );
}

/**
* Print summary enumeration values.
*
* @author RT
*/
public static class SummaryAttribute extends EnumeratedAttribute
{
public String[] getValues()
{
return new String[]{"true", "yes", "false", "no",
"on", "off", "withOutAndErr"};
}

public boolean asBoolean()
{
final String value = getValue();
return "true".equals( value ) ||
"on".equals( value ) ||
"yes".equals( value ) ||
"withOutAndErr".equals( value );
}
}

}

+ 0
- 186
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitTest.java View File

@@ -1,186 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import org.apache.myrmidon.api.TaskContext;

/**
* <p>
*
* Run a single JUnit test. <p>
*
* The JUnit test is actually run by {@link JUnitTestRunner}. So read the doc
* comments for that class :)
*
* @author Thomas Haas
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> ,
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a>
* @see JUnitTask
* @see JUnitTestRunner
*/
public class JUnitTest extends BaseTest
{
/**
* the name of the test case
*/
private String m_name;

/**
* the name of the result file
*/
private String m_outfile;

// Snapshot of the system properties
private Properties m_props;

private long m_runTime;

// @todo this is duplicating TestResult information. Only the time is not
// part of the result. So we'd better derive a new class from TestResult
// and deal with it. (SB)
private long m_runs;
private long m_failures;
private long m_errors;

public JUnitTest()
{
}

public JUnitTest( String name )
{
m_name = name;
}

public JUnitTest( final String name,
final boolean haltOnError,
final boolean haltOnFailure,
final boolean filtertrace )
{
m_name = name;
m_haltOnError = haltOnError;
m_haltOnFail = haltOnFailure;
m_filtertrace = filtertrace;
}

public void setCounts( long runs, long failures, long errors )
{
m_runs = runs;
m_failures = failures;
m_errors = errors;
}

/**
* Set the name of the test class.
*/
public void setName( final String value )
{
m_name = value;
}

/**
* Set the name of the output file.
*/
public void setOutfile( final String value )
{
m_outfile = value;
}

public void setProperties( final Map properties )
{
m_props = new Properties();
final Iterator enum = properties.keySet().iterator();
while( enum.hasNext() )
{
final Object key = enum.next();
final Object value = properties.get( key );
m_props.put( key, value );
}
}

public void setRunTime( final long runTime )
{
m_runTime = runTime;
}

public FormatterElement[] getFormatters()
{
return (FormatterElement[])formatters.toArray( new FormatterElement[ formatters.size() ] );
}

/**
* Get the name of the test class.
*
* @return The Name value
*/
public String getName()
{
return m_name;
}

/**
* Get the name of the output file
*
* @return the name of the output file.
*/
public String getOutfile()
{
return m_outfile;
}

public Properties getProperties()
{
return m_props;
}

public long getRunTime()
{
return m_runTime;
}

public long errorCount()
{
return m_errors;
}

public long failureCount()
{
return m_failures;
}

public long runCount()
{
return m_runs;
}

public boolean shouldRun( final TaskContext context )
{
if( ifProperty != null && context.getProperty( ifProperty ) == null )
{
return false;
}
else if( unlessProperty != null &&
context.getProperty( unlessProperty ) != null )
{
return false;
}

return true;
}

/**
* Convenient method to add formatters to a vector
*/
void addFormattersTo( ArrayList v )
{
v.addAll( formatters );
}
}

+ 0
- 643
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitTestRunner.java View File

@@ -1,643 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Properties;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestListener;
import junit.framework.TestResult;
import junit.framework.TestSuite;
import org.apache.avalon.framework.ExceptionUtil;
import org.apache.myrmidon.api.TaskException;

/**
* Simple Testrunner for JUnit that runs all tests of a testsuite. <p>
*
* This TestRunner expects a name of a TestCase class as its argument. If this
* class provides a static suite() method it will be called and the resulting
* Test will be run. So, the signature should be <pre><code>
* public static junit.framework.Test suite()
* </code></pre> <p>
*
* If no such method exists, all public methods starting with "test" and taking
* no argument will be run. <p>
*
* Summary output is generated at the end.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:ehatcher@apache.org">Erik Hatcher</a>
*/
public class JUnitTestRunner
implements TestListener
{
/**
* No problems with this test.
*/
public final static int SUCCESS = 0;

/**
* Some tests failed.
*/
public final static int FAILURES = 1;

/**
* An error occured.
*/
public final static int ERRORS = 2;

/**
* Do we filter junit.*.* stack frames out of failure and error exceptions.
*/
private static boolean filtertrace = true;

private final static String[] DEFAULT_TRACE_FILTERS = new String[]
{
"junit.framework.TestCase",
"junit.framework.TestResult",
"junit.framework.TestSuite",
"junit.framework.Assert.", // don't filter AssertionFailure
"junit.swingui.TestRunner",
"junit.awtui.TestRunner",
"junit.textui.TestRunner",
"java.lang.reflect.Method.invoke(",
"org.apache.tools.ant."
};

private static ArrayList m_fromCmdLine = new ArrayList();

/**
* Holds the registered formatters.
*/
private ArrayList m_formatters = new ArrayList();

/**
* Do we stop on errors.
*/
private boolean m_haltOnError;

/**
* Do we stop on test failures.
*/
private boolean m_haltOnFailure;

/**
* The corresponding testsuite.
*/
private Test m_suite;

/**
* Returncode
*/
private int m_retCode = SUCCESS;

/**
* Exception caught in constructor.
*/
private Exception m_exception;

/**
* The TestSuite we are currently running.
*/
private JUnitTest m_junitTest;

/**
* Collects TestResults.
*/
private TestResult m_res;

/**
* output written during the test
*/
private PrintStream m_systemError;

/**
* Error output during the test
*/
private PrintStream m_systemOut;

/**
* Constructor for fork=true or when the user hasn't specified a classpath.
*
* @param test Description of Parameter
* @param haltOnError Description of Parameter
* @param filtertrace Description of Parameter
* @param haltOnFailure Description of Parameter
*/
public JUnitTestRunner( final JUnitTest test,
final boolean haltOnError,
final boolean filtertrace,
final boolean haltOnFailure )
{
this( test, haltOnError, filtertrace, haltOnFailure, null );
}

/**
* Constructor to use when the user has specified a classpath.
*
* @param test Description of Parameter
* @param haltOnError Description of Parameter
* @param filtertrace Description of Parameter
* @param haltOnFailure Description of Parameter
* @param loader Description of Parameter
*/
public JUnitTestRunner( JUnitTest test, boolean haltOnError, boolean filtertrace,
boolean haltOnFailure, ClassLoader loader )
{
//JUnitTestRunner.filtertrace = filtertrace;
this.filtertrace = filtertrace;
this.m_junitTest = test;
this.m_haltOnError = haltOnError;
this.m_haltOnFailure = haltOnFailure;

try
{
Class testClass = null;
if( loader == null )
{
testClass = Class.forName( test.getName() );
}
else
{
testClass = loader.loadClass( test.getName() );
}

Method suiteMethod = null;
try
{
// check if there is a suite method
suiteMethod = testClass.getMethod( "suite", new Class[ 0 ] );
}
catch( Exception e )
{
// no appropriate suite method found. We don't report any
// error here since it might be perfectly normal. We don't
// know exactly what is the cause, but we're doing exactly
// the same as JUnit TestRunner do. We swallow the exceptions.
}
if( suiteMethod != null )
{
// if there is a suite method available, then try
// to extract the suite from it. If there is an error
// here it will be caught below and reported.
m_suite = (Test)suiteMethod.invoke( null, new Class[ 0 ] );
}
else
{
// try to extract a test suite automatically
// this will generate warnings if the class is no suitable Test
m_suite = new TestSuite( testClass );
}

}
catch( Exception e )
{
m_retCode = ERRORS;
m_exception = e;
}
}

/**
* Returns a filtered stack trace. This is ripped out of
* junit.runner.BaseTestRunner. Scott M. Stirling.
*
* @param t Description of Parameter
* @return The FilteredTrace value
*/
public static String getFilteredTrace( Throwable t )
{
final String trace = ExceptionUtil.printStackTrace( t );
return JUnitTestRunner.filterStack( trace );
}

/**
* Filters stack frames from internal JUnit and Ant classes
*
* @param stack Description of Parameter
* @return Description of the Returned Value
*/
public static String filterStack( String stack )
{
if( !filtertrace )
{
return stack;
}
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter( sw );
StringReader sr = new StringReader( stack );
BufferedReader br = new BufferedReader( sr );

String line;
try
{
while( ( line = br.readLine() ) != null )
{
if( !filterLine( line ) )
{
pw.println( line );
}
}
}
catch( Exception IOException )
{
return stack;// return the stack unfiltered
}
return sw.toString();
}

/**
* Entry point for standalone (forked) mode. Parameters: testcaseclassname
* plus parameters in the format key=value, none of which is required.
*
* <tablecols="4" border="1">
*
* <tr>
*
* <th>
* key
* </th>
*
* <th>
* description
* </th>
*
* <th>
* default value
* </th>
*
* </tr>
*
* <tr>
*
* <td>
* haltOnError
* </td>
*
* <td>
* halt test on errors?
* </td>
*
* <td>
* false
* </td>
*
* </tr>
*
* <tr>
*
* <td>
* haltOnFailure
* </td>
*
* <td>
* halt test on failures?
* </td>
*
* <td>
* false
* </td>
*
* </tr>
*
* <tr>
*
* <td>
* formatter
* </td>
*
* <td>
* A JUnitResultFormatter given as classname,filename. If filename is
* ommitted, System.out is assumed.
* </td>
*
* <td>
* none
* </td>
*
* </tr>
*
* </table>
*
*
* @param args The command line arguments
* @exception IOException Description of Exception
*/
public static void main( String[] args )
throws IOException, TaskException
{
boolean exitAtEnd = true;
boolean haltError = false;
boolean haltFail = false;
boolean stackfilter = true;
Properties props = new Properties();

if( args.length == 0 )
{
System.err.println( "required argument TestClassName missing" );
System.exit( ERRORS );
}

for( int i = 1; i < args.length; i++ )
{
if( args[ i ].startsWith( "haltOnError=" ) )
{
haltError = "true".equals( args[ i ].substring( 12 ) );
}
else if( args[ i ].startsWith( "haltOnFailure=" ) )
{
haltFail = "true".equals( args[ i ].substring( 14 ) );
}
else if( args[ i ].startsWith( "filtertrace=" ) )
{
stackfilter = "true".equals( args[ i ].substring( 12 ) );
}
else if( args[ i ].startsWith( "formatter=" ) )
{
try
{
createAndStoreFormatter( args[ i ].substring( 10 ) );
}
catch( TaskException be )
{
System.err.println( be.getMessage() );
System.exit( ERRORS );
}
}
else if( args[ i ].startsWith( "propsfile=" ) )
{
FileInputStream in = new FileInputStream( args[ i ].substring( 10 ) );
props.load( in );
in.close();
}
}

JUnitTest t = new JUnitTest( args[ 0 ] );

// Add/overlay system properties on the properties from the Ant project
Hashtable p = System.getProperties();
props.putAll( p );
t.setProperties( props );

JUnitTestRunner runner = new JUnitTestRunner( t, haltError, stackfilter, haltFail );
transferFormatters( runner );
runner.run();
System.exit( runner.getRetCode() );
}

/**
* Line format is: formatter=<classname>(,<pathname>
*
* )?
*
* @param line Description of Parameter
* @exception TaskException Description of Exception
*/
private static void createAndStoreFormatter( String line )
throws TaskException
{
FormatterElement fe = new FormatterElement();
int pos = line.indexOf( ',' );
if( pos == -1 )
{
fe.setClassname( line );
}
else
{
fe.setClassname( line.substring( 0, pos ) );
fe.setOutfile( new File( line.substring( pos + 1 ) ) );
}
m_fromCmdLine.add( fe.createFormatter() );
}

private static boolean filterLine( String line )
{
for( int i = 0; i < DEFAULT_TRACE_FILTERS.length; i++ )
{
if( line.indexOf( DEFAULT_TRACE_FILTERS[ i ] ) > 0 )
{
return true;
}
}
return false;
}

private static void transferFormatters( JUnitTestRunner runner )
{
for( int i = 0; i < m_fromCmdLine.size(); i++ )
{
runner.addFormatter( (JUnitResultFormatter)m_fromCmdLine.get( i ) );
}
}

/**
* Returns what System.exit() would return in the standalone version.
*
* @return 2 if errors occurred, 1 if tests failed else 0.
*/
public int getRetCode()
{
return m_retCode;
}

/**
* Interface TestListener. <p>
*
* An error occured while running the test.
*
* @param test The feature to be added to the Error attribute
* @param t The feature to be added to the Error attribute
*/
public void addError( Test test, Throwable t )
{
if( m_haltOnError )
{
m_res.stop();
}
}

/**
* Interface TestListener for JUnit &lt;= 3.4. <p>
*
* A Test failed.
*
* @param test The feature to be added to the Failure attribute
* @param t The feature to be added to the Failure attribute
*/
public void addFailure( Test test, Throwable t )
{
if( m_haltOnFailure )
{
m_res.stop();
}
}

/**
* Interface TestListener for JUnit &gt; 3.4. <p>
*
* A Test failed.
*
* @param test The feature to be added to the Failure attribute
* @param t The feature to be added to the Failure attribute
*/
public void addFailure( Test test, AssertionFailedError t )
{
addFailure( test, (Throwable)t );
}

public void addFormatter( JUnitResultFormatter f )
{
m_formatters.add( f );
}

/**
* Interface TestListener. <p>
*
* A Test is finished.
*
* @param test Description of Parameter
*/
public void endTest( Test test )
{
}

public void run()
throws TaskException
{
m_res = new TestResult();
m_res.addListener( this );
for( int i = 0; i < m_formatters.size(); i++ )
{
final TestListener listener = (TestListener)m_formatters.get( i );
m_res.addListener( listener );
}

long start = System.currentTimeMillis();

fireStartTestSuite();
if( m_exception != null )
{// had an exception in the constructor
for( int i = 0; i < m_formatters.size(); i++ )
{
( (TestListener)m_formatters.get( i ) ).addError( null,
m_exception );
}
m_junitTest.setCounts( 1, 0, 1 );
m_junitTest.setRunTime( 0 );
}
else
{

ByteArrayOutputStream errStrm = new ByteArrayOutputStream();
m_systemError = new PrintStream( errStrm );

ByteArrayOutputStream outStrm = new ByteArrayOutputStream();
m_systemOut = new PrintStream( outStrm );

try
{
m_suite.run( m_res );
}
finally
{
m_systemError.close();
m_systemError = null;
m_systemOut.close();
m_systemOut = null;
sendOutAndErr( new String( outStrm.toByteArray() ),
new String( errStrm.toByteArray() ) );

m_junitTest.setCounts( m_res.runCount(), m_res.failureCount(),
m_res.errorCount() );
m_junitTest.setRunTime( System.currentTimeMillis() - start );
}
}
fireEndTestSuite();

if( m_retCode != SUCCESS || m_res.errorCount() != 0 )
{
m_retCode = ERRORS;
}
else if( m_res.failureCount() != 0 )
{
m_retCode = FAILURES;
}
}

/**
* Interface TestListener. <p>
*
* A new Test is started.
*/
public void startTest( Test t )
{
}

protected void handleErrorOutput( String line )
{
if( m_systemError != null )
{
m_systemError.println( line );
}
}

protected void handleOutput( String line )
{
if( m_systemOut != null )
{
m_systemOut.println( line );
}
}

private void fireEndTestSuite()
throws TaskException
{
final int size = m_formatters.size();
for( int i = 0; i < size; i++ )
{
final JUnitResultFormatter formatter =
(JUnitResultFormatter)m_formatters.get( i );
formatter.endTestSuite( m_junitTest );
}
}

private void fireStartTestSuite()
throws TaskException
{
final int size = m_formatters.size();
for( int i = 0; i < size; i++ )
{
final JUnitResultFormatter formatter = (JUnitResultFormatter)m_formatters.get( i );
formatter.startTestSuite( m_junitTest );
}
}

private void sendOutAndErr( String out, String err )
{
final int size = m_formatters.size();
for( int i = 0; i < size; i++ )
{
final JUnitResultFormatter formatter =
(JUnitResultFormatter)m_formatters.get( i );

formatter.setSystemOutput( out );
formatter.setSystemError( err );
}
}
}

+ 0
- 69
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/JUnitVersionHelper.java View File

@@ -1,69 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.lang.reflect.Method;
import junit.framework.Test;
import junit.framework.TestCase;

/**
* Work around for some changes to the public JUnit API between different JUnit
* releases.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$
*/
public class JUnitVersionHelper
{

private static Method testCaseName = null;

static
{
try
{
testCaseName = TestCase.class.getMethod( "getName", new Class[ 0 ] );
}
catch( NoSuchMethodException e )
{
// pre JUnit 3.7
try
{
testCaseName = TestCase.class.getMethod( "name", new Class[ 0 ] );
}
catch( NoSuchMethodException e2 )
{
}
}
}

/**
* JUnit 3.7 introduces TestCase.getName() and subsequent versions of JUnit
* remove the old name() method. This method provides access to the name of
* a TestCase via reflection that is supposed to work with version before
* and after JUnit 3.7.
*
* @param t Description of Parameter
* @return The TestCaseName value
*/
public static String getTestCaseName( Test t )
{
if( t instanceof TestCase && testCaseName != null )
{
try
{
return (String)testCaseName.invoke( t, new Object[ 0 ] );
}
catch( Throwable e )
{
}
}
return "unknown";
}

}

+ 0
- 37
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/NodeListImpl.java View File

@@ -1,37 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.util.ArrayList;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* custom implementation of a nodelist
*/
public class NodeListImpl
extends ArrayList
implements NodeList
{
public int getLength()
{
return size();
}

public Node item( final int i )
{
try
{
return (Node)get( i );
}
catch( final ArrayIndexOutOfBoundsException aioobe )
{
return null;// conforming to NodeList interface
}
}
}

+ 0
- 253
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/PlainJUnitResultFormatter.java View File

@@ -1,253 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.NumberFormat;
import java.util.Hashtable;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import org.apache.avalon.excalibur.util.StringUtil;
import org.apache.myrmidon.api.TaskException;

/**
* Prints plain text output of the test to a specified Writer.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/

public class PlainJUnitResultFormatter implements JUnitResultFormatter
{

/**
* Formatter for timings.
*/
private NumberFormat nf = NumberFormat.getInstance();
/**
* Timing helper.
*/
private Hashtable testStarts = new Hashtable();
/**
* Suppress endTest if testcase failed.
*/
private Hashtable failed = new Hashtable();

private String systemOutput = null;
private String systemError = null;
/**
* Helper to store intermediate output.
*/
private StringWriter inner;
/**
* Where to write the log to.
*/
private OutputStream out;
/**
* Convenience layer on top of {@link #inner inner}.
*/
private PrintWriter wri;

public PlainJUnitResultFormatter()
{
inner = new StringWriter();
wri = new PrintWriter( inner );
}

public void setOutput( OutputStream out )
{
this.out = out;
}

public void setSystemError( String err )
{
systemError = err;
}

public void setSystemOutput( String out )
{
systemOutput = out;
}

/**
* Interface TestListener. <p>
*
* An error occured while running the test.
*
* @param test The feature to be added to the Error attribute
* @param t The feature to be added to the Error attribute
*/
public void addError( Test test, Throwable t )
{
formatError( "\tCaused an ERROR", test, t );
}

/**
* Interface TestListener for JUnit &lt;= 3.4. <p>
*
* A Test failed.
*
* @param test The feature to be added to the Failure attribute
* @param t The feature to be added to the Failure attribute
*/
public void addFailure( Test test, Throwable t )
{
formatError( "\tFAILED", test, t );
}

/**
* Interface TestListener for JUnit &gt; 3.4. <p>
*
* A Test failed.
*
* @param test The feature to be added to the Failure attribute
* @param t The feature to be added to the Failure attribute
*/
public void addFailure( Test test, AssertionFailedError t )
{
addFailure( test, (Throwable)t );
}

/**
* Interface TestListener. <p>
*
* A Test is finished.
*
* @param test Description of Parameter
*/
public void endTest( Test test )
{
synchronized( wri )
{
wri.print( "Testcase: "
+ JUnitVersionHelper.getTestCaseName( test ) );
if( Boolean.TRUE.equals( failed.get( test ) ) )
{
return;
}
Long l = (Long)testStarts.get( test );
wri.println( " took "
+ nf.format( ( System.currentTimeMillis() - l.longValue() )
/ 1000.0 )
+ " sec" );
}
}

/**
* The whole testsuite ended.
*/
public void endTestSuite( JUnitTest suite )
throws TaskException
{
StringBuffer sb = new StringBuffer( "Testsuite: " );
sb.append( suite.getName() );
sb.append( StringUtil.LINE_SEPARATOR );
sb.append( "Tests run: " );
sb.append( suite.runCount() );
sb.append( ", Failures: " );
sb.append( suite.failureCount() );
sb.append( ", Errors: " );
sb.append( suite.errorCount() );
sb.append( ", Time elapsed: " );
sb.append( nf.format( suite.getRunTime() / 1000.0 ) );
sb.append( " sec" );
sb.append( StringUtil.LINE_SEPARATOR );

// append the err and output streams to the log
if( systemOutput != null && systemOutput.length() > 0 )
{
sb.append( "------------- Standard Output ---------------" )
.append( StringUtil.LINE_SEPARATOR )
.append( systemOutput )
.append( "------------- ---------------- ---------------" )
.append( StringUtil.LINE_SEPARATOR );
}

if( systemError != null && systemError.length() > 0 )
{
sb.append( "------------- Standard Error -----------------" )
.append( StringUtil.LINE_SEPARATOR )
.append( systemError )
.append( "------------- ---------------- ---------------" )
.append( StringUtil.LINE_SEPARATOR );
}

sb.append( StringUtil.LINE_SEPARATOR );

if( out != null )
{
try
{
out.write( sb.toString().getBytes() );
wri.close();
out.write( inner.toString().getBytes() );
out.flush();
}
catch( IOException ioex )
{
throw new TaskException( "Unable to write output", ioex );
}
finally
{
if( out != System.out && out != System.err )
{
try
{
out.close();
}
catch( IOException e )
{
}
}
}
}
}

/**
* Interface TestListener. <p>
*
* A new Test is started.
*
* @param t Description of Parameter
*/
public void startTest( Test t )
{
testStarts.put( t, new Long( System.currentTimeMillis() ) );
failed.put( t, Boolean.FALSE );
}

/**
* Empty.
*
* @param suite Description of Parameter
*/
public void startTestSuite( JUnitTest suite )
{
}

private void formatError( String type, Test test, Throwable t )
{
synchronized( wri )
{
if( test != null )
{
endTest( test );
failed.put( test, Boolean.TRUE );
}

wri.println( type );
wri.println( t.getMessage() );
String strace = JUnitTestRunner.getFilteredTrace( t );
wri.print( strace );
wri.println( "" );
}
}

}// PlainJUnitResultFormatter

+ 0
- 190
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/SummaryJUnitResultFormatter.java View File

@@ -1,190 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.IOException;
import java.io.OutputStream;
import java.text.NumberFormat;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import org.apache.avalon.excalibur.util.StringUtil;
import org.apache.myrmidon.api.TaskException;

/**
* Prints short summary output of the test to Ant's logging system.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/

public class SummaryJUnitResultFormatter implements JUnitResultFormatter
{

/**
* Formatter for timings.
*/
private NumberFormat nf = NumberFormat.getInstance();

private boolean withOutAndErr = false;
private String systemOutput = null;
private String systemError = null;
/**
* OutputStream to write to.
*/
private OutputStream out;

/**
* Empty
*/
public SummaryJUnitResultFormatter()
{
}

public void setOutput( OutputStream out )
{
this.out = out;
}

public void setSystemError( String err )
{
systemError = err;
}

public void setSystemOutput( String out )
{
systemOutput = out;
}

/**
* Should the output to System.out and System.err be written to the summary.
*
* @param value The new WithOutAndErr value
*/
public void setWithOutAndErr( boolean value )
{
withOutAndErr = value;
}

/**
* Empty
*
* @param test The feature to be added to the Error attribute
* @param t The feature to be added to the Error attribute
*/
public void addError( Test test, Throwable t )
{
}

/**
* Empty
*
* @param test The feature to be added to the Failure attribute
* @param t The feature to be added to the Failure attribute
*/
public void addFailure( Test test, Throwable t )
{
}

/**
* Interface TestListener for JUnit &gt; 3.4. <p>
*
* A Test failed.
*
* @param test The feature to be added to the Failure attribute
* @param t The feature to be added to the Failure attribute
*/
public void addFailure( Test test, AssertionFailedError t )
{
addFailure( test, (Throwable)t );
}

/**
* Empty
*
* @param test Description of Parameter
*/
public void endTest( Test test )
{
}

/**
* The whole testsuite ended.
*
* @param suite Description of Parameter
* @exception TaskException Description of Exception
*/
public void endTestSuite( JUnitTest suite )
throws TaskException
{
StringBuffer sb = new StringBuffer( "Tests run: " );
sb.append( suite.runCount() );
sb.append( ", Failures: " );
sb.append( suite.failureCount() );
sb.append( ", Errors: " );
sb.append( suite.errorCount() );
sb.append( ", Time elapsed: " );
sb.append( nf.format( suite.getRunTime() / 1000.0 ) );
sb.append( " sec" );
sb.append( StringUtil.LINE_SEPARATOR );

if( withOutAndErr )
{
if( systemOutput != null && systemOutput.length() > 0 )
{
sb.append( "Output:" ).append( StringUtil.LINE_SEPARATOR ).append( systemOutput )
.append( StringUtil.LINE_SEPARATOR );
}

if( systemError != null && systemError.length() > 0 )
{
sb.append( "Error: " ).append( StringUtil.LINE_SEPARATOR ).append( systemError )
.append( StringUtil.LINE_SEPARATOR );
}
}

try
{
out.write( sb.toString().getBytes() );
out.flush();
}
catch( IOException ioex )
{
throw new TaskException( "Unable to write summary output", ioex );
}
finally
{
if( out != System.out && out != System.err )
{
try
{
out.close();
}
catch( IOException e )
{
}
}
}
}

/**
* Empty
*
* @param t Description of Parameter
*/
public void startTest( Test t )
{
}

/**
* Empty
*
* @param suite Description of Parameter
*/
public void startTestSuite( JUnitTest suite )
{
}
}

+ 0
- 115
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/XMLConstants.java View File

@@ -1,115 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

/**
* <p>
*
* Interface groups XML constants. Interface that groups all constants used
* throughout the <tt>XML</tt> documents that are generated by the <tt>
* XMLJUnitResultFormatter</tt> As of now the DTD is: <code><pre>
* <-----------------
*
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a>
* @see XMLJUnitResultFormatter
* @see XMLResultAggregator
* @todo describe DTDs ----------------------> </pre></code>
*/
public interface XMLConstants
{
/**
* the testsuites element for the aggregate document
*/
String TESTSUITES = "testsuites";

/**
* the testsuite element
*/
String TESTSUITE = "testsuite";

/**
* the testcase element
*/
String TESTCASE = "testcase";

/**
* the error element
*/
String ERROR = "error";

/**
* the failure element
*/
String FAILURE = "failure";

/**
* the system-err element
*/
String SYSTEM_ERR = "system-err";

/**
* the system-out element
*/
String SYSTEM_OUT = "system-out";

/**
* package attribute for the aggregate document
*/
String ATTR_PACKAGE = "package";

/**
* name attribute for property, testcase and testsuite elements
*/
String ATTR_NAME = "name";

/**
* time attribute for testcase and testsuite elements
*/
String ATTR_TIME = "time";

/**
* errors attribute for testsuite elements
*/
String ATTR_ERRORS = "errors";

/**
* failures attribute for testsuite elements
*/
String ATTR_FAILURES = "failures";

/**
* tests attribute for testsuite elements
*/
String ATTR_TESTS = "tests";

/**
* type attribute for failure and error elements
*/
String ATTR_TYPE = "type";

/**
* message attribute for failure elements
*/
String ATTR_MESSAGE = "message";

/**
* the properties element
*/
String PROPERTIES = "properties";

/**
* the property element
*/
String PROPERTY = "property";

/**
* value attribute for property elements
*/
String ATTR_VALUE = "value";

}

+ 0
- 278
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/XMLJUnitResultFormatter.java View File

@@ -1,278 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import org.apache.myrmidon.api.TaskException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

/**
* Prints XML output of the test to a specified Writer.
*
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:ehatcher@apache.org">Erik Hatcher</a>
* @see FormatterElement
*/

public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants
{
/**
* Element for the current test.
*/
private Hashtable testElements = new Hashtable();
/**
* Timing helper.
*/
private Hashtable testStarts = new Hashtable();

/**
* The XML document.
*/
private Document doc;
/**
* Where to write the log to.
*/
private OutputStream out;
/**
* The wrapper for the whole testsuite.
*/
private Element rootElement;

public XMLJUnitResultFormatter()
{
}

private static DocumentBuilder getDocumentBuilder()
{
try
{
return DocumentBuilderFactory.newInstance().newDocumentBuilder();
}
catch( Exception exc )
{
throw new ExceptionInInitializerError( exc );
}
}

public void setOutput( OutputStream out )
{
this.out = out;
}

public void setSystemError( String out )
{
formatOutput( SYSTEM_ERR, out );
}

public void setSystemOutput( String out )
{
formatOutput( SYSTEM_OUT, out );
}

/**
* Interface TestListener. <p>
*
* An error occured while running the test.
*
* @param test The feature to be added to the Error attribute
* @param t The feature to be added to the Error attribute
*/
public void addError( Test test, Throwable t )
{
formatError( ERROR, test, t );
}

/**
* Interface TestListener for JUnit &lt;= 3.4. <p>
*
* A Test failed.
*
* @param test The feature to be added to the Failure attribute
* @param t The feature to be added to the Failure attribute
*/
public void addFailure( Test test, Throwable t )
{
formatError( FAILURE, test, t );
}

/**
* Interface TestListener for JUnit &gt; 3.4. <p>
*
* A Test failed.
*
* @param test The feature to be added to the Failure attribute
* @param t The feature to be added to the Failure attribute
*/
public void addFailure( Test test, AssertionFailedError t )
{
addFailure( test, (Throwable)t );
}

/**
* Interface TestListener. <p>
*
* A Test is finished.
*
* @param test Description of Parameter
*/
public void endTest( Test test )
{
Element currentTest = (Element)testElements.get( test );
Long l = (Long)testStarts.get( test );
currentTest.setAttribute( ATTR_TIME,
"" + ( ( System.currentTimeMillis() - l.longValue() )
/ 1000.0 ) );
}

/**
* The whole testsuite ended.
*
* @param suite Description of Parameter
* @exception TaskException Description of Exception
*/
public void endTestSuite( JUnitTest suite )
throws TaskException
{
rootElement.setAttribute( ATTR_TESTS, "" + suite.runCount() );
rootElement.setAttribute( ATTR_FAILURES, "" + suite.failureCount() );
rootElement.setAttribute( ATTR_ERRORS, "" + suite.errorCount() );
rootElement.setAttribute( ATTR_TIME, "" + ( suite.getRunTime() / 1000.0 ) );
if( out != null )
{
Writer wri = null;
try
{
wri = new OutputStreamWriter( out, "UTF8" );
wri.write( "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" );
( new DOMElementWriter() ).write( rootElement, wri, 0, " " );
wri.flush();
}
catch( IOException exc )
{
throw new TaskException( "Unable to write log file", exc );
}
finally
{
if( out != System.out && out != System.err )
{
if( wri != null )
{
try
{
wri.close();
}
catch( IOException e )
{
}
}
}
}
}
}

/**
* Interface TestListener. <p>
*
* A new Test is started.
*
* @param t Description of Parameter
*/
public void startTest( Test t )
{
testStarts.put( t, new Long( System.currentTimeMillis() ) );

Element currentTest = doc.createElement( TESTCASE );
currentTest.setAttribute( ATTR_NAME,
JUnitVersionHelper.getTestCaseName( t ) );
rootElement.appendChild( currentTest );
testElements.put( t, currentTest );
}

/**
* The whole testsuite started.
*
* @param suite Description of Parameter
*/
public void startTestSuite( JUnitTest suite )
{
doc = getDocumentBuilder().newDocument();
rootElement = doc.createElement( TESTSUITE );
rootElement.setAttribute( ATTR_NAME, suite.getName() );

// Output properties
Element propsElement = doc.createElement( PROPERTIES );
rootElement.appendChild( propsElement );
Properties props = suite.getProperties();
if( props != null )
{
final Iterator e = props.keySet().iterator();
while( e.hasNext() )
{
final String name = (String)e.next();
final String value = props.getProperty( name );
final Element propElement = doc.createElement( PROPERTY );
propElement.setAttribute( ATTR_NAME, name );
propElement.setAttribute( ATTR_VALUE, value );
propsElement.appendChild( propElement );
}
}
}

private void formatError( String type, Test test, Throwable t )
{
if( test != null )
{
endTest( test );
}

Element nested = doc.createElement( type );
Element currentTest = null;
if( test != null )
{
currentTest = (Element)testElements.get( test );
}
else
{
currentTest = rootElement;
}

currentTest.appendChild( nested );

String message = t.getMessage();
if( message != null && message.length() > 0 )
{
nested.setAttribute( ATTR_MESSAGE, t.getMessage() );
}
nested.setAttribute( ATTR_TYPE, t.getClass().getName() );

String strace = JUnitTestRunner.getFilteredTrace( t );
Text trace = doc.createTextNode( strace );
nested.appendChild( trace );
}

private void formatOutput( String type, String output )
{
Element nested = doc.createElement( type );
rootElement.appendChild( nested );
Text content = doc.createTextNode( output );
nested.appendChild( content );
}

}// XMLJUnitResultFormatter

+ 0
- 336
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/XMLResultAggregator.java View File

@@ -1,336 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.avalon.framework.ExceptionUtil;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.framework.FileSet;
import org.apache.tools.todo.types.DirectoryScanner;
import org.apache.tools.todo.types.ScannerUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

/**
* <p>
*
* This is an helper class that will aggregate all testsuites under a specific
* directory and create a new single document. It is not particulary clean but
* should be helpful while I am thinking about another technique. <p>
*
* The main problem is due to the fact that a JVM can be forked for a testcase
* thus making it impossible to aggregate all testcases since the listener is
* (obviously) in the forked JVM. A solution could be to write a TestListener
* that will receive events from the TestRunner via sockets. This is IMHO the
* simplest way to do it to avoid this file hacking thing.
*
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a>
*/
public class XMLResultAggregator
extends AbstractTask
implements XMLConstants
{
/**
* the default directory: <tt>.</tt> . It is resolved from the project
* directory
*/
public final static String DEFAULT_DIR = ".";

/**
* the default file name: <tt>TESTS-TestSuites.xml</tt>
*/
public final static String DEFAULT_FILENAME = "TESTS-TestSuites.xml";

/**
* the list of all filesets, that should contains the xml to aggregate
*/
protected ArrayList filesets = new ArrayList();

protected ArrayList transformers = new ArrayList();

/**
* the directory to write the file to
*/
protected File toDir;

/**
* the name of the result file
*/
protected String toFile;

/**
* Create a new document builder. Will issue an <tt>
* ExceptionInitializerError</tt> if something is going wrong. It is fatal
* anyway.
*
* @return a new document builder to create a DOM
* @todo factorize this somewhere else. It is duplicated code.
*/
private static DocumentBuilder getDocumentBuilder()
{
try
{
return DocumentBuilderFactory.newInstance().newDocumentBuilder();
}
catch( Exception exc )
{
throw new ExceptionInInitializerError( exc );
}
}

/**
* Set the destination directory where the results should be written. If not
* set if will use {@link #DEFAULT_DIR}. When given a relative directory it
* will resolve it from the project directory.
*
* @param value the directory where to write the results, absolute or
* relative.
*/
public void setTodir( File value )
{
toDir = value;
}

/**
* Set the name of the file aggregating the results. It must be relative
* from the <tt>todir</tt> attribute. If not set it will use {@link
* #DEFAULT_FILENAME}
*
* @param value the name of the file.
* @see #setTodir(File)
*/
public void setTofile( String value )
{
toFile = value;
}

/**
* Add a new fileset containing the xml results to aggregate
*
* @param fs the new fileset of xml results.
*/
public void addFileSet( FileSet fs )
{
filesets.add( fs );
}

public AggregateTransformer createReport()
{
AggregateTransformer transformer = new AggregateTransformer( getContext() );
transformers.add( transformer );
return transformer;
}

/**
* Aggregate all testsuites into a single document and write it to the
* specified directory and file.
*
* @throws TaskException thrown if there is a serious error while writing
* the document.
*/
public void execute()
throws TaskException
{
final Element rootElement = createDocument();
File destFile = getDestinationFile();
// write the document
try
{
writeDOMTree( rootElement.getOwnerDocument(), destFile );
}
catch( IOException e )
{
throw new TaskException( "Unable to write test aggregate to '" + destFile + "'", e );
}
// apply transformation
Iterator enum = transformers.iterator();
while( enum.hasNext() )
{
AggregateTransformer transformer =
(AggregateTransformer)enum.next();
transformer.setXmlDocument( rootElement.getOwnerDocument() );
transformer.transform();
}
}

/**
* Get the full destination file where to write the result. It is made of
* the <tt>todir</tt> and <tt>tofile</tt> attributes.
*
* @return the destination file where should be written the result file.
*/
protected File getDestinationFile()
throws TaskException
{
if( toFile == null )
{
toFile = DEFAULT_FILENAME;
}
if( toDir == null )
{
toDir = getContext().resolveFile( DEFAULT_DIR );
}
return new File( toDir, toFile );
}

/**
* Get all <code>.xml</code> files in the fileset.
*
* @return all files in the fileset that end with a '.xml'.
*/
protected File[] getFiles()
throws TaskException
{
final ArrayList v = new ArrayList();
final int size = filesets.size();
for( int i = 0; i < size; i++ )
{
final FileSet fileSet = (FileSet)filesets.get( i );
final DirectoryScanner scanner = ScannerUtil.getDirectoryScanner( fileSet );
scanner.scan();
final String[] includes = scanner.getIncludedFiles();
for( int j = 0; j < includes.length; j++ )
{
final String pathname = includes[ j ];
if( pathname.endsWith( ".xml" ) )
{
File file = new File( scanner.getBasedir(), pathname );
file = getContext().resolveFile( file.getPath() );
v.add( file );
}
}
}

return (File[])v.toArray( new File[ v.size() ] );
}

/**
* <p>
*
* Add a new testsuite node to the document. The main difference is that it
* split the previous fully qualified name into a package and a name. <p>
*
* For example: <tt>org.apache.Whatever</tt> will be split into <tt>
* org.apache</tt> and <tt>Whatever</tt> .
*
* @param root the root element to which the <tt>testsuite</tt> node should
* be appended.
* @param testsuite the element to append to the given root. It will
* slightly modify the original node to change the name attribute and
* add a package one.
*/
protected void addTestSuite( Element root, Element testsuite )
{
String fullclassname = testsuite.getAttribute( ATTR_NAME );
int pos = fullclassname.lastIndexOf( '.' );

// a missing . might imply no package at all. Don't get fooled.
String pkgName = ( pos == -1 ) ? "" : fullclassname.substring( 0, pos );
String classname = ( pos == -1 ) ? fullclassname : fullclassname.substring( pos + 1 );
Element copy = (Element)DOMUtil.importNode( root, testsuite );

// modify the name attribute and set the package
copy.setAttribute( ATTR_NAME, classname );
copy.setAttribute( ATTR_PACKAGE, pkgName );
}

/**
* <p>
*
* Create a DOM tree. Has 'testsuites' as firstchild and aggregates all
* testsuite results that exists in the base directory.
*
* @return the root element of DOM tree that aggregates all testsuites.
*/
protected Element createDocument()
throws TaskException
{
// create the dom tree
DocumentBuilder builder = getDocumentBuilder();
Document doc = builder.newDocument();
Element rootElement = doc.createElement( TESTSUITES );
doc.appendChild( rootElement );

// get all files and add them to the document
final File[] files = getFiles();
for( int i = 0; i < files.length; i++ )
{
try
{
getContext().debug( "Parsing file: '" + files[ i ] + "'" );
//XXX there seems to be a bug in xerces 1.3.0 that doesn't like file object
// will investigate later. It does not use the given directory but
// the vm dir instead ? Works fine with crimson.
Document testsuiteDoc = builder.parse( "file:///" + files[ i ].getAbsolutePath() );
Element elem = testsuiteDoc.getDocumentElement();
// make sure that this is REALLY a testsuite.
if( TESTSUITE.equals( elem.getNodeName() ) )
{
addTestSuite( rootElement, elem );
}
else
{
// issue a warning.
getContext().warn( "the file " + files[ i ] + " is not a valid testsuite XML document" );
}
}
catch( SAXException e )
{
// a testcase might have failed and write a zero-length document,
// It has already failed, but hey.... mm. just put a warning
getContext().warn( "The file " + files[ i ] + " is not a valid XML document. It is possibly corrupted." );
getContext().debug( ExceptionUtil.printStackTrace( e ) );
}
catch( IOException e )
{
getContext().error( "Error while accessing file " + files[ i ] + ": " + e.getMessage() );
}
}
return rootElement;
}

//----- from now, the methods are all related to DOM tree manipulation

/**
* Write the DOM tree to a file.
*
* @param doc the XML document to dump to disk.
* @param file the filename to write the document to. Should obviouslly be a
* .xml file.
* @throws IOException thrown if there is an error while writing the
* content.
*/
protected void writeDOMTree( Document doc, File file )
throws IOException
{
OutputStream out = new FileOutputStream( file );
PrintWriter wri = new PrintWriter( new OutputStreamWriter( out, "UTF8" ) );
wri.write( "<?xml version=\"1.0\"?>\n" );
( new DOMElementWriter() ).write( doc.getDocumentElement(), wri, 0, " " );
wri.flush();
wri.close();
// writers do not throw exceptions, so check for them.
if( wri.checkError() )
{
throw new IOException( "Error while writing DOM content" );
}
}

}

+ 0
- 38
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/Xalan1Executor.java View File

@@ -1,38 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.OutputStream;
import org.apache.xalan.xslt.XSLTInputSource;
import org.apache.xalan.xslt.XSLTProcessor;
import org.apache.xalan.xslt.XSLTProcessorFactory;
import org.apache.xalan.xslt.XSLTResultTarget;

/**
* Xalan 1 executor. It will need a lot of things in the classpath: xerces for
* the serialization, xalan and bsf for the extension.
*
* @author RT
* @todo do everything via reflection to avoid compile problems ?
*/
public class Xalan1Executor extends XalanExecutor
{
void execute()
throws Exception
{
XSLTProcessor processor = XSLTProcessorFactory.getProcessor();
// need to quote otherwise it breaks because of "extra illegal tokens"
processor.setStylesheetParam( "output.dir", "'" + caller.getToDir().getAbsolutePath() + "'" );
XSLTInputSource xml_src = new XSLTInputSource( caller.getDocument() );
String system_id = caller.getStylesheetSystemId();
XSLTInputSource xsl_src = new XSLTInputSource( system_id );
OutputStream os = getOutputStream();
XSLTResultTarget target = new XSLTResultTarget( os );
processor.process( xml_src, xsl_src, target );
}
}

+ 0
- 40
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/Xalan2Executor.java View File

@@ -1,40 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.OutputStream;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

/**
* Xalan executor via JAXP. Nothing special must exists in the classpath besides
* of course, a parser, jaxp and xalan.
*
* @author RT
*/
public class Xalan2Executor extends XalanExecutor
{
void execute()
throws Exception
{
TransformerFactory tfactory = TransformerFactory.newInstance();
String system_id = caller.getStylesheetSystemId();
Source xsl_src = new StreamSource( system_id );
Transformer tformer = tfactory.newTransformer( xsl_src );
Source xml_src = new DOMSource( caller.getDocument() );
OutputStream os = getOutputStream();
tformer.setParameter( "output.dir", caller.getToDir().getAbsolutePath() );
Result result = new StreamResult( os );
tformer.transform( xml_src, result );
}
}

+ 0
- 127
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/junit/XalanExecutor.java View File

@@ -1,127 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.junit;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import org.apache.myrmidon.api.TaskException;

/**
* Command class that encapsulate specific behavior for each Xalan version. The
* right executor will be instantiated at runtime via class lookup. For
* instance, it will check first for Xalan2, then for Xalan1.
*
* @author RT
*/
abstract class XalanExecutor
{
/**
* the transformer caller
*/
protected AggregateTransformer caller;

/**
* Create a valid Xalan executor. It checks first if Xalan2 is present, if
* not it checks for xalan1. If none is available, it fails.
*
* @param caller object containing the transformation information.
* @return Description of the Returned Value
* @throws TaskException thrown if it could not find a valid xalan
* executor.
*/
static XalanExecutor newInstance( AggregateTransformer caller )
throws TaskException
{
Class procVersion = null;
XalanExecutor executor = null;
try
{
procVersion = Class.forName( "org.apache.xalan.processor.XSLProcessorVersion" );
executor = new Xalan2Executor();
}
catch( Exception xalan2missing )
{
try
{
procVersion = Class.forName( "org.apache.xalan.xslt.XSLProcessorVersion" );
executor = (XalanExecutor)Class.forName(
"org.apache.tools.ant.taskdefs.optional.junit.Xalan1Executor" ).newInstance();
}
catch( Exception xalan1missing )
{
throw new TaskException( "Could not find xalan2 nor xalan1 in the classpath. Check http://xml.apache.org/xalan-j" );
}
}
String version = getXalanVersion( procVersion );
//caller.task.getLogger().info( "Using Xalan version: " + version );
executor.setCaller( caller );
return executor;
}

/**
* pretty useful data (Xalan version information) to display.
*
* @param procVersion Description of Parameter
* @return The XalanVersion value
*/
private static String getXalanVersion( Class procVersion )
{
try
{
Field f = procVersion.getField( "S_VERSION" );
return f.get( null ).toString();
}
catch( Exception e )
{
return "?";
}
}

/**
* get the appropriate stream based on the format (frames/noframes)
*
* @return The OutputStream value
* @exception IOException Description of Exception
*/
protected OutputStream getOutputStream()
throws IOException
{
if( caller.FRAMES.equals( caller.getFormat() ) )
{
// dummy output for the framed report
// it's all done by extension...
return new ByteArrayOutputStream();
}
else
{
return new FileOutputStream( new File( caller.getToDir(), "junit-noframes.html" ) );
}
}

/**
* override to perform transformation
*
* @exception Exception Description of Exception
*/
abstract void execute()
throws Exception;

/**
* set the caller for this object.
*
* @param caller The new Caller value
*/
private final void setCaller( AggregateTransformer caller )
{
this.caller = caller;
}
}

+ 0
- 117
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/Attribute.java View File

@@ -1,117 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.manifest;

/**
* Class to hold manifest attributes
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @author Conor MacNeill
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$ $Date$
*/
public class Attribute
{
/**
* The attribute's name
*/
private String m_name;

/**
* The attribute's value
*/
private String m_value;

/**
* Construct an empty attribute
*/
public Attribute()
{
}

/**
* Construct a manifest by specifying its name and value
*
* @param name the attribute's name
* @param value the Attribute's value
*/
public Attribute( final String name, final String value )
{
m_name = name;
m_value = value;
}

/**
* Set the Attribute's name
*
* @param name the attribute's name
*/
public void setName( final String name )
{
m_name = name;
}

/**
* Set the Attribute's value
*
* @param value the attribute's value
*/
public void setValue( final String value )
{
m_value = value;
}

/**
* Get the Attribute's name
*
* @return the attribute's name.
*/
public String getName()
{
return m_name;
}

/**
* Get the Attribute's value
*
* @return the attribute's value.
*/
public String getValue()
{
return m_value;
}

/**
* Add a continuation line from the Manifest file When lines are too
* long in a manifest, they are continued on the next line by starting
* with a space. This method adds the continuation data to the attribute
* value by skipping the first character.
*
* @param line The feature to be added to the Continuation attribute
*/
public void addContinuation( final String line )
{
m_value += line.substring( 1 );
}

public boolean equals( Object object )
{
if( !( object instanceof Attribute ) )
{
return false;
}

final Attribute other = (Attribute)object;
final String name = other.m_name;
return
( null != m_name && null != name &&
m_name.toLowerCase().equals( name.toLowerCase() ) &&
null != m_value && m_value.equals( other.m_value ) );
}

}

+ 0
- 175
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/Manifest.java View File

@@ -1,175 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.manifest;

import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import org.apache.myrmidon.api.TaskException;

/**
* Class to manage Manifest information
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @author Conor MacNeill
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$ $Date$
*/
public class Manifest
{
/**
* The version of this manifest
*/
private String m_manifestVersion = ManifestUtil.DEFAULT_MANIFEST_VERSION;

/**
* The main section of this manifest
*/
private Section m_mainSection = new Section();

/**
* The named sections of this manifest
*/
private Hashtable m_sections = new Hashtable();

public void setManifestVersion( final String manifestVersion )
{
m_manifestVersion = manifestVersion;
}

public void setMainSection( final Section mainSection )
{
m_mainSection = mainSection;
}

public void addAttribute( final Attribute attribute )
throws ManifestException
{
m_mainSection.addAttribute( attribute );
}

public void addSection( final Section section )
throws ManifestException
{
if( section.getName() == null )
{
final String message = "Sections must have a name";
throw new ManifestException( message );
}
m_sections.put( section.getName().toLowerCase(), section );
}

public String[] getSectionNames( final Manifest other )
{
final Set keys = other.m_sections.keySet();
return (String[])keys.toArray( new String[ keys.size() ] );
}

public String getManifestVersion()
{
return m_manifestVersion;
}

public Section getMainSection()
{
return m_mainSection;
}

public Section getSection( final String name )
{
return (Section)m_sections.get( name );
}

public Section[] getSections()
{
final Collection sections = m_sections.values();
return (Section[])sections.toArray( new Section[ sections.size() ] );
}

/**
* Merge the contents of the given manifest into this manifest
*
* @param other the Manifest to be merged with this one.
* @throws org.apache.tools.todo.taskdefs.manifest.ManifestException if there is a problem merging the manfest
* according to the Manifest spec.
*/
public void merge( final Manifest other )
throws ManifestException
{
if( other.m_manifestVersion != null )
{
m_manifestVersion = other.m_manifestVersion;
}
m_mainSection.merge( other.m_mainSection );

mergeSections( other );
}

public boolean equals( final Object object )
{
if( !( object instanceof Manifest ) )
{
return false;
}

final Manifest other = (Manifest)object;
if( m_manifestVersion == null && other.m_manifestVersion != null )
{
return false;
}
else if( !m_manifestVersion.equals( other.m_manifestVersion ) )
{
return false;
}
if( m_sections.size() != other.m_sections.size() )
{
return false;
}

if( !m_mainSection.equals( other.m_mainSection ) )
{
return false;
}

final Iterator e = m_sections.values().iterator();
while( e.hasNext() )
{
final Section section = (Section)e.next();
final String key = section.getName().toLowerCase();
final Section otherSection = (Section)other.m_sections.get( key );
if( !section.equals( otherSection ) )
{
return false;
}
}

return true;
}

private void mergeSections( final Manifest other )
throws ManifestException
{
final String[] sections = getSectionNames( other );
for( int i = 0; i < sections.length; i++ )
{
final String sectionName = sections[ i ];
final Section section = getSection( sectionName );
final Section otherSection = other.getSection( sectionName );
if( section == null )
{
m_sections.put( sectionName.toLowerCase(), otherSection );
}
else
{
section.merge( otherSection );
}
}
}
}

+ 0
- 64
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/ManifestException.java View File

@@ -1,64 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.manifest;

/**
* ManifestException is thrown when there is a problem parsing, generating or
* handling a Manifest.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class ManifestException
extends Exception
{
/**
* The Throwable that caused this exception to be thrown.
*/
private final Throwable m_throwable;

/**
* Basic constructor for exception that does not specify a message
*/
public ManifestException()
{
this( "", null );
}

/**
* Basic constructor with a message
*
* @param message the message
*/
public ManifestException( final String message )
{
this( message, null );
}

/**
* Constructor that builds cascade so that other exception information can be retained.
*
* @param message the message
* @param throwable the throwable
*/
public ManifestException( final String message, final Throwable throwable )
{
super( message );
m_throwable = throwable;
}

/**
* Retrieve root cause of the exception.
*
* @return the root cause
*/
public final Throwable getCause()
{
return m_throwable;
}
}

+ 0
- 27
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/ManifestMode.java View File

@@ -1,27 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.manifest;

import org.apache.tools.todo.types.EnumeratedAttribute;

/**
* Helper class for Manifest's mode attribute.
*
* @author Conor MacNeill
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class ManifestMode
extends EnumeratedAttribute
{
public String[] getValues()
{
return new String[]{"update", "replace"};
}
}

+ 0
- 198
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/ManifestTask.java View File

@@ -1,198 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.manifest;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.avalon.excalibur.io.IOUtil;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.todo.taskdefs.manifest.Manifest;
import org.apache.tools.todo.taskdefs.manifest.Section;

/**
* Class to manage Manifest information
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @author Conor MacNeill
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @version $Revision$ $Date$
*/
public class ManifestTask
extends AbstractTask
{
private File m_destFile;
private ManifestMode m_mode;
private Manifest m_manifest = new Manifest();

/**
* Construct an empty manifest
*/
public ManifestTask()
throws TaskException
{
m_mode = new ManifestMode();
m_mode.setValue( "replace" );
}

/**
* The name of the manifest file to write.
*/
public void setDestFile( final File destFile )
{
m_destFile = destFile;
}

/**
* Shall we update or replace an existing manifest?
*/
public void setMode( final ManifestMode mode )
{
m_mode = mode;
}

public void setManifestVersion( String manifestVersion )
{
m_manifest.setManifestVersion( manifestVersion );
}

public void addMainSection( Section mainSection )
throws Exception
{
m_manifest.setMainSection( mainSection );
}

/**
* Get the warnings for this manifest.
*
* @return an enumeration of warning strings
*/
public Iterator getWarnings()
{
ArrayList warnings = new ArrayList();

for( Iterator e2 = m_manifest.getMainSection().getWarnings(); e2.hasNext(); )
{
warnings.add( e2.next() );
}

final Section[] sections = m_manifest.getSections();
for( int i = 0; i < sections.length; i++ )
{
final Section section = sections[ i ];
for( Iterator e2 = section.getWarnings(); e2.hasNext(); )
{
warnings.add( e2.next() );
}
}

return warnings.iterator();
}

public void addAttribute( final Attribute attribute )
throws ManifestException, TaskException
{
m_manifest.addAttribute( attribute );
}

public void addSection( final Section section )
throws TaskException
{
try
{
m_manifest.addSection( section );
}
catch( final ManifestException me )
{
throw new TaskException( me.getMessage(), me );
}
}

/**
* Create or update the Manifest when used as a task.
*
* @exception org.apache.myrmidon.api.TaskException Description of Exception
*/
public void execute()
throws TaskException
{
if( null == m_destFile )
{
throw new TaskException( "the file attribute is required" );
}

Manifest toWrite = getDefaultManifest();

if( m_mode.getValue().equals( "update" ) && m_destFile.exists() )
{
FileReader f = null;
try
{
f = new FileReader( m_destFile );
final Manifest other = ManifestUtil.buildManifest( f );
toWrite.merge( other );
}
catch( ManifestException m )
{
throw new TaskException( "Existing manifest " + m_destFile
+ " is invalid", m );
}
catch( IOException e )
{
throw new
TaskException( "Failed to read " + m_destFile, e );
}
finally
{
IOUtil.shutdownReader( f );
}
}

try
{
toWrite.merge( m_manifest );
}
catch( ManifestException m )
{
throw new TaskException( "Manifest is invalid", m );
}

PrintWriter w = null;
try
{
w = new PrintWriter( new FileWriter( m_destFile ) );
ManifestUtil.write( toWrite, w );
}
catch( IOException e )
{
throw new TaskException( "Failed to write " + m_destFile, e );
}
finally
{
IOUtil.shutdownWriter( w );
}
}

private Manifest getDefaultManifest()
throws TaskException
{
try
{
return ManifestUtil.getDefaultManifest();
}
catch( final ManifestException me )
{
throw new TaskException( me.getMessage(), me );
}
}
}

+ 0
- 242
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/ManifestUtil.java View File

@@ -1,242 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.manifest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.jar.Attributes;
import org.apache.tools.todo.taskdefs.manifest.Manifest;
import org.apache.tools.todo.taskdefs.manifest.Section;
import org.apache.tools.todo.taskdefs.manifest.Attribute;

/**
* Utility methods for manifest stuff.
*
* @author Conor MacNeill
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public final class ManifestUtil
{
/**
* The Name Attribute is the first in a named section
*/
public final static String ATTRIBUTE_NAME = "Name";
/**
* The From Header is disallowed in a Manifest
*/
public final static String ATTRIBUTE_FROM = "From";
/**
* The Class-Path Header is special - it can be duplicated
*/
public final static String ATTRIBUTE_CLASSPATH = Attributes.Name.CLASS_PATH.toString();
/**
* Default Manifest version if one is not specified
*/
public final static String DEFAULT_MANIFEST_VERSION = "1.0";
/**
* The max length of a line in a Manifest
*/
public final static int MAX_LINE_LENGTH = 70;

public static Attribute buildAttribute( final String line )
throws ManifestException
{
final Attribute attribute = new Attribute();
parse( attribute, line );
return attribute;
}

public static Manifest buildManifest( final Reader reader )
throws ManifestException, IOException
{
final Manifest manifest = new Manifest();
BufferedReader bufferedReader = new BufferedReader( reader );
// This should be the manifest version
final Section mainSection = manifest.getMainSection();
String nextSectionName = mainSection.read( bufferedReader );
final String readManifestVersion =
mainSection.getAttributeValue( Attributes.Name.MANIFEST_VERSION.toString() );
if( readManifestVersion != null )
{
manifest.setManifestVersion( readManifestVersion );
mainSection.removeAttribute( Attributes.Name.MANIFEST_VERSION.toString() );
}

String line = null;
while( ( line = bufferedReader.readLine() ) != null )
{
if( line.length() == 0 )
{
continue;
}

Section section = new Section();
if( nextSectionName == null )
{
Attribute sectionName = ManifestUtil.buildAttribute( line );
if( !sectionName.getName().equalsIgnoreCase( ManifestUtil.ATTRIBUTE_NAME ) )
{
throw new ManifestException( "Manifest sections should start with a \"" + ManifestUtil.ATTRIBUTE_NAME +
"\" attribute and not \"" + sectionName.getName() + "\"" );
}
nextSectionName = sectionName.getValue();
}
else
{
// we have already started reading this section
// this line is the first attribute. set it and then let the normal
// read handle the rest
Attribute firstAttribute = ManifestUtil.buildAttribute( line );
section.addAttributeAndCheck( firstAttribute );
}

section.setName( nextSectionName );
nextSectionName = section.read( bufferedReader );
manifest.addSection( section );
}

return manifest;
}

/**
* Construct a manifest from Ant's default manifest file.
*/
public static Manifest getDefaultManifest()
throws ManifestException
{
try
{
final InputStream input = getInputStream();
final InputStreamReader reader = getReader( input );
return buildManifest( reader );
}
catch( final IOException ioe )
{
throw new ManifestException( "Unable to read default manifest", ioe );
}
}

private static InputStream getInputStream()
throws ManifestException
{
final String location = "default.mf";
final InputStream input = ManifestUtil.class.getResourceAsStream( location );
if( null == input )
{
throw new ManifestException( "Could not find default manifest: " + location );
}
return input;
}

private static InputStreamReader getReader( final InputStream input )
{
try
{
return new InputStreamReader( input, "ASCII" );
}
catch( final UnsupportedEncodingException uee )
{
return new InputStreamReader( input );
}
}

/**
* Parse a line into name and value pairs
*
* @param line the line to be parsed
* @throws org.apache.tools.todo.taskdefs.manifest.ManifestException if the line does not contain a colon
* separating the name and value
*/
public static void parse( final Attribute attribute, final String line )
throws ManifestException
{
final int index = line.indexOf( ": " );
if( index == -1 )
{
throw new ManifestException( "Manifest line \"" + line + "\" is not valid as it does not " +
"contain a name and a value separated by ': ' " );
}
final String name = line.substring( 0, index );
final String value = line.substring( index + 2 );
attribute.setName( name );
attribute.setValue( value );
}

public static void write( final Attribute attribute, final PrintWriter writer )
throws IOException
{
final String name = attribute.getName();
final String value = attribute.getValue();
String line = name + ": " + value;
while( line.getBytes().length > MAX_LINE_LENGTH )
{
// try to find a MAX_LINE_LENGTH byte section
int breakIndex = MAX_LINE_LENGTH;
String section = line.substring( 0, breakIndex );
while( section.getBytes().length > MAX_LINE_LENGTH && breakIndex > 0 )
{
breakIndex--;
section = line.substring( 0, breakIndex );
}
if( breakIndex == 0 )
{
throw new IOException( "Unable to write manifest line " + name + ": " + value );
}
writer.println( section );
line = " " + line.substring( breakIndex );
}
writer.println( line );
}

/**
* Write the manifest out to a print writer.
*
* @param writer the Writer to which the manifest is written
* @throws java.io.IOException if the manifest cannot be written
*/
public static void write( Manifest manifest, PrintWriter writer )
throws IOException
{
final String sigVersionKey = Attributes.Name.SIGNATURE_VERSION.toString();

writer.println( Attributes.Name.MANIFEST_VERSION + ": " + manifest.getManifestVersion() );

final String signatureVersion =
manifest.getMainSection().getAttributeValue( sigVersionKey );
if( signatureVersion != null )
{
writer.println( Attributes.Name.SIGNATURE_VERSION + ": " + signatureVersion );
manifest.getMainSection().removeAttribute( sigVersionKey );
}
manifest.getMainSection().write( writer );
if( signatureVersion != null )
{
try
{
manifest.getMainSection().addAttribute( new Attribute( sigVersionKey, signatureVersion ) );
}
catch( ManifestException e )
{
// shouldn't happen - ignore
}
}

final Section[] sections = manifest.getSections();
for( int i = 0; i < sections.length; i++ )
{
sections[ i ].write( writer );
}
}
}

+ 0
- 334
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/Section.java View File

@@ -1,334 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.manifest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;

/**
* Class to represent an individual section in the Manifest. A section
* consists of a set of attribute values, separated from other sections by a
* blank line.
*
* @author Conor MacNeill
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class Section
{
private final ArrayList m_warnings = new ArrayList();

/**
* The section's name if any. The main section in a manifest is unnamed.
*/
private String m_name;

/**
* The section's attributes.
*/
private final Hashtable m_attributes = new Hashtable();

/**
* Set the Section's name
*
* @param name the section's name
*/
public void setName( final String name )
{
m_name = name;
}

/**
* Get the value of the attribute with the name given.
*
* @param attributeName the name of the attribute to be returned.
* @return the attribute's value or null if the attribute does not exist
* in the section
*/
public String getAttributeValue( final String attributeName )
{
final Object attributeObject = m_attributes.get( attributeName.toLowerCase() );
if( null == attributeObject )
{
return null;
}
else if( attributeObject instanceof Attribute )
{
final Attribute attribute = (Attribute)attributeObject;
return attribute.getValue();
}
else
{
String value = "";
final ArrayList attributes = (ArrayList)attributeObject;
Iterator e = attributes.iterator();
while( e.hasNext() )
{
final Attribute classpathAttribute = (Attribute)e.next();
value += classpathAttribute.getValue() + " ";
}
return value.trim();
}
}

/**
* Get the Section's name
*
* @return the section's name.
*/
public String getName()
{
return m_name;
}

public Iterator getWarnings()
{
return m_warnings.iterator();
}

/**
* Add an attribute to the section
*
* @param attribute the attribute to be added.
* @return the value of the attribute if it is a name attribute - null
* other wise
* @throws org.apache.tools.todo.taskdefs.manifest.ManifestException if the attribute already exists in this
* section.
*/
public String addAttributeAndCheck( Attribute attribute )
throws ManifestException
{
if( attribute.getName() == null || attribute.getValue() == null )
{
throw new ManifestException( "Attributes must have name and value" );
}
if( attribute.getName().equalsIgnoreCase( ManifestUtil.ATTRIBUTE_NAME ) )
{
m_warnings.add( "\"" + ManifestUtil.ATTRIBUTE_NAME + "\" attributes should not occur in the " +
"main section and must be the first element in all " +
"other sections: \"" + attribute.getName() + ": " + attribute.getValue() + "\"" );
return attribute.getValue();
}

if( attribute.getName().toLowerCase().startsWith( ManifestUtil.ATTRIBUTE_FROM.toLowerCase() ) )
{
m_warnings.add( "Manifest attributes should not start with \"" +
ManifestUtil.ATTRIBUTE_FROM + "\" in \"" + attribute.getName() + ": " + attribute.getValue() + "\"" );
}
else
{
// classpath attributes go into a vector
String attributeName = attribute.getName().toLowerCase();
if( attributeName.equals( ManifestUtil.ATTRIBUTE_CLASSPATH ) )
{
ArrayList classpathAttrs = (ArrayList)m_attributes.get( attributeName );
if( classpathAttrs == null )
{
classpathAttrs = new ArrayList();
m_attributes.put( attributeName, classpathAttrs );
}
classpathAttrs.add( attribute );
}
else if( m_attributes.containsKey( attributeName ) )
{
throw new ManifestException( "The attribute \"" + attribute.getName() + "\" may not " +
"occur more than once in the same section" );
}
else
{
m_attributes.put( attributeName, attribute );
}
}
return null;
}

public void addAttribute( final Attribute attribute )
throws ManifestException
{
String check = addAttributeAndCheck( attribute );
if( check != null )
{
throw new ManifestException( "Specify the section name using the \"name\" attribute of the <section> element rather " +
"than using a \"Name\" manifest attribute" );
}
}

public boolean equals( Object rhs )
{
if( !( rhs instanceof Section ) )
{
return false;
}

Section rhsSection = (Section)rhs;
if( m_attributes.size() != rhsSection.m_attributes.size() )
{
return false;
}

for( Enumeration e = m_attributes.elements(); e.hasMoreElements(); )
{
Attribute attribute = (Attribute)e.nextElement();
Attribute rshAttribute = (Attribute)rhsSection.m_attributes.get( attribute.getName().toLowerCase() );
if( !attribute.equals( rshAttribute ) )
{
return false;
}
}

return true;
}

/**
* Merge in another section
*
* @param section the section to be merged with this one.
* @throws org.apache.tools.todo.taskdefs.manifest.ManifestException if the sections cannot be merged.
*/
public void merge( Section section )
throws ManifestException
{
if( m_name == null && section.getName() != null ||
m_name != null && !( m_name.equalsIgnoreCase( section.getName() ) ) )
{
throw new ManifestException( "Unable to merge sections with different names" );
}

for( Enumeration e = section.m_attributes.keys(); e.hasMoreElements(); )
{
String attributeName = (String)e.nextElement();
if( attributeName.equals( ManifestUtil.ATTRIBUTE_CLASSPATH ) &&
m_attributes.containsKey( attributeName ) )
{
// classpath entries are vetors which are merged
ArrayList classpathAttrs = (ArrayList)section.m_attributes.get( attributeName );
ArrayList ourClasspathAttrs = (ArrayList)m_attributes.get( attributeName );
for( Iterator e2 = classpathAttrs.iterator(); e2.hasNext(); )
{
ourClasspathAttrs.add( e2.next() );
}
}
else
{
// the merge file always wins
m_attributes.put( attributeName, section.m_attributes.get( attributeName ) );
}
}

// add in the warnings
for( Iterator e = section.m_warnings.iterator(); e.hasNext(); )
{
m_warnings.add( e.next() );
}
}

/**
* Read a section through a reader
*
* @param reader the reader from which the section is read
* @return the name of the next section if it has been read as part of
* this section - This only happens if the Manifest is malformed.
* @throws org.apache.tools.todo.taskdefs.manifest.ManifestException if the section is not valid according to
* the JAR spec
* @throws java.io.IOException if the section cannot be read from the reader.
*/
public String read( BufferedReader reader )
throws ManifestException, IOException
{
Attribute attribute = null;
while( true )
{
String line = reader.readLine();
if( line == null || line.length() == 0 )
{
return null;
}
if( line.charAt( 0 ) == ' ' )
{
// continuation line
if( attribute == null )
{
if( m_name != null )
{
// a continuation on the first line is a continuation of the name - concatenate
// this line and the name
m_name += line.substring( 1 );
}
else
{
throw new ManifestException( "Can't start an attribute with a continuation line " + line );
}
}
else
{
attribute.addContinuation( line );
}
}
else
{
attribute = ManifestUtil.buildAttribute( line );
String nameReadAhead = addAttributeAndCheck( attribute );
if( nameReadAhead != null )
{
return nameReadAhead;
}
}
}
}

/**
* Remove tge given attribute from the section
*
* @param attributeName the name of the attribute to be removed.
*/
public void removeAttribute( String attributeName )
{
m_attributes.remove( attributeName.toLowerCase() );
}

/**
* Write the section out to a print writer.
*
* @param writer the Writer to which the section is written
* @throws java.io.IOException if the section cannot be written
*/
public void write( PrintWriter writer )
throws IOException
{
if( m_name != null )
{
Attribute nameAttr = new Attribute( ManifestUtil.ATTRIBUTE_NAME, m_name );
ManifestUtil.write( nameAttr, writer );
}
for( Enumeration e = m_attributes.elements(); e.hasMoreElements(); )
{
Object object = e.nextElement();
if( object instanceof Attribute )
{
Attribute attribute = (Attribute)object;
ManifestUtil.write( attribute, writer );
}
else
{
ArrayList attrList = (ArrayList)object;
for( Iterator e2 = attrList.iterator(); e2.hasNext(); )
{
Attribute attribute = (Attribute)e2.next();
ManifestUtil.write( attribute, writer );
}
}
}
writer.println();
}
}

+ 0
- 3
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/manifest/default.mf View File

@@ -1,3 +0,0 @@
Manifest-Version: 1.0
Created-By: Apache Ant @VERSION@


+ 0
- 54
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/net/Action.java View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.net;

import java.util.Locale;
import org.apache.tools.todo.types.EnumeratedAttribute;

public class Action
extends EnumeratedAttribute
{
private final static String[] validActions = new String[]
{
"send", "put", "recv", "get", "del", "delete", "list", "mkdir"
};

public int getAction()
{
String actionL = getValue().toLowerCase( Locale.US );
if( actionL.equals( "send" ) ||
actionL.equals( "put" ) )
{
return FTP.SEND_FILES;
}
else if( actionL.equals( "recv" ) ||
actionL.equals( "get" ) )
{
return FTP.GET_FILES;
}
else if( actionL.equals( "del" ) ||
actionL.equals( "delete" ) )
{
return FTP.DEL_FILES;
}
else if( actionL.equals( "list" ) )
{
return FTP.LIST_FILES;
}
else if( actionL.equals( "mkdir" ) )
{
return FTP.MK_DIR;
}
return FTP.SEND_FILES;
}

public String[] getValues()
{
return validActions;
}
}

+ 0
- 63
proposal/myrmidon/src/todo/org/apache/tools/todo/taskdefs/net/AntTelnetClient.java View File

@@ -1,63 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.todo.taskdefs.net;

import com.oroinc.net.telnet.TelnetClient;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.myrmidon.api.TaskException;

/**
* This class handles the abstraction of the telnet protocol. Currently it
* is a wrapper around <a href="www.oroinc.com">ORO</a> 's NetComponents
*/
public class AntTelnetClient
extends TelnetClient
{
private TelnetTask m_task;

public AntTelnetClient( final TelnetTask task )
{
m_task = task;
}

/**
* Write this string to the telnet session.
*/
public void sendString( final String string, final boolean echoString )
throws TaskException
{
final OutputStream output = this.getOutputStream();
m_task.doSendString( output, string, echoString );
}

/**
* Read from the telnet session until the string we are waiting for is
* found
*/
public void waitForString( final String string )
throws TaskException
{
waitForString( string, null );
}

/**
* Read from the telnet session until the string we are waiting for is
* found or the timeout has been reached
*
* @parm s The string to wait on
* @parm timeout The maximum number of seconds to wait
*/
public void waitForString( final String string,
final Integer timeout )
throws TaskException
{
final InputStream input = this.getInputStream();
m_task.doWaitForString( input, string, timeout );
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save