Browse Source

Mutant update.

Reorganization of classes to a fair extent
Introduction of a non-functional parallel task
Converted some data types over
Initial experiments with apsects used to store data type values


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269031 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 24 years ago
parent
commit
c2e518039b
34 changed files with 1853 additions and 657 deletions
  1. +3
    -0
      proposal/mutant/build.xml
  2. +75
    -0
      proposal/mutant/src/main/org/apache/ant/component/core/AntAspectHandler.java
  3. +1
    -1
      proposal/mutant/src/main/org/apache/ant/component/core/Echo.java
  4. +0
    -1
      proposal/mutant/src/main/org/apache/ant/component/core/FileConverter.java
  5. +4
    -5
      proposal/mutant/src/main/org/apache/ant/component/core/Property.java
  6. +9
    -0
      proposal/mutant/src/main/org/apache/ant/component/core/antlib.xml
  7. +78
    -0
      proposal/mutant/src/main/org/apache/ant/component/thread/Parallel.java
  8. +78
    -0
      proposal/mutant/src/main/org/apache/ant/component/thread/Sequential.java
  9. +4
    -0
      proposal/mutant/src/main/org/apache/ant/component/thread/antlib.xml
  10. +80
    -0
      proposal/mutant/src/main/org/apache/ant/core/execution/AbstractAspectHandler.java
  11. +96
    -0
      proposal/mutant/src/main/org/apache/ant/core/execution/AbstractTask.java
  12. +39
    -12
      proposal/mutant/src/main/org/apache/ant/core/execution/AntLibrary.java
  13. +124
    -0
      proposal/mutant/src/main/org/apache/ant/core/execution/AspectDefinition.java
  14. +74
    -0
      proposal/mutant/src/main/org/apache/ant/core/execution/AspectHandler.java
  15. +1
    -1
      proposal/mutant/src/main/org/apache/ant/core/execution/ClassIntrospectionException.java
  16. +2
    -2
      proposal/mutant/src/main/org/apache/ant/core/execution/ConverterDefinition.java
  17. +17
    -59
      proposal/mutant/src/main/org/apache/ant/core/execution/ExecutionContext.java
  18. +444
    -122
      proposal/mutant/src/main/org/apache/ant/core/execution/ExecutionFrame.java
  19. +0
    -317
      proposal/mutant/src/main/org/apache/ant/core/execution/ExecutionManager.java
  20. +10
    -12
      proposal/mutant/src/main/org/apache/ant/core/execution/Task.java
  21. +100
    -0
      proposal/mutant/src/main/org/apache/ant/core/execution/TaskAdapter.java
  22. +1
    -1
      proposal/mutant/src/main/org/apache/ant/core/execution/TaskContainer.java
  23. +1
    -1
      proposal/mutant/src/main/org/apache/ant/core/execution/TaskDefinition.java
  24. +42
    -12
      proposal/mutant/src/main/org/apache/ant/core/model/BuildElement.java
  25. +1
    -1
      proposal/mutant/src/main/org/apache/ant/core/model/Project.java
  26. +1
    -1
      proposal/mutant/src/main/org/apache/ant/core/model/Target.java
  27. +4
    -1
      proposal/mutant/src/main/org/apache/ant/core/support/AntClassLoader.java
  28. +1
    -1
      proposal/mutant/src/main/org/apache/ant/core/support/AntException.java
  29. +131
    -0
      proposal/mutant/src/main/org/apache/ant/core/types/DataType.java
  30. +369
    -0
      proposal/mutant/src/main/org/apache/ant/core/types/PatternSet.java
  31. +29
    -2
      proposal/mutant/src/main/org/apache/ant/core/xml/AntLibParser.java
  32. +12
    -85
      proposal/mutant/src/main/org/apache/ant/core/xml/XMLProjectParser.java
  33. +17
    -13
      proposal/mutant/src/main/org/apache/ant/frontend/Commandline.java
  34. +5
    -7
      proposal/mutant/src/main/org/apache/ant/frontend/DefaultLogger.java

+ 3
- 0
proposal/mutant/build.xml View File

@@ -55,6 +55,9 @@
<antcall target="build-task">
<param name="taskset" value="file"/>
</antcall>
<antcall target="build-task">
<param name="taskset" value="thread"/>
</antcall>
<copy todir="${build.lib}">
<fileset dir="lib"/>
</copy>


+ 75
- 0
proposal/mutant/src/main/org/apache/ant/component/core/AntAspectHandler.java View File

