Browse Source

This is a major change. :-)

It introduces the concept of a TaskContainer to allow a task to contain
other tasks. This allows Task composition
It introduces a <parallel> task for multithreading support. There is
also a <sequential> task.
It reworks System.out management to handle all task generated output
and route it through the Ant event system. This handles multithreaded
output.

This is a major rework to the patch originally submitted by Thomas. I
have taken a different route for the output management, in particular.

Based on patch by Thomas Christen <chr@active.ch>


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269371 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 24 years ago
parent
commit
059ad35916
18 changed files with 729 additions and 165 deletions
  1. +151
    -0
      src/main/org/apache/tools/ant/DemuxOutputStream.java
  2. +52
    -34
      src/main/org/apache/tools/ant/Main.java
  3. +24
    -18
      src/main/org/apache/tools/ant/Project.java
  4. +37
    -20
      src/main/org/apache/tools/ant/ProjectHelper.java
  5. +14
    -18
      src/main/org/apache/tools/ant/Target.java
  6. +31
    -0
      src/main/org/apache/tools/ant/Task.java
  7. +70
    -0
      src/main/org/apache/tools/ant/TaskContainer.java
  8. +2
    -15
      src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
  9. +29
    -3
      src/main/org/apache/tools/ant/taskdefs/Java.java
  10. +179
    -0
      src/main/org/apache/tools/ant/taskdefs/Parallel.java
  11. +92
    -0
      src/main/org/apache/tools/ant/taskdefs/Sequential.java
  12. +0
    -11
      src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java
  13. +2
    -0
      src/main/org/apache/tools/ant/taskdefs/defaults.properties
  14. +0
    -11
      src/main/org/apache/tools/ant/taskdefs/optional/Javah.java
  15. +22
    -2
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
  16. +24
    -9
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
  17. +0
    -12
      src/main/org/apache/tools/ant/taskdefs/rmic/KaffeRmic.java
  18. +0
    -12
      src/main/org/apache/tools/ant/taskdefs/rmic/WLRmic.java

+ 151
- 0
src/main/org/apache/tools/ant/DemuxOutputStream.java View File

@@ -0,0 +1,151 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

package org.apache.tools.ant;

import java.io.*;
import java.util.*;


/**
* Logs content written by a thread and forwards the buffers onto the
* project object which will forward the content to the appropriate
* task
*
* @author Conor MacNeill
*/
public class DemuxOutputStream extends OutputStream {

static private final int MAX_SIZE = 1024;
private Hashtable buffers = new Hashtable();
// private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
private boolean skip = false;
private Project project;
private boolean isErrorStream;
/**
* Creates a new instance of this class.
*
* @param task the task for whom to log
* @param level loglevel used to log data written to this stream.
*/
public DemuxOutputStream(Project project, boolean isErrorStream) {
this.project = project;
this.isErrorStream = isErrorStream;
}

private ByteArrayOutputStream getBuffer() {
Thread current = Thread.currentThread();
ByteArrayOutputStream buffer = (ByteArrayOutputStream)buffers.get(current);
if (buffer == null) {
buffer = new ByteArrayOutputStream();
buffers.put(current, buffer);
}
return buffer;
}

private void resetBuffer() {
Thread current = Thread.currentThread();
buffers.remove(current);
}
/**
* Write the data to the buffer and flush the buffer, if a line
* separator is detected.
*
* @param cc data to log (byte).
*/
public void write(int cc) throws IOException {
final byte c = (byte)cc;
if ((c == '\n') || (c == '\r')) {
if (!skip) {
processBuffer();
}
} else {
ByteArrayOutputStream buffer = getBuffer();
buffer.write(cc);
if (buffer.size() > MAX_SIZE) {
processBuffer();
}
}
skip = (c == '\r');
}


/**
* Converts the buffer to a string and sends it to <code>processLine</code>
*/
protected void processBuffer() {
String output = getBuffer().toString();
project.demuxOutput(output, isErrorStream);
resetBuffer();
}

/**
* Writes all remaining
*/
public void close() throws IOException {
flush();
}

/**
* Writes all remaining
*/
public void flush() throws IOException {
if (getBuffer().size() > 0) {
processBuffer();
}
}
}

