diff --git a/proposal/mutant/build/ant1compat.xml b/proposal/mutant/build/ant1compat.xml index ec8ea5c16..ac7286099 100644 --- a/proposal/mutant/build/ant1compat.xml +++ b/proposal/mutant/build/ant1compat.xml @@ -28,14 +28,14 @@ - - + diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java index a14106e95..f6cf43dfa 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java @@ -766,7 +766,7 @@ public class ComponentManager implements ComponentService { Task nestedTask = (Task)createComponent(nestedElementModel); TaskContainer container = (TaskContainer)element; - container.addTask(nestedTask); + container.addNestedTask(nestedTask); } else { if (setter.supportsNestedAdder(nestedElementName)) { addNestedElement(factory, setter, element, diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java index 6814f1441..272c94319 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java @@ -250,9 +250,15 @@ public class Frame implements DemuxOutputReceiver { * @exception ExecutionException if the properties cannot be set */ protected void setMagicProperties() throws ExecutionException { - // set up various magic properties - setDataValue(MagicProperties.ANT_HOME, - initConfig.getAntHome().toString(), true); + URL antHomeURL = initConfig.getAntHome(); + String antHomeString = null; + if (antHomeURL.getProtocol().equals("file")) { + File antHome = new File(antHomeURL.getFile()); + antHomeString = antHome.getAbsolutePath(); + } else { + antHomeString = antHomeURL.toString(); + } + setDataValue(MagicProperties.ANT_HOME, antHomeString, true); } /** diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java index ffba40a70..0bd1dbf5a 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java @@ -131,6 +131,32 @@ public abstract class Task extends ProjectComponent return description; } + + /** + * XXX Adds a feature to the NestedTask attribute of the Task object + * + * @param task XXX The feature to be added to the NestedTask attribute + * @exception ExecutionException XXX Description of Exception + */ + public void addNestedTask(org.apache.ant.common.antlib.Task task) + throws ExecutionException { + + if (!(this instanceof TaskContainer)) { + throw new BuildException("Can't add tasks to this task"); + } + // wrap the Ant2 task in a TaskAdapter + TaskContainer container = (TaskContainer)this; + if (task instanceof Task) { + container.addTask((Task)task); + } else { + TaskAdapter adapter = new TaskAdapter(); + adapter.setProxy(task); + adapter.setProject(getProject()); + adapter.init(task.getAntContext(), task.getComponentType()); + container.addTask(adapter); + } + } + /** * Initialise this component * diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/TaskContainer.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/TaskContainer.java index 39adddd3c..fd73dbe1c 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/TaskContainer.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/TaskContainer.java @@ -59,6 +59,13 @@ package org.apache.tools.ant; * @author Conor MacNeill * @created 31 January 2002 */ -public interface TaskContainer { +public interface TaskContainer + extends org.apache.ant.common.antlib.TaskContainer { + /** + * Add a task to this container + * + * @param task the task to be added + */ + void addTask(Task task); } diff --git a/proposal/mutant/src/java/antlibs/system/antlib.xml b/proposal/mutant/src/java/antlibs/system/antlib.xml index a210aa2a6..48e84c58f 100644 --- a/proposal/mutant/src/java/antlibs/system/antlib.xml +++ b/proposal/mutant/src/java/antlibs/system/antlib.xml @@ -7,6 +7,9 @@ + + diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Parallel.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Parallel.java new file mode 100644 index 000000000..e2d4c0a1a --- /dev/null +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Parallel.java @@ -0,0 +1,205 @@ +/* + * 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 + * . + */ +package org.apache.ant.antlib.system; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.apache.ant.common.antlib.AbstractTask; +import org.apache.ant.common.antlib.AntContext; + +import org.apache.ant.common.antlib.Task; +import org.apache.ant.common.antlib.TaskContainer; +import org.apache.ant.common.service.ExecService; +import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.Location; + +/** + * Implements a multi threaded task execution. + * + * @author Thomas Christen chr@active.ch + * @author Conor MacNeill + * @created 27 February 2002 + */ +public class Parallel extends AbstractTask + implements TaskContainer { + + /** + * Class which stores information about the thread to which each task is + * associated + * + * @author Conor MacNeill + * @created 27 February 2002 + */ + private class TaskThread extends Thread { + /** The exception thrown, if any, by the task running in this thread */ + private Throwable exception; + /** The task running is this thread */ + private Task task; + /** An identifier for the thread */ + private int taskNumber; + + /** + * Construct a new TaskThread + * + * @param task the Task to be executed in a seperate thread + * @param taskNumber the thread's identifier + */ + TaskThread(int taskNumber, Task task) { + this.task = task; + this.taskNumber = taskNumber; + } + + /** + * Get the exception thrown by the task, if any. + * + * @return the Throwable instance thrown by the task or null if + * nothing was thrown. + */ + public Throwable getException() { + return exception; + } + + /** + * Executes the task within a thread and takes care about Exceptions + * raised within the task. + */ + public void run() { + try { + AntContext context = getAntContext(); + ExecService execService + = (ExecService)context.getCoreService(ExecService.class); + execService.executeTask(task); + } catch (Throwable t) { + exception = t; + } + } + } + + /** Collection holding the nested tasks */ + private List nestedTasks = new ArrayList(); + + + /** + * Add a nested task to execute parallel (asynchron). + * + * @param nestedTask Nested task to be executed in parallel + */ + public void addNestedTask(Task nestedTask) { + nestedTasks.add(nestedTask); + } + + /** + * Block execution until the specified time or for a specified amount of + * milliseconds and if defined, execute the wait status. + * + * @exception ExecutionException if any of the nested tasks throws an + * exception + */ + public void execute() throws ExecutionException { + TaskThread[] threads = new TaskThread[nestedTasks.size()]; + int threadNumber = 0; + for (Iterator i = nestedTasks.iterator(); i.hasNext(); threadNumber++) { + Task nestedTask = (Task)i.next(); + 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 ExecutionException && + firstLocation == Location.UNKNOWN_LOCATION) { + firstLocation = ((ExecutionException)t).getLocation(); + } + exceptionMessage.append(lSep); + exceptionMessage.append(t.getMessage()); + } + } + + if (numExceptions == 1) { + if (firstException instanceof ExecutionException) { + throw (ExecutionException)firstException; + } else { + throw new ExecutionException(firstException); + } + } else if (numExceptions > 1) { + throw new ExecutionException(exceptionMessage.toString(), + firstLocation); + } + } +} + diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Sequential.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Sequential.java new file mode 100644 index 000000000..e99fc2279 --- /dev/null +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Sequential.java @@ -0,0 +1,110 @@ +/* + * 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 + * . + */ +package org.apache.ant.antlib.system; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.apache.ant.common.antlib.AbstractTask; +import org.apache.ant.common.antlib.AntContext; + +import org.apache.ant.common.antlib.Task; +import org.apache.ant.common.antlib.TaskContainer; +import org.apache.ant.common.service.ExecService; +import org.apache.ant.common.util.ExecutionException; + +/** + * Implements a single threaded task execution.

+ * + * + * + * @author Thomas Christen chr@active.ch + * @created 27 February 2002 + */ +public class Sequential extends AbstractTask + implements TaskContainer { + + /** Collection holding the nested tasks */ + private List nestedTasks = new ArrayList(); + + + /** + * Add a nested task to Sequential.

+ * + * + * + * @param nestedTask Nested task to execute Sequential

+ * + * + */ + public void addNestedTask(Task nestedTask) { + nestedTasks.add(nestedTask); + } + + /** + * Execute all nestedTasks. + * + * @exception ExecutionException if any of the nested tasks throws an + * exception + */ + public void execute() throws ExecutionException { + AntContext context = getAntContext(); + ExecService execService + = (ExecService)context.getCoreService(ExecService.class); + for (Iterator i = nestedTasks.iterator(); i.hasNext(); ) { + Task nestedTask = (Task)i.next(); + execService.executeTask(nestedTask); + } + } +} + diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/TaskContainer.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/TaskContainer.java index e7bdeb52a..9e296b2d4 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/TaskContainer.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/TaskContainer.java @@ -67,6 +67,6 @@ public interface TaskContainer { * @param task the task tobe added * @exception ExecutionException if the container cannot add the task */ - void addTask(Task task) throws ExecutionException; + void addNestedTask(Task task) throws ExecutionException; }