@@ -0,0 +1,75 @@
/*
* 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.ant.component.core;

import java.io.File;
import java.net.*;
import org.apache.ant.core.execution.*;

/**
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public class AntAspectHandler extends AbstractAspectHandler {
private String id;
public void setId(String id) {
this.id = id;
}

public void afterConfigElement(Object element) throws ExecutionException {
getAspectContext().setDataValue(id, element);
}
}

+ 1
- 1
proposal/mutant/src/main/org/apache/ant/component/core/Echo.java View File

@@ -63,7 +63,7 @@ import java.io.*;
*
* @author costin@dnt.ro
*/
public class Echo extends ExecutionTask {
public class Echo extends AbstractTask {
protected String message = ""; // required
protected File file = null;
protected boolean append = false;


+ 0
- 1
proposal/mutant/src/main/org/apache/ant/component/core/FileConverter.java View File

@@ -76,7 +76,6 @@ public class FileConverter implements AntConverter {
try {
URL url = new URL(frame.getBaseURL(), value);
if (url.getProtocol().equals("file")) {
System.out.println("Converted URL to " + url);
return new File(url.getFile());
}
return new File(value);


+ 4
- 5
proposal/mutant/src/main/org/apache/ant/component/core/Property.java View File

@@ -62,7 +62,7 @@ import java.net.*;
/**
*
*/
public class Property extends ExecutionTask {
public class Property extends AbstractTask {
private String name;
private String value;
private URL file;
@@ -144,9 +144,8 @@ public class Property extends ExecutionTask {
//

public void execute() throws ExecutionException {
ExecutionFrame frame = getExecutionFrame();
if ((name != null) && (value != null)) {
frame.setDataValue(name, value);
getTaskContext().setDataValue(name, value);
}

if (file != null) {
@@ -199,11 +198,11 @@ public class Property extends ExecutionTask {
}

protected void addProperties(Properties properties) throws ExecutionException {
ExecutionFrame frame = getExecutionFrame();
for (Iterator i = properties.keySet().iterator(); i.hasNext();) {
String propertyName = (String)i.next();
String propertyValue = properties.getProperty(propertyName);
frame.setDataValue(propertyName, frame.replacePropertyRefs(propertyValue));
getTaskContext().setDataValue(propertyName,
getTaskContext().replacePropertyRefs(propertyValue));
}
}



+ 9
- 0
proposal/mutant/src/main/org/apache/ant/component/core/antlib.xml View File

@@ -1,8 +1,17 @@
<antlib>
<!-- Tasks -->
<taskdef name="property" classname="org.apache.ant.component.core.Property"/>
<taskdef name="echo" classname="org.apache.ant.component.core.Echo"/>
<!-- Data Types -->
<taskdef name="patternset" classname="org.apache.ant.core.types.PatternSet"/>
<!-- Converters -->
<converter target="java.io.File" classname="org.apache.ant.component.core.FileConverter"/>
<converter target="java.net.URL" classname="org.apache.ant.component.core.URLConverter"/>
<converter target="org.apache.ant.core.types.EnumeratedAttribute"
classname="org.apache.ant.component.core.EnumeratedAttributeConverter"/>
<!-- Aspect Handlers -->
<aspect prefix="ant" classname="org.apache.ant.component.core.AntAspectHandler"/>
</antlib>

+ 78
- 0
proposal/mutant/src/main/org/apache/ant/component/thread/Parallel.java View File

@@ -0,0 +1,78 @@
/*
* 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.ant.component.thread;

import org.apache.ant.core.execution.*;
import java.io.*;
import java.util.*;

/**
* Parallel execution of contained tasks.
*
*/
public class Parallel extends AbstractTask implements TaskContainer {
private List tasks = new ArrayList();
public void addTask(Task nestedTask) {
tasks.add(nestedTask);
}

public void execute() throws ExecutionException {
for (Iterator i = tasks.iterator(); i.hasNext(); ) {
Task nestedTask = (Task)i.next();
nestedTask.execute();
}
}
}

+ 78
- 0
proposal/mutant/src/main/org/apache/ant/component/thread/Sequential.java View File

@@ -0,0 +1,78 @@
/*
* 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.ant.component.thread;

import org.apache.ant.core.execution.*;
import java.io.*;
import java.util.*;

/**
* Sequential execution of contained tasks.
*
*/
public class Sequential extends AbstractTask implements TaskContainer {
private List tasks = new ArrayList();
public void addTask(Task nestedTask) {
tasks.add(nestedTask);
}

public void execute() throws ExecutionException {
for (Iterator i = tasks.iterator(); i.hasNext(); ) {
Task nestedTask = (Task)i.next();
nestedTask.execute();
}
}
}

+ 4
- 0
proposal/mutant/src/main/org/apache/ant/component/thread/antlib.xml View File

@@ -0,0 +1,4 @@
<antlib>
<taskdef name="parallel" classname="org.apache.ant.component.thread.Parallel"/>
<taskdef name="sequential" classname="org.apache.ant.component.thread.Sequential"/>
</antlib>

+ 80
- 0
proposal/mutant/src/main/org/apache/ant/core/execution/AbstractAspectHandler.java View File

@@ -0,0 +1,80 @@
/*
* 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.ant.core.execution;

import org.apache.ant.core.model.*;
import org.apache.ant.core.support.*;
import java.util.*;
import java.net.URL;

/**
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public abstract class AbstractAspectHandler implements AspectHandler {
private ExecutionContext aspectContext;
public void setAspectContext(ExecutionContext context) {
this.aspectContext = context;
}

protected ExecutionContext getAspectContext() {
return aspectContext;
}
public void afterConfigElement(Object element) throws ExecutionException {
}
}


+ 96
- 0
proposal/mutant/src/main/org/apache/ant/core/execution/AbstractTask.java View File

@@ -0,0 +1,96 @@
/*
* 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.ant.core.execution;

import org.apache.ant.core.model.*;
import org.apache.ant.core.support.*;
import java.util.*;
import java.net.URL;

/**
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public abstract class AbstractTask implements Task {
private ExecutionContext taskContext;
public void setTaskContext(ExecutionContext context) {
this.taskContext = context;
}

protected ExecutionContext getTaskContext() {
return taskContext;
}
/**
* Log a message with the default (INFO) priority.
*
* @param msg the message to be logged.
*/
public void log(String msg) {
log(msg, BuildEvent.MSG_INFO);
}
/**
* Log a mesage with the give priority.
*
* @param the message to be logged.
* @param msgLevel the message priority at which this message is to be logged.
*/
public void log(String msg, int msgLevel) {
taskContext.log(msg, msgLevel);
}

}


+ 39
- 12
proposal/mutant/src/main/org/apache/ant/core/execution/AntLibrary.java View File

@@ -54,6 +54,7 @@

package org.apache.ant.core.execution;

import org.apache.ant.core.support.*;
import java.util.*;
import java.net.URL;

@@ -68,35 +69,51 @@ public class AntLibrary {
/**
* The task definitions contained by this library
*/
private List taskDefinitions = new ArrayList();
private Map taskDefinitions = new HashMap();
/**
* The converter definitions contained by this library
*/
private List converterDefinitions = new ArrayList();
private Map converterDefinitions = new HashMap();
/**
* The aspect handler definitions contained by this library
*/
private Map aspectDefinitions = new HashMap();
/**
* Add a task definition to this library
*/
public void addTaskDefinition(TaskDefinition taskDefinition) {
taskDefinitions.add(taskDefinition);
String taskName = taskDefinition.getName();
taskDefinitions.put(taskName, taskDefinition);
}
/**
* Add a converter definition to this library
*/
public void addConverterDefinition(ConverterDefinition converterDef) {
String targetClassname = converterDef.getTargetClassName();
converterDefinitions.put(targetClassname, converterDef);
}

/**
* Add an aspect handler definition to this library
*/
public void addAspectDefinition(AspectDefinition aspectDef) {
String aspectPrefix = aspectDef.getAspectPrefix();
aspectDefinitions.put(aspectPrefix, aspectDef);
}

/**
* Get the task definitions
*
* @return an iterator which returns TaskDefinition objects.
*/
public Iterator getTaskDefinitions() {
return taskDefinitions.iterator();
return taskDefinitions.values().iterator();
}
/**
* Add a converter definition to this library
*/
public void addConverterDefinition(ConverterDefinition converterDefinition) {
converterDefinitions.add(converterDefinition);
}
/**
* Get the converter definitions
@@ -104,7 +121,17 @@ public class AntLibrary {
* @return an iterator which returns ConverterDefinition objects.
*/
public Iterator getConverterDefinitions() {
return converterDefinitions.iterator();
return converterDefinitions.values().iterator();
}

/**
* Get the aspect handler definitions
*
* @return an iterator which returns AspectDefinition objects.
*/
public Iterator getAspectDefinitions() {
return aspectDefinitions.values().iterator();
}
}


+ 124
- 0
proposal/mutant/src/main/org/apache/ant/core/execution/AspectDefinition.java View File

@@ -0,0 +1,124 @@
/*
* 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.ant.core.execution;

import java.util.*;
import java.net.URL;

/**
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public class AspectDefinition {
/** The URL of the library which defines this aspect handler */
private URL aspectLibraryURL;
/** The aspect's tag */
private String aspectPrefix;
/** The aspect handler's classname */
private String aspectClassName;
/** The aspect handler's class loader. */
private ClassLoader aspectClassLoader;
/** The class to which this converter converts. */
private Class aspectHandlerClass = null;

public AspectDefinition(URL aspectLibraryURL, String aspectPrefix,
String aspectClassName, ClassLoader aspectClassLoader) {
this.aspectLibraryURL = aspectLibraryURL;
this.aspectPrefix = aspectPrefix;
this.aspectClassName = aspectClassName;
this.aspectClassLoader = aspectClassLoader;
}
/**
* Get the URL where this aspect handler was defined.
*
* @returns a URL of the lib defintion file
*/
public URL getLibraryURL() {
return aspectLibraryURL;
}
/**
* Get the Aspect's Prefix
*/
public String getAspectPrefix() {
return aspectPrefix;
}


/**
* Get the aspect handler class
*
* @return a class object for this aspect handler's class
*/
public synchronized Class getAspectHandlerClass() throws ClassNotFoundException {
if (aspectHandlerClass == null) {
aspectHandlerClass = Class.forName(aspectClassName, true, aspectClassLoader);
}
return aspectHandlerClass;
}
/**
* Get the classname of the aspect handler that is being defined.
*/
public String getAspectHandlerClassName() {
return aspectClassName;
}
}


+ 74
- 0
proposal/mutant/src/main/org/apache/ant/core/execution/AspectHandler.java View File

@@ -0,0 +1,74 @@
/*
* 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.ant.core.execution;

import org.apache.ant.core.model.*;
import org.apache.ant.core.support.*;
import java.util.*;
import java.net.URL;

/**
* An AspectHandler is used to handle a set of aspects which may occur in a number
* of elements in the build model.
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public interface AspectHandler {
void setAspectContext(ExecutionContext context);
void afterConfigElement(Object element) throws ExecutionException ;
}


+ 1
- 1
proposal/mutant/src/main/org/apache/ant/core/execution/ClassIntrospectionException.java View File

@@ -90,7 +90,7 @@ public class ClassIntrospectionException extends Exception {
* @param cause Exception that might have caused this one.
*/
public ClassIntrospectionException(Throwable cause) {
super(cause.toString());
super(cause.getMessage());
this.cause = cause;
}



+ 2
- 2
proposal/mutant/src/main/org/apache/ant/core/execution/ConverterDefinition.java View File

@@ -124,7 +124,7 @@ public class ConverterDefinition {
*/
public synchronized Class getConverterClass() throws ClassNotFoundException {
if (converterClass == null) {
converterClass = converterClassLoader.loadClass(converterClassName);
converterClass = Class.forName(converterClassName, true, converterClassLoader);
}
return converterClass;
}
@@ -136,7 +136,7 @@ public class ConverterDefinition {
*/
public synchronized Class getTargetClass() throws ClassNotFoundException {
if (targetClass == null) {
targetClass = converterClassLoader.loadClass(targetClassName);
targetClass = Class.forName(targetClassName, true, converterClassLoader);
}
return targetClass;
}


proposal/mutant/src/main/org/apache/ant/core/execution/ExecutionTask.java → proposal/mutant/src/main/org/apache/ant/core/execution/ExecutionContext.java View File

@@ -60,60 +60,22 @@ import java.util.*;
import java.net.URL;

/**
* An ExecutionTask is the execution time equivalent of the Task
* object in the Ant project model. Subclasses of ExecutionTask are
* created by Task writers to implement particular, desired
* functionality
*
* An ExecutionTask subclass is created for a particular task type.
* The data from the task model is introspected into the ExecutionTask
* which is then executed.
* The ExecutionContext interface provides a task or apsect instance with access to the
* container-provided services. This is the only way to access the container.
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public abstract class ExecutionTask {
public class ExecutionContext {
private ExecutionFrame frame = null;
private Location location = Location.UNKNOWN_LOCATION;
private BuildEventSupport eventSupport;
private BuildElement buildElement;

void setExecutionFrame(ExecutionFrame frame) {
public ExecutionContext(ExecutionFrame frame, BuildEventSupport eventSupport,
BuildElement buildElement) {
this.frame = frame;
}

/**
* Get the ExecutionFrame in which this ExecutionTask is being executed.
* to which this task belongs
*
* @return the execution task's ExecutionFrame.
*/
public ExecutionFrame getExecutionFrame() {
return frame;
}

/**
* Configure the event support to be used to fire events
*/
void setBuildEventSupport(BuildEventSupport eventSupport) {
this.eventSupport = eventSupport;
}
/**
* Associate this ExecutionTask with a buildElement in the
* project model
*/
void setBuildElement(BuildElement buildElement) {
this.buildElement = buildElement;
}
/**
* Log a message with the default (INFO) priority.
*
* @param msg the message to be logged.
*/
public void log(String msg) {
log(msg, BuildEvent.MSG_INFO);
}

/**
* Log a mesage with the give priority.
@@ -125,26 +87,22 @@ public abstract class ExecutionTask {
eventSupport.fireMessageLogged(this, buildElement, msg, msgLevel);
}

/**
* Called by the project to let the task initialize properly.
*
* @throws ExecutionException if someting goes wrong with the build
*/
public void init() throws ExecutionException {}
public void setDataValue(String name, Object value) throws ExecutionException {
frame.setDataValue(name, value);
}

/**
* Called by the frame to let the task do it's work.
*
* @throws ExecutionException if someting goes wrong with the build
*/
abstract public void execute() throws ExecutionException;
public Object getDataValue(String name) throws ExecutionException {
return frame.getDataValue(name);
}

/**
* Returns the file location where this task was defined.
* Replace ${} style constructions in the given value with the string value of
* the corresponding data types.
*
* @param value the string to be scanned for property references.
*/
public Location getLocation() {
return buildElement.getLocation();
public String replacePropertyRefs(String value) throws ExecutionException {
return frame.replacePropertyRefs(value);
}
}


+ 444
- 122
proposal/mutant/src/main/org/apache/ant/core/execution/ExecutionFrame.java View File

@@ -55,6 +55,7 @@ package org.apache.ant.core.execution;

import org.apache.ant.core.model.*;
import org.apache.ant.core.support.*;
import org.apache.ant.core.types.*;

import java.util.*;
import java.net.*;
@@ -67,6 +68,13 @@ import java.net.*;
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public class ExecutionFrame {
/** State used in dependency analysis when a target's dependencies are being
examined. */
private static final String VISITING = "VISITING";

/** State used in dependency analysis to indicate a target has been examined */
private static final String VISITED = "VISITED";

/** The Project that this execiton frame is processing */
private Project project = null;
@@ -74,9 +82,6 @@ public class ExecutionFrame {
Project's source URL and it's base attribute. */
private URL baseURL = null;
/** The task defs that this frame will use to process tasks */
private Map taskDefs = new HashMap();
/** The imported frames of this frame. For each project imported by this frame's
project, a corresponding ExecutionFrame is created. */
private Map importedFrames = new HashMap();
@@ -88,22 +93,79 @@ public class ExecutionFrame {
created by tasks that have been executed */
private Map dataValues = new HashMap();
/** Introspector objects used to configure ExecutionTasks from the Task models.*/
/** Introspector objects used to configure Tasks from the Task models.*/
private Map introspectors = new HashMap();
/** The task defs that this frame will use to process tasks */
private Map taskDefs = new HashMap();
/** Type converters for this executionFrame. Converters are used when configuring
Tasks to handle special type conversions. */
private Map converters = new HashMap();
/** The aspect handler active in this frame */
private Map aspectHandlers = new HashMap();
/** The namespace under which this execution frame lives in the hierarchical
project namespace - null for the root namespace */
private String namespace;
public ExecutionFrame(Project project, Map taskDefs, Map converterDefs,
String namespace) throws ConfigException {
this.project = project;
this.taskDefs = taskDefs;
/**
* Construct an execution frame to process the given project model with
* the configuration represented by the libraries.
*
* @param project the model of the project to be built.
* @param libraries an Array of AntLibrary objects containing the
* configuration of Ant for this build.
*
* @throws ConfigException when the project cannot be setup with the
* given configuration
*/
public ExecutionFrame(Project project, AntLibrary[] libraries)
throws ConfigException {
this.namespace = null;
setupFrame(project, libraries);
}
/**
* Construct a subframe for managing a project imported into the main project.
* @param project the model of the project to be built.
* @param libraries an Array of AntLibrary objects containing the
* configuration of Ant for this build.
* @param namespace the location of this project within the overall import
* namespace.
*
* @throws ConfigException when the project cannot be setup with the
* given configuration
*/
private ExecutionFrame(Project project, AntLibrary[] libraries, String namespace)
throws ConfigException {
this.namespace = namespace;
setupFrame(project, libraries);
}

/**
* Set up the execution frame.
*
* This method examines the project model and constructs the required
* subframes to handle imported projects.
* @param project the model of the project to be built.
* @param libraries an Array of AntLibrary objects containing the
* configuration of Ant for this build.
*
* @throws ConfigException when the project cannot be setup with the
* given configuration
*/
private void setupFrame(Project project, AntLibrary[] libraries)
throws ConfigException {

this.project = project;
for (int i = 0; i < libraries.length; ++i) {
addLibrary(libraries[i]);
}

try {
String base = project.getBase();
@@ -123,74 +185,149 @@ public class ExecutionFrame {
+ "\" is not valid", e, project.getLocation());
}
// We create a set of converters from the converter definitions we
// have been given and initialise them. They should be AntConverters
setupConverters(converterDefs);
for (Iterator i = project.getImportedProjectNames(); i.hasNext();) {
String importName = (String)i.next();
Project importedProject = project.getImportedProject(importName);
String importNamespace
= namespace == null ? importName : namespace + ":" + importName;
ExecutionFrame importedFrame
= new ExecutionFrame(importedProject, taskDefs, converterDefs, importNamespace);
= new ExecutionFrame(importedProject, libraries, importNamespace);
importedFrames.put(importName, importedFrame);
}
}

public URL getBaseURL() {
return baseURL;
/**
* Add a configuration library to this execution frame. The library
* will contain task definitions, converters, apsect handler definitions,
* etc.
*
* @param library the configuration library to add to this frame.
*
* @throws ConfigException if the items in the library cannot be configured.
*/
public void addLibrary(AntLibrary library) throws ConfigException {
for (Iterator i = library.getTaskDefinitions(); i.hasNext(); ) {
TaskDefinition taskDefinition = (TaskDefinition)i.next();
addTaskDefinition(taskDefinition);
}
for (Iterator i = library.getConverterDefinitions(); i.hasNext(); ) {
ConverterDefinition converterDef = (ConverterDefinition)i.next();
addConverterDefinition(converterDef);
}
for (Iterator i = library.getAspectDefinitions(); i.hasNext(); ) {
AspectDefinition aspectDef = (AspectDefinition)i.next();
addAspectHandler(aspectDef);
}
}

private void setupConverters(Map converterDefs) throws ConfigException {
converters = new HashMap();
for (Iterator i = converterDefs.values().iterator(); i.hasNext(); ) {
ConverterDefinition converterDef = (ConverterDefinition)i.next();
boolean targetLoaded = false;
try {
Class targetClass = converterDef.getTargetClass();
targetLoaded = false;
Class converterClass = converterDef.getConverterClass();
Converter converter = (AntConverter)converterClass.newInstance();
if (converter instanceof AntConverter) {
((AntConverter)converter).init(this);
}
converters.put(targetClass, converter);
}
catch (ClassNotFoundException e) {
if (targetLoaded) {
throw new ConfigException("Unable to load converter class for "
+ converterDef.getConverterClassName()
+ " in converter from " + converterDef.getLibraryURL()
, e);
}
else {
throw new ConfigException("Unable to load target class "
+ converterDef.getTargetClassName()
+ " in converter from " + converterDef.getLibraryURL()
, e);
}
/**
* Add a task definition to this execution frame
*
* @param taskDefinition the TaskDefinition to be added to the project.
*/
public void addTaskDefinition(TaskDefinition taskDefinition) {
String taskName = taskDefinition.getName();
taskDefs.put(taskName, taskDefinition);
}
/**
* Add a aspect handler definition to this execution frame
*
* @param taskDefinition the TaskDefinition to be added to the project.
*
* @throws ConfigException if the aspect handler cannot be created or configured.
*/
public void addAspectHandler(AspectDefinition aspectDefinition)
throws ConfigException {
String aspectPrefix = aspectDefinition.getAspectPrefix();
try {
Class aspectHandlerClass = aspectDefinition.getAspectHandlerClass();
aspectHandlers.put(aspectPrefix, aspectHandlerClass);
}
catch (ClassNotFoundException e) {
throw new ConfigException("Unable to load aspect handler class for "
+ aspectDefinition.getAspectHandlerClassName()
+ " in converter from " + aspectDefinition.getLibraryURL(),
e);
}
}
/**
* Add a converter definition to this library.
*
* The converter is created immediately to handle conversions
* when items are being configured. If the converter is an instance of
* an AntConverter, the converter is configured with this execution
* frame giving it the context it needs to resolve items relative to the
* project's base, etc.
*
* @param converterDef the converter definition to load
*
* @throws ConfigException if the converter cannot be created or configured.
*/
public void addConverterDefinition(ConverterDefinition converterDef) throws ConfigException {
boolean targetLoaded = false;
try {
Class targetClass = converterDef.getTargetClass();
targetLoaded = false;
Class converterClass = converterDef.getConverterClass();
Converter converter = (AntConverter)converterClass.newInstance();
if (converter instanceof AntConverter) {
((AntConverter)converter).init(this);
}
catch (InstantiationException e) {
throw new ConfigException("Unable to instantiate converter class "
+ converterDef.getTargetClassName()
+ " in converter from " + converterDef.getLibraryURL()
, e);
converters.put(targetClass, converter);
}
catch (ClassNotFoundException e) {
if (targetLoaded) {
throw new ConfigException("Unable to load converter class for "
+ converterDef.getConverterClassName()
+ " in converter from " + converterDef.getLibraryURL(),
e);
}
catch (IllegalAccessException e) {
throw new ConfigException("Unable to access converter class "
else {
throw new ConfigException("Unable to load target class "
+ converterDef.getTargetClassName()
+ " in converter from " + converterDef.getLibraryURL()
, e);
+ " in converter from " + converterDef.getLibraryURL(),
e);
}
}
catch (InstantiationException e) {
throw new ConfigException("Unable to instantiate converter class "
+ converterDef.getTargetClassName()
+ " in converter from " + converterDef.getLibraryURL(),
e);
}
catch (IllegalAccessException e) {
throw new ConfigException("Unable to access converter class "
+ converterDef.getTargetClassName()
+ " in converter from " + converterDef.getLibraryURL(),
e);
}
}

/**
* Get the bae URL of this frame. This will either be specified by the project's
* base attribute or be derived implicitly from the project's location.
*/
public URL getBaseURL() {
return baseURL;
}


public void addBuildListener(BuildListener listener) {
for (Iterator i = getImportedFrames(); i.hasNext(); ) {
ExecutionFrame subFrame = (ExecutionFrame)i.next();
subFrame.addBuildListener(listener);
}
eventSupport.addBuildListener(listener);
}
public void removeBuildListener(BuildListener listener) {
for (Iterator i = getImportedFrames(); i.hasNext(); ) {
ExecutionFrame subFrame = (ExecutionFrame)i.next();
subFrame.removeBuildListener(listener);
}
eventSupport.removeBuildListener(listener);
}

@@ -257,26 +394,6 @@ public class ExecutionFrame {
return namespace == null ? name : namespace + ":" + name;
}
/**
* Get the relative name of something with respect to this
* execution frame.
*
* @param fullname the fully qualified name.
*
* @return the relative version of the given name
*/
public String getRelativeName(String fullname) {
if (namespace == null) {
return fullname;
}
int index = fullname.indexOf(namespace);
if (index != 0) {
return fullname;
}
return fullname.substring(namespace.length() + 1);
}
/**
* Execute the given target's tasks
*
@@ -297,32 +414,140 @@ public class ExecutionFrame {
}
/**
* Initialise the frame by executing the project level tasks if any
* Initialize the frame by executing the project level tasks if any
*/
public void initialise() throws ExecutionException, ConfigException {
public void initialize() throws ExecutionException, ConfigException {
for (Iterator i = getImportedFrames(); i.hasNext(); ) {
ExecutionFrame subFrame = (ExecutionFrame)i.next();
subFrame.initialize();
}
Iterator taskIterator = project.getTasks();
executeTasks(taskIterator);
}

public void fillinDependencyOrder(String targetName, List dependencyOrder,
Map state, Stack visiting) throws ConfigException {
String fullTargetName = getQualifiedName(targetName);
if (state.get(fullTargetName) == VISITED) {
return;
}
Target target = getProject().getTarget(targetName);
if (target == null) {
StringBuffer sb = new StringBuffer("Target `");
sb.append(targetName);
sb.append("' does not exist in this project. ");
if (!visiting.empty()) {
String parent = (String)visiting.peek();
sb.append("It is used from target `");
sb.append(parent);
sb.append("'.");
}

throw new ConfigException(new String(sb), getProject().getLocation());
}
state.put(fullTargetName, VISITING);
visiting.push(fullTargetName);
for (Iterator i = target.getDependencies(); i.hasNext(); ) {
String dependency = (String)i.next();
try {
ExecutionFrame dependencyFrame = getRelativeFrame(dependency);
if (dependencyFrame == null) {
StringBuffer sb = new StringBuffer("Target `");
sb.append(dependency);
sb.append("' does not exist in this project. ");
throw new ConfigException(new String(sb), target.getLocation());
}
String fullyQualifiedName = getQualifiedName(dependency);
String dependencyState = (String)state.get(fullyQualifiedName);
if (dependencyState == null) {
dependencyFrame.fillinDependencyOrder(getNameInFrame(dependency), dependencyOrder,
state, visiting);
}
else if (dependencyState == VISITING) {
String circleDescription
= getCircularDesc(dependency, visiting);
throw new ConfigException(circleDescription, target.getLocation());
}
}
catch (ExecutionException e) {
throw new ConfigException(e.getMessage(), e, target.getLocation());
}
}
state.put(fullTargetName, VISITED);
String poppedNode = (String)visiting.pop();
if (poppedNode != fullTargetName) {
throw new ConfigException("Problem determining dependencies " +
" - expecting '" + fullTargetName +
"' but got '" + poppedNode + "'");
}
dependencyOrder.add(fullTargetName);
}
private String getCircularDesc(String end, Stack visitingNodes) {
StringBuffer sb = new StringBuffer("Circular dependency: ");
sb.append(end);
String c;
do {
c = (String)visitingNodes.pop();
sb.append(" <- ");
sb.append(c);
} while(!c.equals(end));
return new String(sb);
}

/**
* Check whether the targets in this frame and its subframes are OK
*/
public void checkTargets(List dependencyOrder, Map state, Stack visiting)
throws ConfigException {
// get the targets and just iterate through them.
for (Iterator i = getProject().getTargets(); i.hasNext();) {
Target target = (Target)i.next();
fillinDependencyOrder(target.getName(),
dependencyOrder, state, visiting);
}
// Now do the subframes.
for (Iterator i = getImportedFrames(); i.hasNext();) {
ExecutionFrame importedFrame = (ExecutionFrame)i.next();
importedFrame.checkTargets(dependencyOrder, state, visiting);
}
}

private ExecutionTask getConfiguredExecutionTask(TaskElement model)
/**
* Create a Task and configure it according to the given model.
*/
private Task configureTask(TaskElement model)
throws ConfigException, ExecutionException {

String taskType = model.getType();
TaskDefinition taskDefinition = (TaskDefinition)taskDefs.get(taskType);
if (taskDefinition == null) {
throw new ConfigException("There is no task defintion for tasks of type <"
throw new ConfigException("There is no defintion for tasks of type <"
+ taskType + ">", model.getLocation());
}
try {
Class executionTaskClass = taskDefinition.getExecutionTaskClass();
ExecutionTask executionTask = (ExecutionTask)executionTaskClass.newInstance();
executionTask.setExecutionFrame(this);
executionTask.setBuildEventSupport(eventSupport);
executionTask.setBuildElement(model);
configureElement(executionTask, model);
return executionTask;
Class elementClass = taskDefinition.getExecutionTaskClass();
Object element = elementClass.newInstance();
Task task = null;
if (element instanceof Task) {
// create a Task context for the Task
task = (Task)element;
}
else {
task = new TaskAdapter(taskType, element);
}
ExecutionContext context = new ExecutionContext(this, eventSupport, model);
task.setTaskContext(context);
configureElement(element, model);

return task;
}
catch (ClassNotFoundException e) {
throw new ConfigException("Execution class " + taskDefinition.getTaskClassName()
@@ -339,43 +564,51 @@ public class ExecutionFrame {
e, model.getLocation());
}
}
/**
* Run the tasks returned by the give iterator
*
* @param taskIterator the iterator giving the tasks to execute
*/
public void executeTasks(Iterator taskIterator) throws ExecutionException, ConfigException {
Task task = null;
try {
while (taskIterator.hasNext()) {
task = (Task)taskIterator.next();

private List getActiveAspects(BuildElement model)
throws ConfigException, ExecutionException,
ClassIntrospectionException, ConversionException {
List activeAspects = new ArrayList();
for (Iterator i = model.getAspectNames(); i.hasNext();) {
String aspectPrefix = (String)i.next();
Class aspectHandlerClass = (Class)aspectHandlers.get(aspectPrefix);
if (aspectHandlerClass != null) {
try {
ExecutionTask executionTask = getConfiguredExecutionTask(task);
eventSupport.fireTaskStarted(this, task);
executionTask.execute();
}
catch (ExecutionException e) {
if (e.getLocation() == null || e.getLocation() == Location.UNKNOWN_LOCATION) {
e.setLocation(task.getLocation());
AspectHandler aspectHandler
= (AspectHandler)aspectHandlerClass.newInstance();
ClassIntrospector introspector = getIntrospector(aspectHandlerClass);
ExecutionContext context = new ExecutionContext(this, eventSupport, model);
aspectHandler.setAspectContext(context);
Map aspectAttributes = model.getAspectAttributes(aspectPrefix);
for (Iterator j = aspectAttributes.keySet().iterator(); j.hasNext();) {
String attributeName = (String)j.next();
String attributeValue = (String)aspectAttributes.get(attributeName);
introspector.setAttribute(aspectHandler, attributeName,
replacePropertyRefs(attributeValue));
}
throw e;
activeAspects.add(aspectHandler);
}
catch (ConfigException e) {
if (e.getLocation() == null || e.getLocation() == Location.UNKNOWN_LOCATION) {
e.setLocation(task.getLocation());
}
throw e;
catch (InstantiationException e) {
throw new ConfigException("Unable to instantiate aspect handler class "
+ aspectHandlerClass,
e);
}
catch (IllegalAccessException e) {
throw new ConfigException("Unable to access aspect handler class "
+ aspectHandlerClass,
e);
}
eventSupport.fireTaskFinished(this, task, null);
}
}
catch (RuntimeException e) {
eventSupport.fireTaskFinished(this, task, e);
throw e;
}
}
}
return activeAspects;
}

/**
* Configure an element according to the given model.
*/
private void configureElement(Object element, TaskElement model)
throws ExecutionException, ConfigException {

@@ -401,11 +634,9 @@ public class ExecutionFrame {
if (element instanceof TaskContainer &&
!introspector.supportsNestedElement(nestedElementModel.getType())) {
ExecutionTask nestedExecutionTask
= getConfiguredExecutionTask(nestedElementModel);
Task nestedTask = configureTask(nestedElementModel);
TaskContainer container = (TaskContainer)element;
container.addExecutionTask(nestedExecutionTask);
container.addTask(nestedTask);
}
else {
Object nestedElement
@@ -413,6 +644,11 @@ public class ExecutionFrame {
configureElement(nestedElement, nestedElementModel);
}
}
List aspects = getActiveAspects(model);
for (Iterator i = aspects.iterator(); i.hasNext(); ) {
AspectHandler aspectHandler = (AspectHandler)i.next();
aspectHandler.afterConfigElement(element);
}
}
catch (ClassIntrospectionException e) {
throw new ExecutionException(e, model.getLocation());
@@ -422,6 +658,42 @@ public class ExecutionFrame {
}
}

/**
* Run the tasks returned by the give iterator
*
* @param taskIterator the iterator giving the tasks to execute
*/
public void executeTasks(Iterator taskIterator) throws ExecutionException, ConfigException {
TaskElement task = null;
try {
while (taskIterator.hasNext()) {
task = (TaskElement)taskIterator.next();
try {
Task configuredTask = configureTask(task);
eventSupport.fireTaskStarted(this, task);
configuredTask.execute();
}
catch (ExecutionException e) {
if (e.getLocation() == null || e.getLocation() == Location.UNKNOWN_LOCATION) {
e.setLocation(task.getLocation());
}
throw e;
}
catch (ConfigException e) {
if (e.getLocation() == null || e.getLocation() == Location.UNKNOWN_LOCATION) {
e.setLocation(task.getLocation());
}
throw e;
}
eventSupport.fireTaskFinished(this, task, null);
}
}
catch (RuntimeException e) {
eventSupport.fireTaskFinished(this, task, e);
throw e;
}
}

private ClassIntrospector getIntrospector(Class c) {
if (introspectors.containsKey(c)) {
return (ClassIntrospector)introspectors.get(c);
@@ -510,7 +782,7 @@ public class ExecutionFrame {
* Given a name of an object, get the frame relative from this frame that
* contains that object.
*/
private ExecutionFrame getRelativeFrame(String name) throws ExecutionException {
public ExecutionFrame getRelativeFrame(String name) throws ExecutionException {
int index = name.lastIndexOf(":");
if (index == -1) {
return this;
@@ -534,7 +806,7 @@ public class ExecutionFrame {
/**
* Get the name of an object in its frame
*/
private String getNameInFrame(String name) {
public String getNameInFrame(String name) {
int index = name.lastIndexOf(":");
if (index == -1) {
return name;
@@ -553,7 +825,7 @@ public class ExecutionFrame {
/**
* Get a value from this frame or any imported frame
*/
private Object getDataValue(String name) throws ExecutionException {
public Object getDataValue(String name) throws ExecutionException {
ExecutionFrame frame = getRelativeFrame(name);
return frame.getDirectDataValue(getNameInFrame(name));
}
@@ -586,5 +858,55 @@ public class ExecutionFrame {
private boolean isDirectDataValueSet(String name) {
return dataValues.containsKey(name);
}

public void runBuild(List targetNames) throws AntException {
Throwable buildFailureCause = null;
try {
eventSupport.fireBuildStarted(this, project);
initialize();

if (targetNames.isEmpty()) {
// we just execute the default target if any
String defaultTarget = project.getDefaultTarget();
if (defaultTarget != null) {
executeTarget(defaultTarget);
}
}
else {
for (Iterator i = targetNames.iterator(); i.hasNext();) {
executeTarget((String)i.next());
}
}
eventSupport.fireBuildFinished(this, project, null);
}
catch (RuntimeException e) {
buildFailureCause = e;
throw e;
}
catch (AntException e) {
buildFailureCause = e;
throw e;
}
finally {
eventSupport.fireBuildFinished(this, project, buildFailureCause);
}
}

public void executeTarget(String targetName) throws ExecutionException, ConfigException {
// to execute a target we must determine its dependencies and
// execute them in order.
Map state = new HashMap();
Stack visiting = new Stack();
List dependencyOrder = new ArrayList();
ExecutionFrame startingFrame = getRelativeFrame(targetName);
startingFrame.fillinDependencyOrder(getNameInFrame(targetName),
dependencyOrder, state, visiting);

// Now tell each frame to execute the targets required
for (Iterator i = dependencyOrder.iterator(); i.hasNext();) {
String fullTargetName = (String)i.next();
ExecutionFrame frame = getRelativeFrame(fullTargetName);
frame.executeTargetTasks(getNameInFrame(fullTargetName));
}
}
}

+ 0
- 317
proposal/mutant/src/main/org/apache/ant/core/execution/ExecutionManager.java View File

@@ -1,317 +0,0 @@
/*
* 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.ant.core.execution;


import org.apache.ant.core.model.*;
import org.apache.ant.core.support.*;
import java.util.*;

/**
* The ExecutionManager manages the execution of Ant. It will create
* ExecutionFrames to handle the various imported projects, the
* data values associated with those projects. Before the ExecutionManager
* can be used, it must be initialised with a set of Ant libraries. These
* will contain task definitions, aspect definitions, etc.
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public class ExecutionManager implements BuildListener {
private static final String VISITING = "VISITING";
private static final String VISITED = "VISITED";

private HashMap taskDefs = new HashMap();
private HashMap converterDefs = new HashMap();
private Project project;
private ExecutionFrame mainFrame;
private Map namespaceMap = null;
private List frameInitOrder = null;
private BuildEventSupport eventSupport = new BuildEventSupport();
public void addBuildListener(BuildListener listener) {
eventSupport.addBuildListener(listener);
}
public void removeBuildListener(BuildListener listener) {
eventSupport.removeBuildListener(listener);
}

/**
* Forward any events to our listeners.
*/
public void processBuildEvent(BuildEvent event) {
eventSupport.forwardEvent(event);
}

public void addLibraries(AntLibrary[] libraries) throws ConfigException {
for (int i = 0; i < libraries.length; ++i) {
addLibrary(libraries[i]);
}
}
public void addLibrary(AntLibrary library) throws ConfigException {
for (Iterator i = library.getTaskDefinitions(); i.hasNext(); ) {
TaskDefinition taskDefinition = (TaskDefinition)i.next();
addTaskDefinition(taskDefinition);
}
for (Iterator i = library.getConverterDefinitions(); i.hasNext(); ) {
ConverterDefinition converterDef = (ConverterDefinition)i.next();
addConverterDefinition(converterDef);
}
}

public void addTaskDefinition(TaskDefinition taskDefinition) throws ConfigException {
String taskName = taskDefinition.getName();
if (taskDefs.containsKey(taskName)) {
String message = "Task " + taskName + " is defined twice" +
", in " + ((TaskDefinition)taskDefs.get(taskName)).getLibraryURL() +
" and " + taskDefinition.getLibraryURL();
throw new ConfigException(message, new Location(taskDefinition.getLibraryURL().toString()));
}
taskDefs.put(taskName, taskDefinition);
}
public void addConverterDefinition(ConverterDefinition converterDef) throws ConfigException {
String targetClassname = converterDef.getTargetClassName();
if (converterDefs.containsKey(targetClassname)) {
String message = "Converter for " + targetClassname + " is defined twice" +
", in " + ((ConverterDefinition)converterDefs.get(targetClassname)).getLibraryURL() +
" and " + converterDef.getLibraryURL();
throw new ConfigException(message, new Location(converterDef.getLibraryURL().toString()));
}
converterDefs.put(targetClassname, converterDef);
}
public void setProject(Project project) throws ConfigException {
this.project = project;
mainFrame = new ExecutionFrame(project, (Map)taskDefs.clone(),
(Map)converterDefs.clone(), null);
namespaceMap = new HashMap();
frameInitOrder = new ArrayList();
setupFrame(mainFrame);
// We iterate through all nodes of all projects and make sure every node is OK
Map state = new HashMap();
Stack visiting = new Stack();
List dependencyOrder = new ArrayList();

checkFrameTargets(mainFrame, dependencyOrder, state, visiting);
}

/**
* Check whether the targets in the given execution frame and its subframes are OK
*/
private void checkFrameTargets(ExecutionFrame frame, List dependencyOrder,
Map state, Stack visiting)
throws ConfigException {
// get the targets and just iterate through them.
for (Iterator i = frame.getProject().getTargets(); i.hasNext();) {
Target target = (Target)i.next();
fillinDependencyOrder(frame, target.getName(),
dependencyOrder, state, visiting);
}
// Now do the subframes.
for (Iterator i = frame.getImportedFrames(); i.hasNext();) {
ExecutionFrame importedFrame = (ExecutionFrame)i.next();
checkFrameTargets(importedFrame, dependencyOrder, state, visiting);
}
}
private void setupFrame(ExecutionFrame frame) {
frame.addBuildListener(this);
String namespace = frame.getNamespace();
if (namespace != null) {
namespaceMap.put(namespace, frame);
}
for (Iterator i = frame.getImportedFrameNames(); i.hasNext();) {
String importName = (String)i.next();
setupFrame(frame.getImportedFrame(importName));
}
frameInitOrder.add(frame);
}
public void runBuild(List targetNames) throws AntException {
Throwable buildFailureCause = null;
try {
eventSupport.fireBuildStarted(this, project);
// we initialise each execution frame
for (Iterator i = frameInitOrder.iterator(); i.hasNext();) {
ExecutionFrame frame = (ExecutionFrame)i.next();
frame.initialise();
}
if (targetNames.isEmpty()) {
// we just execute the default target if any
String defaultTarget = project.getDefaultTarget();
if (defaultTarget != null) {
executeTarget(defaultTarget);
}
}
else {
for (Iterator i = targetNames.iterator(); i.hasNext();) {
executeTarget((String)i.next());
}
}
eventSupport.fireBuildFinished(this, project, null);
}
catch (RuntimeException e) {
buildFailureCause = e;
throw e;
}
catch (AntException e) {
buildFailureCause = e;
throw e;
}
finally {
eventSupport.fireBuildFinished(this, project, buildFailureCause);
}
}

private ExecutionFrame getFrame(String name) {
int namespaceIndex = name.lastIndexOf(":");
if (namespaceIndex == -1) {
return mainFrame;
}
return (ExecutionFrame)namespaceMap.get(name.substring(0, namespaceIndex));
}
public void executeTarget(String targetName) throws ExecutionException, ConfigException {
// to execute a target we must determine its dependencies and
// execute them in order.
Map state = new HashMap();
Stack visiting = new Stack();
List dependencyOrder = new ArrayList();
ExecutionFrame startingFrame = getFrame(targetName);
fillinDependencyOrder(startingFrame, startingFrame.getRelativeName(targetName),
dependencyOrder, state, visiting);

// Now tell each frame to execute the target
for (Iterator i = dependencyOrder.iterator(); i.hasNext();) {
String fullTargetName = (String)i.next();
ExecutionFrame frame = getFrame(fullTargetName);
frame.executeTargetTasks(frame.getRelativeName(fullTargetName));
}
}
private void fillinDependencyOrder(ExecutionFrame frame, String targetName,
List dependencyOrder, Map state,
Stack visiting) throws ConfigException {
String fullTargetName = frame.getQualifiedName(targetName);
if (state.get(fullTargetName) == VISITED) {
return;
}
Target target = frame.getProject().getTarget(targetName);
if (target == null) {
StringBuffer sb = new StringBuffer("Target `");
sb.append(targetName);
sb.append("' does not exist in this project. ");
if (!visiting.empty()) {
String parent = (String)visiting.peek();
sb.append("It is used from target `");
sb.append(parent);
sb.append("'.");
}

throw new ConfigException(new String(sb), frame.getProject().getLocation());
}
state.put(fullTargetName, VISITING);
visiting.push(fullTargetName);
for (Iterator i = target.getDependencies(); i.hasNext(); ) {
String dependency = (String)i.next();
String fullyQualifiedName = frame.getQualifiedName(dependency);
ExecutionFrame dependencyFrame = getFrame(fullyQualifiedName);
if (dependencyFrame == null) {
StringBuffer sb = new StringBuffer("Target `");
sb.append(dependency);
sb.append("' does not exist in this project. ");
throw new ConfigException(new String(sb), target.getLocation());
}
String dependencyState = (String)state.get(fullyQualifiedName);
if (dependencyState == null) {
fillinDependencyOrder(dependencyFrame, dependencyFrame.getRelativeName(fullyQualifiedName),
dependencyOrder, state, visiting);
}
else if (dependencyState == VISITING) {
String circleDescription
= getCircularDesc(dependency, visiting);
throw new ConfigException(circleDescription, target.getLocation());
}
}
state.put(fullTargetName, VISITED);
String poppedNode = (String)visiting.pop();
if (poppedNode != fullTargetName) {
throw new ConfigException("Problem determining dependencies " +
" - expecting '" + fullTargetName +
"' but got '" + poppedNode + "'");
}
dependencyOrder.add(fullTargetName);
}
private String getCircularDesc(String end, Stack visitingNodes) {
StringBuffer sb = new StringBuffer("Circular dependency: ");
sb.append(end);
String c;
do {
c = (String)visitingNodes.pop();
sb.append(" <- ");
sb.append(c);
} while(!c.equals(end));
return new String(sb);
}
}

proposal/mutant/src/main/org/apache/ant/core/model/Task.java → proposal/mutant/src/main/org/apache/ant/core/execution/Task.java View File

@@ -51,25 +51,23 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.core.model;

package org.apache.ant.core.execution;

import org.apache.ant.core.model.*;
import org.apache.ant.core.support.*;
import java.util.*;
import java.net.URL;

/**
* A Task is a holder for Task information (attributes and elements)
* A task is a top level element in the buidl which will be processed. Ant
* currently handles two types of tasks - DataType tasks and execution tasks.
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public class Task extends TaskElement {
/**
* Create a Task of the given type
*
* @param location the location of the element
* @param type the task's type
*/
public Task(Location location, String type) {
super(location, type);
}
public interface Task {
void setTaskContext(ExecutionContext context);
void execute() throws ExecutionException;
}


+ 100
- 0
proposal/mutant/src/main/org/apache/ant/core/execution/TaskAdapter.java View File

@@ -0,0 +1,100 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "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.ant.core.execution;

import java.lang.reflect.*;
import java.util.*;

/**
* Use introspection to "adapt" an arbitrary Bean ( not extending Task, but with similar
* patterns).
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public class TaskAdapter extends AbstractTask {

/**
* The real object that is performing the work
*/
private Object worker;

private Method executeMethod = null;

public TaskAdapter(String taskType, Object worker)
throws ExecutionException {
this.worker = worker;
try {
Class workerClass = worker.getClass();
executeMethod = workerClass.getMethod("execute", new Class[0]);
if (executeMethod == null) {
throw new ExecutionException("No execute method in the class for the <"
+ taskType + "> task.");
}
}
catch (NoSuchMethodException e) {
throw new ExecutionException(e);
}
}

public void execute() throws ExecutionException {
try {
executeMethod.invoke(worker, null);
}
catch( Exception ex ) {
throw new ExecutionException(ex);
}
}
}

+ 1
- 1
proposal/mutant/src/main/org/apache/ant/core/execution/TaskContainer.java View File

@@ -67,6 +67,6 @@ public interface TaskContainer {
/**
* Add a task to the container.
*/
void addExecutionTask(ExecutionTask executionTask) throws ExecutionException;
void addTask(Task task) throws ExecutionException;
}


+ 1
- 1
proposal/mutant/src/main/org/apache/ant/core/execution/TaskDefinition.java View File

@@ -117,7 +117,7 @@ public class TaskDefinition {
*/
public synchronized Class getExecutionTaskClass() throws ClassNotFoundException {
if (taskClass == null) {
taskClass = taskClassLoader.loadClass(taskClassName);
taskClass = Class.forName(taskClassName, true, taskClassLoader);
}
return taskClass;
}


+ 42
- 12
proposal/mutant/src/main/org/apache/ant/core/model/BuildElement.java View File

@@ -63,20 +63,13 @@ import org.apache.ant.core.support.*;
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public class BuildElement {
/**
* The aspects defined for this element.
*/
private Map aspects;
/** The aspects defined for this element. */
private Map aspectMaps;

/**
* The location of this element
*/
/** The location of this element */
private Location location;
/**
* A comment associated with this element, if any
*
*/
/** A comment associated with this element, if any */
private String comment;
/**
@@ -121,7 +114,44 @@ public class BuildElement {
* @param aspects a Map of apects that relate to this build element.
*/
public void setAspects(Map aspects) {
this.aspects = aspects;
aspectMaps = new HashMap();
for (Iterator i = aspects.keySet().iterator(); i.hasNext(); ) {
String aspectName = (String)i.next();
int separator = aspectName.indexOf(":");
if (separator != -1) {
String prefix = aspectName.substring(0, separator);
String name = aspectName.substring(separator + 1);
if (prefix.length() != 0 && name.length() != 0) {
Map prefixMap = (Map)aspectMaps.get(prefix);
if (prefixMap == null) {
prefixMap = new HashMap();
aspectMaps.put(prefix, prefixMap);
}
prefixMap.put(name, aspects.get(aspectName));
}
}
}
}
/**
* Get an iterator on the aspects which have been given values on this element
*
* @return an iterator of Strings , being the aspects which have been given values on
* this element.
*/
public Iterator getAspectNames() {
return aspectMaps.keySet().iterator();
}
/**
* Get the set of attribute values related to the given aspect
*
* @param apsectPrefix the prefix used to identify the prefix.
*
* @return a map of the attribute values for the given aspect.
*/
public Map getAspectAttributes(String aspectPrefix) {
return (Map)aspectMaps.get(aspectPrefix);
}
}


+ 1
- 1
proposal/mutant/src/main/org/apache/ant/core/model/Project.java View File

@@ -191,7 +191,7 @@ public class Project extends BuildElement {
* @param task a task to be executed when an execution context
* is associated with the Project (a non-target task)
*/
public void addTask(Task task) {
public void addTask(TaskElement task) {
tasks.add(task);
}


+ 1
- 1
proposal/mutant/src/main/org/apache/ant/core/model/Target.java View File

@@ -100,7 +100,7 @@ public class Target extends BuildElement {
*
* @param task the task to be added to the target.
*/
public void addTask(Task task) {
public void addTask(TaskElement task) {
tasks.add(task);
}


+ 4
- 1
proposal/mutant/src/main/org/apache/ant/core/support/AntClassLoader.java View File

@@ -59,14 +59,17 @@ import java.net.*;
import java.io.*;

/**
* A ReverseURLclassLoader is a type of URL classloader which reverse the standard
* The AntClassLoader is a type of URL classloader which reverse the standard
* lookup order to load things from the URLs first and then to use the parent class
* loader only if the class does not exist in the URLs.
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public class AntClassLoader extends URLClassLoader {
/** A Debug label to print when the Classloader finds or fails to find a class. */
private String debugLabel = null;
/** A flag whihc controls whether messages are logged by the loader */
private boolean debug = false;

private void dumpURLs() {


+ 1
- 1
proposal/mutant/src/main/org/apache/ant/core/support/AntException.java View File

@@ -110,7 +110,7 @@ public abstract class AntException extends Exception {
* @param cause Exception that might have caused this one.
*/
public AntException(Throwable cause) {
super(cause.toString());
super(cause.getMessage());
this.cause = cause;
}



+ 131
- 0
proposal/mutant/src/main/org/apache/ant/core/types/DataType.java View File

@@ -0,0 +1,131 @@
/*
* 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.ant.core.types;

import org.apache.ant.core.execution.*;
import java.io.*;

/**
* A DataType is an element which can register a named value in the
* ExecutionFrame's context.
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
*/
public abstract class DataType extends AbstractTask {
private String reference = null;

final public void execute() throws ExecutionException {
}


/**
* Creates an exception that indicates that refid has to be the
* only attribute if it is set.
*/
protected ExecutionException tooManyAttributes() {
return new ExecutionException("You must not specify more than one attribute" +
" when using refid" );
}

/**
* Creates an exception that indicates that this XML element must
* not have child elements if the refid attribute is set.
*/
protected ExecutionException noChildrenAllowed() {
return new ExecutionException("You must not specify nested elements when using refid");
}

/**
* Creates an exception that indicates the user has generated a
* loop of data types referencing each other.
*/
protected ExecutionException circularReference() {
return new ExecutionException("This data type contains a circular reference.");
}
/**
* Makes this instance in effect a reference to another DataType
* instance.
*/
public void setRefid(String reference) throws ExecutionException {
this.reference = reference;
// check the reference now
getReferencedObject();
}

/**
* Has the refid attribute of this element been set?
*/
public boolean isReference() {
return reference != null;
}

protected Object getReferencedObject() throws ExecutionException {
if (!isReference()) {
throw new ExecutionException("You cannot get a referenced value from a data type " +
"which does not have the refid attribute");
}
Object referencedObject = getTaskContext().getDataValue(reference);
if (referencedObject == null) {
throw new ExecutionException("Unable to locate the reference specified by refid '" +
getReference() + "'");
}
return referencedObject;
}
protected String getReference() {
return reference;
}
}

+ 369
- 0
proposal/mutant/src/main/org/apache/ant/core/types/PatternSet.java View File

@@ -0,0 +1,369 @@
/*
* 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.ant.core.types;

import java.io.*;
import java.util.*;
import org.apache.ant.core.execution.*;

/**
* Named collection of include/exclude tags.
*
* <p>Moved out of MatchingTask to make it a standalone object that
* could be referenced (by scripts for example).
*
* @author Arnout J. Kuiper <a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a>
* @author Stefano Mazzocchi <a href="mailto:stefano@apache.org">stefano@apache.org</a>
* @author Sam Ruby <a href="mailto:rubys@us.ibm.com">rubys@us.ibm.com</a>
* @author Jon S. Stevens <a href="mailto:jon@clearink.com">jon@clearink.com</a>
* @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a>
*/
public class PatternSet extends DataType {
private List includeList = new ArrayList();
private List excludeList = new ArrayList();
// private File incl = null;
// private File excl = null;
//
/**
* inner class to hold a name on list. "If" and "Unless" attributes
* may be used to invalidate the entry based on the existence of a
* property (typically set thru the use of the Available task).
*/
public class NameEntry {
private String name;
// private String ifCond;
// private String unlessCond;

public void setName(String name) {
this.name = name;
}

// public void setIf(String cond) {
// ifCond = cond;
// }
//
// public void setUnless(String cond) {
// unlessCond = cond;
// }
//
public String getName() {
return name;
}

// public String evalName(Project p) {
// return valid(p) ? name : null;
// }

// private boolean valid(Project p) {
// if (ifCond != null && p.getProperty(ifCond) == null) {
// return false;
// } else if (unlessCond != null && p.getProperty(unlessCond) != null) {
// return false;
// }
// return true;
// }
}


public PatternSet() {
}

/**
* Makes this instance in effect a reference to another PatternSet
* instance.
*
* <p>You must not set another attribute or nest elements inside
* this element if you make it a reference.</p>
*/
public void setRefid(String reference) throws ExecutionException {
if (!includeList.isEmpty() || !excludeList.isEmpty()) {
throw tooManyAttributes();
}
super.setRefid(reference);
}

/**
* add a name entry on the include list
*/
public NameEntry createInclude() throws ExecutionException {
if (isReference()) {
throw noChildrenAllowed();
}
return addPatternToList(includeList);
}
/**
* add a name entry on the exclude list
*/
public NameEntry createExclude() throws ExecutionException {
if (isReference()) {
throw noChildrenAllowed();
}
return addPatternToList(excludeList);
}

/**
* 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(String includes) throws ExecutionException {
if (isReference()) {
throw tooManyAttributes();
}
if (includes != null && includes.length() > 0) {
StringTokenizer tok = new StringTokenizer(includes, ", ", false);
while (tok.hasMoreTokens()) {
createInclude().setName(tok.nextToken());
}
}
}

/**
* 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(String excludes) throws ExecutionException {
if (isReference()) {
throw tooManyAttributes();
}
if (excludes != null && excludes.length() > 0) {
StringTokenizer tok = new StringTokenizer(excludes, ", ", false);
while (tok.hasMoreTokens()) {
createExclude().setName(tok.nextToken());
}
}
}

/**
* add a name entry to the given list
*/
private NameEntry addPatternToList(List list) {
NameEntry result = new NameEntry();
list.add(result);
return result;
}

// /**
// * Sets the name of the file containing the includes patterns.
// *
// * @param incl The file to fetch the include patterns from.
// */
// public void setIncludesfile(File incl) throws BuildException {
// if (isReference()) {
// throw tooManyAttributes();
// }
// if (!incl.exists()) {
// throw new BuildException("Includesfile "+incl.getAbsolutePath()
// +" not found.");
// }
// this.incl = incl;
// }
//
// /**
// * Sets the name of the file containing the excludes patterns.
// *
// * @param excl The file to fetch the exclude patterns from.
// */
// public void setExcludesfile(File excl) throws BuildException {
// if (isReference()) {
// throw tooManyAttributes();
// }
// if (!excl.exists()) {
// throw new BuildException("Excludesfile "+excl.getAbsolutePath()
// +" not found.");
// }
// this.excl = excl;
// }
//
// /**
// * Reads path matching patterns from a file and adds them to the
// * includes or excludes list (as appropriate).
// */
// private void readPatterns(File patternfile, Vector patternlist, Project p)
// throws BuildException {
//
// try {
// // Get a FileReader
// BufferedReader patternReader =
// new BufferedReader(new FileReader(patternfile));
//
// // Create one NameEntry in the appropriate pattern list for each
// // line in the file.
// String line = patternReader.readLine();
// while (line != null) {
// if (line.length() > 0) {
// line = ProjectHelper.replaceProperties(p, line,
// p.getProperties());
// addPatternToList(patternlist).setName(line);
// }
// line = patternReader.readLine();
// }
// } catch(IOException ioe) {
// String msg = "An error occured while reading from pattern file: "
// + patternfile;
// throw new BuildException(msg, ioe);
// }
// }
//
/**
* Adds the patterns of the other instance to this set.
*/
public void append(PatternSet other) throws ExecutionException {
if (isReference()) {
throw new ExecutionException("Cannot append to a reference");
}

String[] incl = other.getIncludePatterns();
if (incl != null) {
for (int i=0; i<incl.length; i++) {
createInclude().setName(incl[i]);
}
}
String[] excl = other.getExcludePatterns();
if (excl != null) {
for (int i=0; i<excl.length; i++) {
createExclude().setName(excl[i]);
}
}
}

/**
* Returns the filtered include patterns.
*/
public String[] getIncludePatterns() throws ExecutionException {
if (isReference()) {
return getReferencedPatternSet().getIncludePatterns();
} else {
// readFiles(p);
return makeArray(includeList);
}
}

/**
* Returns the filtered include patterns.
*/
public String[] getExcludePatterns() throws ExecutionException {
if (isReference()) {
return getReferencedPatternSet().getExcludePatterns();
} else {
// readFiles(p);
return makeArray(excludeList);
}
}

// /**
// * helper for FileSet.
// */
// boolean hasPatterns() {
// return incl != null || excl != null
// || includeList.size() > 0 || excludeList.size() > 0;
// }
//
/**
* Performs the check for circular references and returns the
* referenced PatternSet.
*/
private PatternSet getReferencedPatternSet() throws ExecutionException {
Object o = getReferencedObject();
if (!(o instanceof PatternSet)) {
throw new ExecutionException(getReference() + " doesn\'t denote a patternset");;
} else {
return (PatternSet) o;
}
}


/**
* Convert a list of NameEntry elements into an array of Strings.
*/
private String[] makeArray(List list) {
if (list.size() == 0) {
return null;
}

List tmpNames = new Vector();
for (Iterator i = list.iterator() ; i.hasNext() ;) {
NameEntry ne = (NameEntry)i.next();
String pattern = ne.getName();
if (pattern != null && pattern.length() > 0) {
tmpNames.add(pattern);
}
}

String[] result = (String[])tmpNames.toArray(new String[0]);
return result;
}
// /**
// * Read includefile ot excludefile if not already done so.
// */
// private void readFiles(Project p) {
// if (incl != null) {
// readPatterns(incl, includeList, p);
// incl = null;
// }
// if (excl != null) {
// readPatterns(excl, excludeList, p);
// excl = null;
// }
// }
//
}

+ 29
- 2
proposal/mutant/src/main/org/apache/ant/core/xml/AntLibParser.java View File

@@ -72,6 +72,7 @@ import org.xml.sax.helpers.DefaultHandler;
public class AntLibParser {
public static final String TASK_ELEMENT = "taskdef";
public static final String CONVERTER_ELEMENT = "converter";
public static final String ASPECT_ELEMENT = "aspect";
/**
* The factory used to create SAX parsers.
@@ -191,6 +192,9 @@ public class AntLibParser {
else if (qualifiedName.equals(CONVERTER_ELEMENT)) {
createConverterDef(attributes);
}
else if (qualifiedName.equals(ASPECT_ELEMENT)) {
createAspectHandler(attributes);
}
else {
throw new SAXParseException("Unrecognized element <" +
qualifiedName + "> in Ant library definition", getLocator());
@@ -219,7 +223,6 @@ public class AntLibParser {
"<" + TASK_ELEMENT + "> element", getLocator());
}
System.out.println("Adding taskdef for " + taskName);
TaskDefinition taskdef = new TaskDefinition(getSourceURL(), taskName, className, componentLoader);
library.addTaskDefinition(taskdef);
}
@@ -229,7 +232,7 @@ public class AntLibParser {
validAttributes.add("target");
validAttributes.add("classname");
Map attributeValues
= AttributeValidator.validateAttributes("convert", attributes,
= AttributeValidator.validateAttributes(CONVERTER_ELEMENT, attributes,
validAttributes, getLocator());
String targetClassName = (String)attributeValues.get("target");
String className = (String)attributeValues.get("classname");
@@ -248,6 +251,30 @@ public class AntLibParser {
library.addConverterDefinition(converterDef);
}

public void createAspectHandler(Attributes attributes) throws SAXParseException {
Set validAttributes = new HashSet();
validAttributes.add("prefix");
validAttributes.add("classname");
Map attributeValues
= AttributeValidator.validateAttributes(ASPECT_ELEMENT, attributes,
validAttributes, getLocator());
String aspectPrefix = (String)attributeValues.get("prefix");
String aspectClassname = (String)attributeValues.get("classname");
if (aspectPrefix == null) {
throw new SAXParseException("'prefix' attribute is required in a <"
+ ASPECT_ELEMENT + "> element",
getLocator());
}
if (aspectClassname == null) {
throw new SAXParseException("'classname' attribute is required in a " +
"<" + ASPECT_ELEMENT + "> element", getLocator());
}
AspectDefinition aspectDef
= new AspectDefinition(getSourceURL(), aspectPrefix, aspectClassname, componentLoader);
library.addAspectDefinition(aspectDef);
}
public void endElement(String namespaceURI, String localName, String qName) {
if (state == STATE_ROOT_SEEN && qName.equals("antlib")) {
state = STATE_FINISHED;


+ 12
- 85
proposal/mutant/src/main/org/apache/ant/core/xml/XMLProjectParser.java View File

@@ -373,10 +373,10 @@ public class XMLProjectParser {
}
else {
// everything else is a task
TaskHandler taskHandler
= new TaskHandler(getXMLReader(), this, getLocator(),
TaskElementHandler taskElementHandler
= new TaskElementHandler(getXMLReader(), this, getLocator(),
attributes, qualifiedName);
project.addTask(taskHandler.getTask());
project.addTask(taskElementHandler.getTaskElement());
}
}
@@ -730,10 +730,10 @@ public class XMLProjectParser {
public void startElement(String uri, String localName, String qualifiedName,
Attributes attributes) throws SAXParseException {
// everything is a task
TaskHandler taskHandler
= new TaskHandler(getXMLReader(), this, getLocator(),
attributes, qualifiedName);
target.addTask(taskHandler.getTask());
TaskElementHandler taskHandler
= new TaskElementHandler(getXMLReader(), this, getLocator(),
attributes, qualifiedName);
target.addTask(taskHandler.getTaskElement());
}
/**
@@ -747,80 +747,7 @@ public class XMLProjectParser {
}

/**
* A Task Handler is used to parse tasks.
*/
private class TaskHandler extends ElementHandler {
/**
* The task being parsed by this handler.
*/
private Task task;
/**
* Create a task handler to parse the Task element
*
* @param xmlReader the XML parser being used to parse the task element.
* @param parent the parent element handler.
* @param locator the SAX locator object used to associate elements with source
* locations.
* @param attributes attributes of the task
* @param taskTagName the name of the task.
*/
public TaskHandler(XMLReader xmlReader, ContentHandler parent, Locator locator,
Attributes attributes, String taskTagName) {
super(xmlReader, parent, locator);
task = new Task(getLocation(locator), taskTagName);
Map aspects = new HashMap();
for (int i = 0; i < attributes.getLength(); ++i) {
String attributeName = attributes.getQName(i);
String attributeValue = attributes.getValue(i);
if (attributeName.indexOf(":") != -1) {
// potential aspect attribute
aspects.put(attributeName, attributeValue);
}
else {
task.addAttribute(attributeName, attributeValue);
}
}
task.setAspects(aspects);
}
/*
* Process a nested element within this task. All nested elements within
* the task are treated as taskelements.
*
* @param uri The Namespace URI.
* @param localName The local name (without prefix).
* @param qualifiedName The qualified name (with prefix)
* @param attributes The attributes attached to the element.
*
* @throws SAXParseException if there is a parsing problem.
*/
public void startElement(String uri, String localName, String qualifiedName,
Attributes attributes) throws SAXParseException {
// everything within a task is a task element
TaskElementHandler taskElementHandler
= new TaskElementHandler(getXMLReader(), this, getLocator(),
attributes, qualifiedName);
task.addTaskElement(taskElementHandler.getTaskElement());
}
public void characters(char[] buf, int start, int end) throws SAXParseException {
task.addText(new String(buf, start, end));
}

/**
* Get the task that is being parsed
*
* @return the task being parsed by this task handler.
*/
public Task getTask() {
return task;
}
}
/**
* A Task Element Handler parses the nested elements of tasks.
* A TaskElementHandler parses the task elements of a build
*/
private class TaskElementHandler extends ElementHandler {
/**
@@ -839,7 +766,7 @@ public class XMLProjectParser {
* @param elementTagName the name of the task element.
*/
public TaskElementHandler(XMLReader xmlReader, ContentHandler parent, Locator locator,
Attributes attributes, String elementTagName) {
Attributes attributes, String elementTagName) {
super(xmlReader, parent, locator);
taskElement
= new TaskElement(getLocation(locator), elementTagName);
@@ -873,10 +800,10 @@ public class XMLProjectParser {
public void startElement(String uri, String localName, String qualifiedName,
Attributes attributes) throws SAXParseException {
// everything within a task element is also a task element
TaskElementHandler taskElementHandler
TaskElementHandler nestedHandler
= new TaskElementHandler(getXMLReader(), this, getLocator(),
attributes, qualifiedName);
taskElement.addTaskElement(taskElementHandler.getTaskElement());
attributes, qualifiedName);
taskElement.addTaskElement(nestedHandler.getTaskElement());
}
public void characters(char[] buf, int start, int end) throws SAXParseException {


+ 17
- 13
proposal/mutant/src/main/org/apache/ant/frontend/Commandline.java View File

@@ -111,7 +111,7 @@ public class Commandline {
}
public void runAnt(String[] args) {
ExecutionManager executionManager = null;
ExecutionFrame mainFrame = null;
try {
parseArguments(args);
Project project = getProject();
@@ -121,10 +121,16 @@ public class Commandline {

// Get the list of library components
AntLibrary[] libraries = ComponentManager.getComponents();
executionManager = new ExecutionManager();
executionManager.addLibraries(libraries);
executionManager.setProject(project);
addBuildListeners(executionManager);

mainFrame = new ExecutionFrame(project, libraries);
// We iterate through all nodes of all projects and make sure every node is OK
Map state = new HashMap();
Stack visiting = new Stack();
List dependencyOrder = new ArrayList();
mainFrame.checkTargets(dependencyOrder, state, visiting);
addBuildListeners(mainFrame);
}
catch (AntException e) {
Location location = e.getLocation();
@@ -132,19 +138,17 @@ public class Commandline {
if (location != null && location != Location.UNKNOWN_LOCATION) {
System.out.print(location);
}
System.out.print(e.getMessage());
System.out.println(e.getMessage());
if (cause != null) {
System.out.println();
System.out.print("Root cause: " + cause.getClass().getName() + ": " + cause.getMessage());
System.out.println("Root cause: " + cause.getClass().getName() + ": " + cause.getMessage());
}
System.out.println();
System.exit(1);
}
try {
executionManager.runBuild(targets);
mainFrame.runBuild(targets);
System.exit(0);
}
catch (Exception e) {
@@ -152,18 +156,18 @@ public class Commandline {
}
}
protected void addBuildListeners(ExecutionManager executionManager)
protected void addBuildListeners(ExecutionFrame frame)
throws ConfigException {

// Add the default listener
executionManager.addBuildListener(createLogger());
frame.addBuildListener(createLogger());

for (Iterator i = listeners.iterator(); i.hasNext(); ) {
String className = (String) i.next();
try {
BuildListener listener =
(BuildListener) Class.forName(className).newInstance();
executionManager.addBuildListener(listener);
frame.addBuildListener(listener);
}
catch(Exception exc) {
throw new ConfigException("Unable to instantiate listener " + className, exc);


+ 5
- 7
proposal/mutant/src/main/org/apache/ant/frontend/DefaultLogger.java View File

@@ -131,13 +131,11 @@ public class DefaultLogger implements BuildLogger {
if (location != null && location != Location.UNKNOWN_LOCATION) {
out.print(location);
}
out.print(e.getMessage());
out.println(e.getMessage());
if (cause != null) {
out.println();
out.print("Root cause: " + cause.getClass().getName() + ": " + cause.getMessage());
out.println("Root cause: " + cause.toString());
}
out.println();
}
else {
t.printStackTrace(err);
@@ -183,9 +181,9 @@ public class DefaultLogger implements BuildLogger {
// Print out the name of the task if we're in one
Object buildElement = event.getBuildElement();
if (buildElement instanceof Task) {
Task task = (Task)buildElement;
String name = task.getType();
if (buildElement instanceof TaskElement) {
TaskElement taskElement = (TaskElement)buildElement;
String name = taskElement.getType();
if (!emacsMode) {
String msg = "[" + name + "] ";


Loading…
Cancel
Save