+ 52
- 34
src/main/org/apache/tools/ant/Main.java View File

@@ -267,7 +267,14 @@ public class Main {
System.out.println("Only one logger class may be specified.");
return;
}
loggerClassname = args[++i];
try {
loggerClassname = args[++i];
}
catch (ArrayIndexOutOfBoundsException aioobe) {
System.out.println("You must specify a classname when " +
"using the -logger argument");
return;
}
} else if (arg.equals("-emacs")) {
emacsMode = true;
} else if (arg.equals("-projecthelp")) {
@@ -403,43 +410,54 @@ public class Main {
try {
addBuildListeners(project);

project.fireBuildStarted();
project.init();
project.setUserProperty("ant.version", getAntVersion());

// set user-define properties
Enumeration e = definedProps.keys();
while (e.hasMoreElements()) {
String arg = (String)e.nextElement();
String value = (String)definedProps.get(arg);
project.setUserProperty(arg, value);
}

project.setUserProperty("ant.file" , buildFile.getAbsolutePath() );

// first use the ProjectHelper to create the project object
// from the given build file.
PrintStream err = System.err;
PrintStream out = System.out;
try {
Class.forName("javax.xml.parsers.SAXParserFactory");
ProjectHelper.configureProject(project, buildFile);
} catch (NoClassDefFoundError ncdfe) {
throw new BuildException("No JAXP compliant XML parser found. See http://java.sun.com/xml for the\nreference implementation.", ncdfe);
} catch (ClassNotFoundException cnfe) {
throw new BuildException("No JAXP compliant XML parser found. See http://java.sun.com/xml for the\nreference implementation.", cnfe);
} catch (NullPointerException npe) {
throw new BuildException("No JAXP compliant XML parser found. See http://java.sun.com/xml for the\nreference implementation.", npe);
System.setOut(new PrintStream(new DemuxOutputStream(project, false)));
System.setErr(new PrintStream(new DemuxOutputStream(project, true)));
project.fireBuildStarted();
project.init();
project.setUserProperty("ant.version", getAntVersion());

// set user-define properties
Enumeration e = definedProps.keys();
while (e.hasMoreElements()) {
String arg = (String)e.nextElement();
String value = (String)definedProps.get(arg);
project.setUserProperty(arg, value);
}
project.setUserProperty("ant.file" , buildFile.getAbsolutePath() );
// first use the ProjectHelper to create the project object
// from the given build file.
try {
Class.forName("javax.xml.parsers.SAXParserFactory");
ProjectHelper.configureProject(project, buildFile);
} catch (NoClassDefFoundError ncdfe) {
throw new BuildException("No JAXP compliant XML parser found. See http://java.sun.com/xml for the\nreference implementation.", ncdfe);
} catch (ClassNotFoundException cnfe) {
throw new BuildException("No JAXP compliant XML parser found. See http://java.sun.com/xml for the\nreference implementation.", cnfe);
} catch (NullPointerException npe) {
throw new BuildException("No JAXP compliant XML parser found. See http://java.sun.com/xml for the\nreference implementation.", npe);
}
// make sure that we have a target to execute
if (targets.size() == 0) {
targets.addElement(project.getDefaultTarget());
}
if (!projectHelp) {
project.executeTargets(targets);
}
}

// make sure that we have a target to execute
if (targets.size() == 0) {
targets.addElement(project.getDefaultTarget());
finally {
System.setOut(out);
System.setErr(err);
}

if (projectHelp) {
printTargets(project);
} else {
// actually do some work
project.executeTargets(targets);
printTargets(project);
}
}
catch(RuntimeException exc) {


+ 24
- 18
src/main/org/apache/tools/ant/Project.java View File

@@ -113,6 +113,9 @@ public class Project {

/** The system classloader - may be null */
private ClassLoader systemLoader = null;

/** Records the latest task on a thread */
private Hashtable threadTasks = new Hashtable();
static {

@@ -525,6 +528,21 @@ public class Project {
}
}

public void demuxOutput(String line, boolean isError) {
Task task = (Task)threadTasks.get(Thread.currentThread());
if (task == null) {
fireMessageLogged(this, line, isError ? MSG_ERR : MSG_INFO);
}
else {
if (isError) {
task.handleOutput(line);
}
else {
task.handleErrorOutput(line);
}
}
}
public void executeTarget(String targetName) throws BuildException {

// sanity check ourselves, if we've been asked to build nothing
@@ -547,7 +565,7 @@ public class Project {

do {
curtarget = (Target) sortedTargets.elementAt(curidx++);
runTarget(curtarget);
curtarget.performTasks();
} while (!curtarget.getName().equals(targetName));
}

@@ -903,23 +921,6 @@ public class Project {
s.equalsIgnoreCase("yes"));
}

// Given a string defining a target name, and a Hashtable
// containing the "name to Target" mapping, pick out the
// Target and execute it.
public void runTarget(Target target)
throws BuildException {

try {
fireTargetStarted(target);
target.execute();
fireTargetFinished(target, null);
}
catch(RuntimeException exc) {
fireTargetFinished(target, exc);
throw exc;
}
}

/**
* Topologically sort a set of Targets.
* @param root is the (String) name of the root Target. The sort is
@@ -1084,6 +1085,8 @@ public class Project {
}

protected void fireTaskStarted(Task task) {
// register this as the current task on the current thread.
threadTasks.put(Thread.currentThread(), task);
BuildEvent event = new BuildEvent(task);
for (int i = 0; i < listeners.size(); i++) {
BuildListener listener = (BuildListener) listeners.elementAt(i);
@@ -1092,6 +1095,9 @@ public class Project {
}

protected void fireTaskFinished(Task task, Throwable exception) {
threadTasks.remove(Thread.currentThread());
System.out.flush();
System.err.flush();
BuildEvent event = new BuildEvent(task);
for (int i = 0; i < listeners.size(); i++) {
BuildListener listener = (BuildListener) listeners.elementAt(i);


+ 37
- 20
src/main/org/apache/tools/ant/ProjectHelper.java View File

@@ -348,11 +348,11 @@ public class ProjectHelper {
}

private void handleTaskdef(String name, AttributeList attrs) throws SAXParseException {
(new TaskHandler(this, null)).init(name, attrs);
(new TaskHandler(this, null, null)).init(name, attrs);
}

private void handleProperty(String name, AttributeList attrs) throws SAXParseException {
(new TaskHandler(this, null)).init(name, attrs);
(new TaskHandler(this, null, null)).init(name, attrs);
}

private void handleTarget(String tag, AttributeList attrs) throws SAXParseException {
@@ -433,7 +433,7 @@ public class ProjectHelper {
if (project.getDataTypeDefinitions().get(name) != null) {
new DataTypeHandler(this, target).init(name, attrs);
} else {
new TaskHandler(this, target).init(name, attrs);
new TaskHandler(this, target, target).init(name, attrs);
}
}
}
@@ -443,12 +443,13 @@ public class ProjectHelper {
*/
private class TaskHandler extends AbstractHandler {
private Target target;
private TaskContainer container;
private Task task;
private RuntimeConfigurable wrapper = null;

public TaskHandler(DocumentHandler parentHandler, Target target) {
public TaskHandler(DocumentHandler parentHandler, TaskContainer container, Target target) {
super(parentHandler);
this.container = container;
this.target = target;
}

@@ -471,7 +472,7 @@ public class ProjectHelper {
// Top level tasks don't have associated targets
if (target != null) {
task.setOwningTarget(target);
target.addTask(task);
container.addTask(task);
task.init();
wrapper = task.getRuntimeConfigurableWrapper();
wrapper.setAttributes(attrs);
@@ -500,7 +501,13 @@ public class ProjectHelper {
}

public void startElement(String name, AttributeList attrs) throws SAXParseException {
new NestedElementHandler(this, task, wrapper).init(name, attrs);
if (task instanceof TaskContainer) {
// task can contain other tasks - no other nested elements possible
new TaskHandler(this, (TaskContainer)task, target).init(name, attrs);
}
else {
new NestedElementHandler(this, task, wrapper, target).init(name, attrs);
}
}
}

@@ -508,35 +515,38 @@ public class ProjectHelper {
* Handler for all nested properties.
*/
private class NestedElementHandler extends AbstractHandler {
private Object target;
private Object parent;
private Object child;
private RuntimeConfigurable parentWrapper;
private RuntimeConfigurable childWrapper = null;
private Target target;

public NestedElementHandler(DocumentHandler parentHandler,
Object target,
RuntimeConfigurable parentWrapper) {
Object parent,
RuntimeConfigurable parentWrapper,
Target target) {
super(parentHandler);

if (target instanceof TaskAdapter) {
this.target = ((TaskAdapter) target).getProxy();
if (parent instanceof TaskAdapter) {
this.parent = ((TaskAdapter) parent).getProxy();
} else {
this.target = target;
this.parent = parent;
}
this.parentWrapper = parentWrapper;
this.target = target;
}

public void init(String propType, AttributeList attrs) throws SAXParseException {
Class targetClass = target.getClass();
Class parentClass = parent.getClass();
IntrospectionHelper ih =
IntrospectionHelper.getHelper(targetClass);
IntrospectionHelper.getHelper(parentClass);

try {
if (target instanceof UnknownElement) {
if (parent instanceof UnknownElement) {
child = new UnknownElement(propType.toLowerCase());
((UnknownElement) target).addChild((UnknownElement) child);
((UnknownElement) parent).addChild((UnknownElement) child);
} else {
child = ih.createElement(project, target, propType.toLowerCase());
child = ih.createElement(project, parent, propType.toLowerCase());
}

configureId(child, attrs);
@@ -566,7 +576,14 @@ public class ProjectHelper {
}

public void startElement(String name, AttributeList attrs) throws SAXParseException {
new NestedElementHandler(this, child, childWrapper).init(name, attrs);
if (child instanceof TaskContainer) {
// taskcontainer nested element can contain other tasks - no other
// nested elements possible
new TaskHandler(this, (TaskContainer)child, target).init(name, attrs);
}
else {
new NestedElementHandler(this, child, childWrapper, target).init(name, attrs);
}
}
}

@@ -616,7 +633,7 @@ public class ProjectHelper {
}

public void startElement(String name, AttributeList attrs) throws SAXParseException {
new NestedElementHandler(this, element, wrapper).init(name, attrs);
new NestedElementHandler(this, element, wrapper, target).init(name, attrs);
}
}



+ 14
- 18
src/main/org/apache/tools/ant/Target.java View File

@@ -62,7 +62,7 @@ import java.util.*;
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
*/

public class Target {
public class Target implements TaskContainer {

private String name;
private String ifCondition = "";
@@ -161,23 +161,7 @@ public class Target {
Object o = enum.nextElement();
if (o instanceof Task) {
Task task = (Task) o;
try {
project.fireTaskStarted(task);
task.maybeConfigure();
task.execute();
project.fireTaskFinished(task, null);
}
catch(RuntimeException exc) {
if (exc instanceof BuildException) {
BuildException be = (BuildException) exc;
if (be.getLocation() == Location.UNKNOWN_LOCATION) {
be.setLocation(task.getLocation());
}
}
project.fireTaskFinished(task, exc);
throw exc;
}
task.perform();
} else {
RuntimeConfigurable r = (RuntimeConfigurable) o;
r.maybeConfigure(project);
@@ -192,6 +176,18 @@ public class Target {
}
}

public final void performTasks() {
try {
project.fireTargetStarted(this);
execute();
project.fireTargetFinished(this, null);
}
catch(RuntimeException exc) {
project.fireTargetFinished(this, exc);
throw exc;
}
}
void replaceTask(UnknownElement el, Task t) {
int index = -1;
while ((index = children.indexOf(el)) >= 0) {


+ 31
- 0
src/main/org/apache/tools/ant/Task.java View File

@@ -220,5 +220,36 @@ public abstract class Task {
wrapper.maybeConfigure(project);
}
}

protected void handleOutput(String line) {
log(line, Project.MSG_INFO);
}
protected void handleErrorOutput(String line) {
log(line, Project.MSG_ERR);
}
/**
* Perform this task
*/
public final void perform() {
try {
project.fireTaskStarted(this);
maybeConfigure();
execute();
project.fireTaskFinished(this, null);
}
catch(RuntimeException exc) {
if (exc instanceof BuildException) {
BuildException be = (BuildException) exc;
if (be.getLocation() == Location.UNKNOWN_LOCATION) {
be.setLocation(getLocation());
}
}
project.fireTaskFinished(this, exc);
throw exc;
}
}
}


+ 70
- 0
src/main/org/apache/tools/ant/TaskContainer.java View File

@@ -0,0 +1,70 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

package org.apache.tools.ant;

/**
* Interface for objects which can contain tasks
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public interface TaskContainer {
/**
* Add a task to this task container
*
* @param task the task to be added to this container
*/
void addTask(Task task);
}


+ 2
- 15
src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java View File

@@ -76,7 +76,6 @@ public class ExecuteJava {
private Commandline javaCommand = null;
private Path classpath = null;
private CommandlineJava.SysProperties sysProperties = null;
private PrintStream out;

public void setJavaCommand(Commandline javaCommand) {
this.javaCommand = javaCommand;
@@ -93,15 +92,13 @@ public class ExecuteJava {
/**
* All output (System.out as well as System.err) will be written
* to this Stream.
*
* @deprecated manage output at the task level
*/
public void setOutput(PrintStream out) {
this.out = out;
}

public void execute(Project project) throws BuildException{
PrintStream sOut = System.out;
PrintStream sErr = System.err;

final String classname = javaCommand.getExecutable();
final Object[] argument = { javaCommand.getArguments() };

@@ -111,11 +108,6 @@ public class ExecuteJava {
sysProperties.setSystem();
}

if (out != null) {
System.setErr(out);
System.setOut(out);
}

final Class[] param = { Class.forName("[Ljava.lang.String;") };
Class target = null;
if (classpath == null) {
@@ -150,11 +142,6 @@ public class ExecuteJava {
if (sysProperties != null) {
sysProperties.restoreSystem();
}
if (out != null) {
System.setOut(sOut);
System.setErr(sErr);
out.close();
}
}
}
}

+ 29
- 3
src/main/org/apache/tools/ant/taskdefs/Java.java View File

@@ -76,6 +76,7 @@ public class Java extends Task {
private boolean fork = false;
private File dir = null;
private File out;
private PrintStream outStream = null;
private boolean failOnError = false;
/**
@@ -239,6 +240,24 @@ public class Java extends Task {
}
}

protected void handleOutput(String line) {
if (outStream != null) {
outStream.println(line);
}
else {
super.handleOutput(line);
}
}
protected void handleErrorOutput(String line) {
if (outStream != null) {
outStream.println(line);
}
else {
super.handleErrorOutput(line);
}
}
/**
* Executes the given classname with the given arguments as it
* was a command line application.
@@ -250,13 +269,20 @@ public class Java extends Task {
exe.setSystemProperties(command.getSystemProperties());
if (out != null) {
try {
exe.setOutput(new PrintStream(new FileOutputStream(out)));
outStream = new PrintStream(new FileOutputStream(out));
exe.execute(project);
} catch (IOException io) {
throw new BuildException(io, location);
}
finally {
if (outStream != null) {
outStream.close();
}
}
}
else {
exe.execute(project);
}
exe.execute(project);
}

/**


+ 179
- 0
src/main/org/apache/tools/ant/taskdefs/Parallel.java View File

@@ -0,0 +1,179 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.taskdefs;

import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;
import java.util.*;
import java.text.*;
import java.lang.RuntimeException;

/**
* Implements a multi threaded task execution.
* <p>
* @author Thomas Christen <a href="mailto:chr@active.ch">chr@active.ch</a>
* @author <a href="mailto:conor@apache.org">Conor MacNeill </a>
*/
public class Parallel extends Task
implements TaskContainer {

/** Collection holding the nested tasks */
private Vector nestedTasks = new Vector();


/**
* Add a nested task to execute parallel (asynchron).
* <p>
* @param nestedTask Nested task to be executed in parallel
*/
public void addTask(Task nestedTask) throws BuildException {
nestedTasks.addElement(nestedTask);
}

/**
* Block execution until the specified time or for a
* specified amount of milliseconds and if defined,
* execute the wait status.
*/
public void execute() throws BuildException {
TaskThread[] threads = new TaskThread[nestedTasks.size()];
int threadNumber = 0;
for (Enumeration e = nestedTasks.elements(); e.hasMoreElements(); threadNumber++) {
Task nestedTask = (Task)e.nextElement();
threads[threadNumber] = new TaskThread(threadNumber, nestedTask);
}

// now start all threads
for (int i = 0; i < threads.length; ++i) {
threads[i].start();
}

// now join to all the threads
for (int i = 0; i < threads.length; ++i) {
try {
threads[i].join();
}
catch (InterruptedException ie) {
// who would interrupt me at a time like this?
}
}
// now did any of the threads throw an exception
StringBuffer exceptionMessage = new StringBuffer();
String lSep = System.getProperty("line.separator");
int numExceptions = 0;
Throwable firstException = null;
Location firstLocation = Location.UNKNOWN_LOCATION;;
for (int i = 0; i < threads.length; ++i) {
Throwable t = threads[i].getException();
if (t != null) {
numExceptions++;
if (firstException == null) {
firstException = t;
}
if (t instanceof BuildException &&
firstLocation == Location.UNKNOWN_LOCATION) {
firstLocation = ((BuildException)t).getLocation();
}
exceptionMessage.append(lSep);
exceptionMessage.append(t.getMessage());
}
}
if (numExceptions == 1) {
if (firstException instanceof BuildException) {
throw (BuildException)firstException;
}
else {
throw new BuildException(firstException);
}
}
else if (numExceptions > 1) {
throw new BuildException(exceptionMessage.toString(), firstLocation);
}
}

class TaskThread extends Thread {
private Throwable exception;
private Task task;
private int taskNumber;

/**
* Construct a new TaskThread<p>
*
* @param task the Task to be executed in a seperate thread
*/
TaskThread(int taskNumber, Task task) {
this.task = task;
this.taskNumber = taskNumber;
}

/**
* Executes the task within a thread and takes care about
* Exceptions raised within the task.
*/
public void run() {
try {
task.perform();
}
catch (Throwable t) {
exception = t;
}
}
public Throwable getException() {
return exception;
}
}
}

+ 92
- 0
src/main/org/apache/tools/ant/taskdefs/Sequential.java View File

@@ -0,0 +1,92 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.taskdefs;

import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;
import java.util.*;
import java.text.*;
import java.lang.RuntimeException;

/**
* Implements a single threaded task execution.
* <p>
* @author Thomas Christen <a href="mailto:chr@active.ch">chr@active.ch</a>
*/
public class Sequential extends Task
implements TaskContainer {

/** Optional Vector holding the nested tasks */
private Vector nestedTasks = new Vector();

/**
* Add a nested task to Sequential.
* <p>
* @param nestedTask Nested task to execute Sequential
* <p>
*/
public void addTask(Task nestedTask) {
nestedTasks.addElement(nestedTask);
}

/**
* Execute all nestedTasks.
*/
public void execute() throws BuildException {
for (Enumeration e = nestedTasks.elements(); e.hasMoreElements();) {
Task nestedTask = (Task)e.nextElement();
nestedTask.perform();
}
}
}

+ 0
- 11
src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java View File

@@ -83,15 +83,8 @@ public class Javac13 extends DefaultCompilerAdapter {
attributes.log("Using modern compiler", Project.MSG_VERBOSE);
Commandline cmd = setupJavacCommand();

PrintStream err = System.err;
PrintStream out = System.out;

PrintStream logstr =
new PrintStream(new LogOutputStream(attributes, Project.MSG_WARN));
// Use reflection to be able to build on all JDKs >= 1.1:
try {
System.setOut(logstr);
System.setErr(logstr);
Class c = Class.forName ("com.sun.tools.javac.Main");
Object compiler = c.newInstance ();
Method compile = c.getMethod ("compile",
@@ -105,10 +98,6 @@ public class Javac13 extends DefaultCompilerAdapter {
} else {
throw new BuildException("Error starting modern compiler", ex, location);
}
} finally {
System.setErr(err);
System.setOut(out);
logstr.close();
}
}
}

+ 2
- 0
src/main/org/apache/tools/ant/taskdefs/defaults.properties View File

@@ -49,6 +49,8 @@ typedef=org.apache.tools.ant.taskdefs.Typedef
sleep=org.apache.tools.ant.taskdefs.Sleep
pathconvert=org.apache.tools.ant.taskdefs.PathConvert
ear=org.apache.tools.ant.taskdefs.Ear
parallel=org.apache.tools.ant.taskdefs.Parallel
sequential=org.apache.tools.ant.taskdefs.Sequential

# optional tasks
script=org.apache.tools.ant.taskdefs.optional.Script


+ 0
- 11
src/main/org/apache/tools/ant/taskdefs/optional/Javah.java View File

@@ -308,19 +308,12 @@ public class Javah extends Task {
throw new BuildException("Compile failed");
}
*/
PrintStream err = System.err;
PrintStream out = System.out;

PrintStream logstr =
new PrintStream(new LogOutputStream(this, Project.MSG_WARN));
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.
//------------------------------------------------------------------
System.setOut(logstr);
System.setErr(logstr);
com.sun.tools.javah.Main main = new com.sun.tools.javah.Main( cmd.getArguments() );
main.run();
}
@@ -335,10 +328,6 @@ public class Javah extends Task {
} else {
throw new BuildException("Error starting javah: ", ex, location);
}
} finally {
System.setErr(err);
System.setOut(out);
logstr.close();
}
}



+ 22
- 2
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java View File

@@ -155,7 +155,8 @@ public class JUnitTask extends Task {
private Integer timeout = null;
private boolean summary = false;
private String summaryValue = "";

private JUnitTestRunner runner = null;
/**
* Tells this task to halt when there is an error in a test.
* this property is applied on all BatchTest (batchtest) and JUnitTest (test)
@@ -509,6 +510,25 @@ public class JUnitTask extends Task {
// 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);
}
}
protected void handleErrorOutput(String line) {
if (runner != null) {
runner.handleErrorOutput(line);
}
else {
super.handleErrorOutput(line);
}
}
/**
* Execute inside VM.
*/
@@ -535,7 +555,7 @@ public class JUnitTask extends Task {
// will cause trouble in JDK 1.1 if omitted
cl.addSystemPackageRoot("org.apache.tools.ant");
}
JUnitTestRunner runner = new JUnitTestRunner(test, test.getHaltonerror(), test.getHaltonfailure(), cl);
runner = new JUnitTestRunner(test, test.getHaltonerror(), test.getHaltonfailure(), cl);

if (summary) {
log("Running " + test.getName(), Project.MSG_INFO);


+ 24
- 9
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java View File

@@ -138,6 +138,12 @@ public class JUnitTestRunner implements TestListener {
*/
private JUnitTest junitTest;

/** output written during the test */
private PrintStream systemError;
/** Error output during the test */
private PrintStream systemOut;
/**
* Constructor for fork=true or when the user hasn't specified a
* classpath.
@@ -212,22 +218,19 @@ public class JUnitTestRunner implements TestListener {
} else {


PrintStream oldErr = System.err;
PrintStream oldOut = System.out;
ByteArrayOutputStream errStrm = new ByteArrayOutputStream();
System.setErr(new PrintStream(errStrm));
systemError = new PrintStream(errStrm);
ByteArrayOutputStream outStrm = new ByteArrayOutputStream();
System.setOut(new PrintStream(outStrm));
systemOut = new PrintStream(outStrm);

try {
suite.run(res);
} finally {
System.err.close();
System.out.close();
System.setErr(oldErr);
System.setOut(oldOut);
systemError.close();
systemError = null;
systemOut.close();
systemOut = null;
sendOutAndErr(new String(outStrm.toByteArray()),
new String(errStrm.toByteArray()));

@@ -299,6 +302,18 @@ public class JUnitTestRunner implements TestListener {
}
}

protected void handleOutput(String line) {
if (systemOut != null) {
systemOut.println(line);
}
}
protected void handleErrorOutput(String line) {
if (systemError != null) {
systemError.println(line);
}
}
private void sendOutAndErr(String out, String err) {
for (int i=0; i<formatters.size(); i++) {
JUnitResultFormatter formatter =


+ 0
- 12
src/main/org/apache/tools/ant/taskdefs/rmic/KaffeRmic.java View File

@@ -74,15 +74,7 @@ public class KaffeRmic extends DefaultRmicAdapter {
getRmic().log("Using Kaffe rmic", Project.MSG_VERBOSE);
Commandline cmd = setupRmicCommand();

PrintStream err = System.err;
PrintStream out = System.out;

// the project log
PrintStream logstr =
new PrintStream(new LogOutputStream(getRmic(), Project.MSG_WARN));
try {
System.setOut(logstr);
System.setErr(logstr);

Class c = Class.forName("kaffe.rmi.rmic.RMIC");
Constructor cons = c.getConstructor(new Class[] { String[].class });
@@ -103,10 +95,6 @@ public class KaffeRmic extends DefaultRmicAdapter {
} else {
throw new BuildException("Error starting Kaffe rmic: ", ex, getRmic().getLocation());
}
} finally {
System.setErr(err);
System.setOut(out);
logstr.close();
}
}
}

+ 0
- 12
src/main/org/apache/tools/ant/taskdefs/rmic/WLRmic.java View File

@@ -75,15 +75,7 @@ public class WLRmic extends DefaultRmicAdapter {
getRmic().log("Using WebLogic rmic", Project.MSG_VERBOSE);
Commandline cmd = setupRmicCommand(new String[] {"-noexit"});

PrintStream err = System.err;
PrintStream out = System.out;

PrintStream logstr =
new PrintStream(new LogOutputStream(getRmic(), Project.MSG_WARN));
try {
System.setOut(logstr);
System.setErr(logstr);

// Create an instance of the rmic
Class c = Class.forName("weblogic.rmic");
Method doRmic = c.getMethod("main",
@@ -101,10 +93,6 @@ public class WLRmic extends DefaultRmicAdapter {
} else {
throw new BuildException("Error starting WebLogic rmic: ", ex, getRmic().getLocation());
}
} finally {
System.setErr(err);
System.setOut(out);
logstr.close();
}
}



Loading…
Cancel
Save