Browse Source

Mutant can now build itself - although it cannot bootstrap

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271149 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 23 years ago
parent
commit
81c17b6164
53 changed files with 2111 additions and 770 deletions
  1. +1
    -2
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java
  2. +18
    -18
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java
  3. +1
    -1
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrarySpec.java
  4. +1
    -1
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfig.java
  5. +1
    -1
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfigHandler.java
  6. +29
    -21
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java
  7. +11
    -2
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ClassIntrospector.java
  8. +358
    -0
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java
  9. +11
    -13
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java
  10. +14
    -13
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionDataService.java
  11. +182
    -308
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionFrame.java
  12. +14
    -10
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java
  13. +110
    -0
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ImportInfo.java
  14. +6
    -8
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java
  15. +2
    -2
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/BuildElementHandler.java
  16. +2
    -2
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/IncludeHandler.java
  17. +1
    -1
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/NoProjectReadException.java
  18. +3
    -3
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java
  19. +5
    -5
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/RefHandler.java
  20. +14
    -6
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/TargetHandler.java
  21. +2
    -2
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/XMLProjectParser.java
  22. +8
    -3
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java
  23. +138
    -9
      proposal/mutant/src/java/antlibs/ant1compat/antlib.xml
  24. +59
    -10
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/AntClassLoader.java
  25. +1
    -1
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/BuildEvent.java
  26. +2
    -2
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java
  27. +10
    -1
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java
  28. +7
    -2
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java
  29. +6
    -0
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/types/DataType.java
  30. +3
    -0
      proposal/mutant/src/java/antlibs/system/antlib.xml
  31. +44
    -48
      proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Ant.java
  32. +293
    -0
      proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/AntBase.java
  33. +87
    -0
      proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/AntCall.java
  34. +32
    -4
      proposal/mutant/src/java/cli/org/apache/ant/cli/Commandline.java
  35. +184
    -156
      proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java
  36. +122
    -0
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java
  37. +1
    -33
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java
  38. +7
    -7
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java
  39. +11
    -2
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java
  40. +14
    -5
      proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java
  41. +48
    -3
      proposal/mutant/src/java/common/org/apache/ant/common/event/BuildListener.java
  42. +1
    -1
      proposal/mutant/src/java/common/org/apache/ant/common/model/BuildElement.java
  43. +1
    -1
      proposal/mutant/src/java/common/org/apache/ant/common/model/ModelElement.java
  44. +1
    -1
      proposal/mutant/src/java/common/org/apache/ant/common/model/ModelException.java
  45. +49
    -40
      proposal/mutant/src/java/common/org/apache/ant/common/model/Project.java
  46. +1
    -1
      proposal/mutant/src/java/common/org/apache/ant/common/model/Target.java
  47. +36
    -0
      proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
  48. +4
    -3
      proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java
  49. +12
    -9
      proposal/mutant/src/java/common/org/apache/ant/common/util/AntException.java
  50. +1
    -1
      proposal/mutant/src/java/common/org/apache/ant/common/util/CircularDependencyChecker.java
  51. +1
    -4
      proposal/mutant/src/java/common/org/apache/ant/common/util/CircularDependencyException.java
  52. +1
    -4
      proposal/mutant/src/java/common/org/apache/ant/common/util/ConfigException.java
  53. +140
    -0
      proposal/mutant/src/java/common/org/apache/ant/common/util/StringUtils.java

+ 1
- 2
proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java View File

@@ -52,8 +52,7 @@
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.antlib;
import org.apache.ant.antcore.util.ConfigException;

import org.apache.ant.common.util.ConfigException;
import org.apache.ant.antcore.xml.ElementHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXParseException;


+ 18
- 18
proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java View File

@@ -60,11 +60,11 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.ant.antcore.util.CircularDependencyChecker;
import org.apache.ant.antcore.util.CircularDependencyException;
import org.apache.ant.antcore.util.ConfigException;
import org.apache.ant.antcore.xml.ParseContext;
import org.apache.ant.antcore.xml.XMLParseException;
import org.apache.ant.common.util.CircularDependencyChecker;
import org.apache.ant.common.util.CircularDependencyException;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.init.InitConfig;
import org.apache.ant.init.InitUtils;
import org.apache.ant.init.LoaderUtils;
@@ -102,10 +102,10 @@ public class AntLibManager {
* @param libURL the URL from which Ant libraries are to be loaded
* @exception MalformedURLException if the URL for the individual
* library components cannot be formed
* @exception ConfigException if the library specs cannot be parsed
* @exception ExecutionException if the library specs cannot be parsed
*/
public void addAntLibraries(Map librarySpecs, URL libURL)
throws MalformedURLException, ConfigException {
throws MalformedURLException, ExecutionException {
URL[] libURLs = LoaderUtils.getLocationURLs(libURL, libURL.toString(),
ANTLIB_EXTENSIONS);

@@ -122,7 +122,7 @@ public class AntLibManager {
if (antLibrarySpec != null) {
String libraryId = antLibrarySpec.getLibraryId();
if (librarySpecs.containsKey(libraryId)) {
throw new ConfigException("Found more than one "
throw new ExecutionException("Found more than one "
+ "copy of library with id = " + libraryId +
" (" + libURLs[i] + ")");
}
@@ -134,7 +134,7 @@ public class AntLibManager {
// ignore file not found exceptions - means the
// jar does not provide META-INF/antlib.xml
if (!(t instanceof FileNotFoundException)) {
throw new ConfigException("Unable to parse Ant library "
throw new ExecutionException("Unable to parse Ant library "
+ libURLs[i], e);
}
}
@@ -149,12 +149,12 @@ public class AntLibManager {
* @param librarySpecs the loaded specifications of the Ant libraries
* @param initConfig the Ant initialization configuration
* @param libraries the collection of libraries already configured
* @exception ConfigException if a library cannot be configured from the
* given specification
* @exception ExecutionException if a library cannot be configured from
* the given specification
*/
public void configLibraries(InitConfig initConfig, Map librarySpecs,
Map libraries)
throws ConfigException {
throws ExecutionException {

// check if any already defined
for (Iterator i = librarySpecs.keySet().iterator(); i.hasNext(); ) {
@@ -162,7 +162,7 @@ public class AntLibManager {
if (libraries.containsKey(libraryId)) {
AntLibrary currentVersion
= (AntLibrary)libraries.get(libraryId);
throw new ConfigException("Ant Library \"" + libraryId
throw new ExecutionException("Ant Library \"" + libraryId
+ "\" is already loaded from "
+ currentVersion.getDefinitionURL());
}
@@ -185,12 +185,12 @@ public class AntLibManager {
* @param libLocationString URL or file where libraries can be found
* @param librarySpecs A collection of library specs which will be
* populated with the libraries found
* @exception ConfigException if the libraries cannot be loaded
* @exception ExecutionException if the libraries cannot be loaded
* @exception MalformedURLException if the library's location cannot be
* formed
*/
public void loadLib(Map librarySpecs, String libLocationString)
throws ConfigException, MalformedURLException {
throws ExecutionException, MalformedURLException {

File libLocation = new File(libLocationString);
if (!libLocation.exists()) {
@@ -198,7 +198,7 @@ public class AntLibManager {
URL libLocationURL = new URL(libLocationString);
if (!libLocationURL.getProtocol().equals("file")
&& !remoteAllowed) {
throw new ConfigException("The config library "
throw new ExecutionException("The config library "
+ "location \"" + libLocationString
+ "\" cannot be used because config does "
+ "not allow remote libraries");
@@ -223,13 +223,13 @@ public class AntLibManager {
* dependencies.
* @param libraries the collection of libraries which have already been
* configured
* @exception ConfigException if the library cannot be configured.
* @exception ExecutionException if the library cannot be configured.
*/
private void configLibrary(InitConfig initConfig, Map librarySpecs,
String libraryId,
CircularDependencyChecker configuring,
Map libraries)
throws ConfigException {
throws ExecutionException {

try {
configuring.visitNode(libraryId);
@@ -240,7 +240,7 @@ public class AntLibManager {
if (extendsId != null) {
if (!libraries.containsKey(extendsId)) {
if (!librarySpecs.containsKey(extendsId)) {
throw new ConfigException("Could not find library, "
throw new ExecutionException("Could not find library, "
+ extendsId + ", upon which library "
+ libraryId + " depends");
}
@@ -284,7 +284,7 @@ public class AntLibManager {
libraries.put(libraryId, antLibrary);
configuring.leaveNode(libraryId);
} catch (CircularDependencyException e) {
throw new ConfigException(e);
throw new ExecutionException(e);
}
}



+ 1
- 1
proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrarySpec.java View File

@@ -57,7 +57,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ant.antcore.util.ConfigException;
import org.apache.ant.common.util.ConfigException;

/**
* This class represents the specification of an Ant library. It is merely


+ 1
- 1
proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfig.java View File

@@ -60,7 +60,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.ant.antcore.util.ConfigException;
import org.apache.ant.common.util.ConfigException;
import org.apache.ant.common.util.PathTokenizer;
import org.apache.ant.init.InitUtils;



+ 1
- 1
proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfigHandler.java View File

@@ -52,7 +52,7 @@
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.config;
import org.apache.ant.antcore.util.ConfigException;
import org.apache.ant.common.util.ConfigException;
import org.apache.ant.antcore.xml.ElementHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXParseException;


+ 29
- 21
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java View File

@@ -56,7 +56,7 @@ import java.util.ArrayList;
import java.util.Iterator;

import java.util.List;
import org.apache.ant.antcore.model.ModelElement;
import org.apache.ant.common.model.ModelElement;
import org.apache.ant.common.event.BuildListener;
import org.apache.ant.common.event.BuildEvent;

@@ -101,19 +101,6 @@ public class BuildEventSupport {
listeners.remove(listener);
}

/**
* Forward the given event to the subscibed listeners
*
* @param event the event to be forwarded to the listeners
*/
public void forwardEvent(BuildEvent event) {
for (Iterator i = listeners.iterator(); i.hasNext(); ) {
BuildListener listener = (BuildListener)i.next();

listener.processBuildEvent(event);
}
}

/**
* Fire a build started event
*
@@ -121,7 +108,10 @@ public class BuildEventSupport {
*/
public void fireBuildStarted(ModelElement element) {
BuildEvent event = new BuildEvent(element, BuildEvent.BUILD_STARTED);
forwardEvent(event);
for (Iterator i = listeners.iterator(); i.hasNext(); ) {
BuildListener listener = (BuildListener)i.next();
listener.buildStarted(event);
}
}

/**
@@ -134,7 +124,10 @@ public class BuildEventSupport {
Throwable cause) {
BuildEvent event = new BuildEvent(element, BuildEvent.BUILD_FINISHED,
cause);
forwardEvent(event);
for (Iterator i = listeners.iterator(); i.hasNext(); ) {
BuildListener listener = (BuildListener)i.next();
listener.buildFinished(event);
}
}

/**
@@ -144,7 +137,10 @@ public class BuildEventSupport {
*/
public void fireTargetStarted(ModelElement element) {
BuildEvent event = new BuildEvent(element, BuildEvent.TARGET_STARTED);
forwardEvent(event);
for (Iterator i = listeners.iterator(); i.hasNext(); ) {
BuildListener listener = (BuildListener)i.next();
listener.targetStarted(event);
}
}

/**
@@ -157,7 +153,10 @@ public class BuildEventSupport {
Throwable cause) {
BuildEvent event = new BuildEvent(element, BuildEvent.TARGET_FINISHED,
cause);
forwardEvent(event);
for (Iterator i = listeners.iterator(); i.hasNext(); ) {
BuildListener listener = (BuildListener)i.next();
listener.targetFinished(event);
}
}

/**
@@ -167,7 +166,10 @@ public class BuildEventSupport {
*/
public void fireTaskStarted(ModelElement element) {
BuildEvent event = new BuildEvent(element, BuildEvent.TASK_STARTED);
forwardEvent(event);
for (Iterator i = listeners.iterator(); i.hasNext(); ) {
BuildListener listener = (BuildListener)i.next();
listener.taskStarted(event);
}
}

/**
@@ -180,7 +182,10 @@ public class BuildEventSupport {
Throwable cause) {
BuildEvent event = new BuildEvent(element, BuildEvent.TASK_FINISHED,
cause);
forwardEvent(event);
for (Iterator i = listeners.iterator(); i.hasNext(); ) {
BuildListener listener = (BuildListener)i.next();
listener.taskFinished(event);
}
}

/**
@@ -193,7 +198,10 @@ public class BuildEventSupport {
public void fireMessageLogged(ModelElement element,
String message, int priority) {
BuildEvent event = new BuildEvent(element, message, priority);
forwardEvent(event);
for (Iterator i = listeners.iterator(); i.hasNext(); ) {
BuildListener listener = (BuildListener)i.next();
listener.messageLogged(event);
}
}
}


+ 11
- 2
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ClassIntrospector.java View File

@@ -95,7 +95,16 @@ public class ClassIntrospector {
&& !args[0].isArray()) {
reflector.addAttributeMethod(m, getPropertyName(name, "set"),
converters);
} else if (name.startsWith("add")
} else if (name.startsWith("addConfigured")
&& name.length() > 13
&& returnType.equals(Void.TYPE)
&& args.length == 1
&& !args[0].equals(String.class)
&& !args[0].isArray()
&& !args[0].isPrimitive()) {
reflector.addElementMethod(m,
getPropertyName(name, "addConfigured"));
} else if (name.startsWith("add")
&& name.length() > 3
&& returnType.equals(Void.TYPE)
&& args.length == 1
@@ -103,7 +112,7 @@ public class ClassIntrospector {
&& !args[0].isArray()
&& !args[0].isPrimitive()) {
reflector.addElementMethod(m, getPropertyName(name, "add"));
} else if (name.startsWith("create")
} else if (name.startsWith("create")
&& name.length() > 6
&& !returnType.isArray()
&& !returnType.isPrimitive()


+ 358
- 0
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java View File

@@ -0,0 +1,358 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 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.antcore.execution;
import java.io.File;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.ant.antcore.antlib.AntLibDefinition;
import org.apache.ant.antcore.antlib.AntLibManager;
import org.apache.ant.antcore.antlib.AntLibrary;
import org.apache.ant.antcore.modelparser.XMLProjectParser;
import org.apache.ant.antcore.xml.XMLParseException;
import org.apache.ant.common.antlib.AntLibFactory;
import org.apache.ant.common.antlib.Converter;
import org.apache.ant.common.antlib.StandardLibFactory;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.service.ComponentService;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.init.InitUtils;

/**
* The instance of the ComponentServices made available by the core to the
* ant libraries.
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 27 January 2002
*/
public class ComponentManager implements ComponentService {
/** The prefix for library ids that are automatically imported */
public final static String ANT_LIB_PREFIX = "ant.";

/**
* Type converters for this executionFrame. Converters are used when
* configuring Tasks to handle special type conversions.
*/
private Map converters = new HashMap();

/** The factory objects for each library, indexed by the library Id */
private Map libFactories = new HashMap();

/** The ExecutionFrame this service instance is working for */
private ExecutionFrame frame;

/** The library manager instance used to configure libraries. */
private AntLibManager libManager;

/**
* These are AntLibraries which have been loaded into this component
* manager
*/
private Map antLibraries;
/** The definitions which have been imported into this frame. */
private Map definitions = new HashMap();

/**
* Constructor
*
* @param executionFrame the frame containing this context
* @param allowRemoteLibs true if remote libraries can be loaded though
* this service.
*/
protected ComponentManager(ExecutionFrame executionFrame,
boolean allowRemoteLibs) {
this.frame = executionFrame;
libManager = new AntLibManager(allowRemoteLibs);
}

/**
* Load a library or set of libraries from a location making them
* available for use
*
* @param libLocation the file or URL of the library location
* @param importAll if true all tasks are imported as the library is
* loaded
* @exception ExecutionException if the library cannot be loaded
*/
public void loadLib(String libLocation, boolean importAll)
throws ExecutionException {
try {
Map librarySpecs = new HashMap();
libManager.loadLib(librarySpecs, libLocation);
libManager.configLibraries(frame.getInitConfig(), librarySpecs,
antLibraries);

if (importAll) {
Iterator i = librarySpecs.keySet().iterator();
while (i.hasNext()) {
String libraryId = (String)i.next();
importLibrary(libraryId);
}
}
} catch (MalformedURLException e) {
throw new ExecutionException("Unable to load libraries from "
+ libLocation, e);
}
}

/**
* Run a sub-build.
*
* @param antFile the file containing the XML description of the model
* @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
* @exception ExecutionException if the subbuild cannot be run
*/
public void runBuild(File antFile, Map properties, List targets)
throws ExecutionException {
try {
// Parse the build file into a project
XMLProjectParser parser = new XMLProjectParser();
Project project
= parser.parseBuildFile(InitUtils.getFileURL(antFile));
runBuild(project, properties, targets);
} catch (MalformedURLException e) {
throw new ExecutionException(e);
} catch (XMLParseException e) {
throw new ExecutionException(e);
}
}

/**
* Run a sub-build.
*
* @param model the project model to be used for the build
* @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
* @exception ExecutionException if the subbuild cannot be run
*/
public void runBuild(Project model, Map properties, List targets)
throws ExecutionException {
ExecutionFrame newFrame = frame.createFrame(model);
newFrame.setInitialProperties(properties);
newFrame.runBuild(targets);
}

/**
* Run a sub-build using the current frame's project model
*
* @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
* @exception ExecutionException if the subbuild cannot be run
*/
public void callTarget(Map properties, List targets)
throws ExecutionException {
runBuild(frame.getProject(), properties, targets);
}

/**
* Set the standard libraries (i.e. those which are independent of the
* build files) to be used in this component manager
*
* @param standardLibs A collection of AntLibrary objects indexed by
* their libraryId
* @exception ExecutionException if the components cannot be imported
* form the libraries fro which such importing is automatic.
*/
protected void setStandardLibraries(Map standardLibs)
throws ExecutionException {
antLibraries = new HashMap(standardLibs);

// go through the libraries and import all standard ant libraries
for (Iterator i = antLibraries.keySet().iterator(); i.hasNext(); ) {
String libraryId = (String)i.next();
if (libraryId.startsWith(ANT_LIB_PREFIX)) {
// standard library - import whole library
importLibrary(libraryId);
}
}
}

/**
* Get the collection ov converters currently configured
*
* @return A map of converter instances indexed on the class they can
* convert
*/
protected Map getConverters() {
return converters;
}

/**
* Get the collection of Ant Libraries defined for this frame
*
* @return a map of Ant Libraries indexed by thier library Id
*/
protected Map getAntLibraries() {
return antLibraries;
}

/**
* Gets the factory object for the given library
*
* @param antLibrary the library for which the factory is required
* @return the library's factory object
* @exception ExecutionException if the factory cannot be initialised
*/
protected AntLibFactory getLibFactory(AntLibrary antLibrary)
throws ExecutionException {
String libraryId = antLibrary.getLibraryId();
if (libFactories.containsKey(libraryId)) {
return (AntLibFactory)libFactories.get(libraryId);
}
AntLibFactory libFactory = antLibrary.getFactory();
if (libFactory == null) {
libFactory = new StandardLibFactory();
}
libFactories.put(libraryId, libFactory);
libFactory.init(new ExecutionContext(frame));
return libFactory;
}

/**
* Get an imported definition from the component manager
*
* @param name the name under which the component has been imported
* @return the ImportInfo object detailing the import's library and
* other details
*/
protected ImportInfo getDefinition(String name) {
return (ImportInfo)definitions.get(name);
}

/**
* Import a complete library into this frame
*
* @param libraryId The id of the library to be imported
* @exception ExecutionException if the library cannot be imported
*/
protected void importLibrary(String libraryId) throws ExecutionException {
AntLibrary library = (AntLibrary)antLibraries.get(libraryId);
if (library == null) {
throw new ExecutionException("Unable to import library " + libraryId
+ " as it has not been loaded");
}
Map libDefs = library.getDefinitions();
for (Iterator i = libDefs.keySet().iterator(); i.hasNext(); ) {
String defName = (String)i.next();
AntLibDefinition libdef
= (AntLibDefinition)libDefs.get(defName);
definitions.put(defName, new ImportInfo(library, libdef));
}
addLibraryConverters(library);
}

/**
* Add the converters from the given library to those managed by this
* frame.
*
* @param library the library from which the converters are required
* @exception ExecutionException if a converter defined in the library
* cannot be instantiated
*/
private void addLibraryConverters(AntLibrary library)
throws ExecutionException {
if (!library.hasConverters()) {
return;
}

String className = null;
try {
AntLibFactory libFactory = getLibFactory(library);
ClassLoader converterLoader = library.getClassLoader();
for (Iterator i = library.getConverterClassNames(); i.hasNext(); ) {
className = (String)i.next();
Class converterClass
= Class.forName(className, true, converterLoader);
if (!Converter.class.isAssignableFrom(converterClass)) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId() + "\" the converter class "
+ converterClass.getName()
+ " does not implement the Converter interface");
}
Converter converter
= libFactory.createConverter(converterClass);
ExecutionContext context
= new ExecutionContext(frame);
converter.init(context);
Class[] converterTypes = converter.getTypes();
for (int j = 0; j < converterTypes.length; ++j) {
converters.put(converterTypes[j], converter);
}
}
} catch (ClassNotFoundException e) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId() + "\" converter class "
+ className + " was not found", e);
} catch (NoClassDefFoundError e) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId()
+ "\" could not load a dependent class ("
+ e.getMessage() + ") for converter " + className);
} catch (InstantiationException e) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId()
+ "\" unable to instantiate converter class "
+ className, e);
} catch (IllegalAccessException e) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId()
+ "\" unable to access converter class "
+ className, e);
}
}
}


+ 11
- 13
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java View File

@@ -53,11 +53,10 @@
*/
package org.apache.ant.antcore.execution;
import java.io.File;
import org.apache.ant.antcore.model.ModelElement;
import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.model.ModelElement;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.FileUtils;
import org.apache.ant.common.util.Location;

/**
* This is the core's implementation of the AntContext for all core objects.
@@ -83,13 +82,10 @@ public class ExecutionContext implements AntContext {
* Initilaise this context's environment
*
* @param frame the frame containing this context
* @param eventSupport the event support instance used to send build
* events
*/
public ExecutionContext(ExecutionFrame frame,
BuildEventSupport eventSupport) {
public ExecutionContext(ExecutionFrame frame) {
this.frame = frame;
this.eventSupport = eventSupport;
this.eventSupport = frame.getEventSupport();
}

/**
@@ -116,15 +112,17 @@ public class ExecutionContext implements AntContext {
}

/**
* Get the build fiel location with which this context is associated
* Get the model element associated with this context. If the context is
* not associated with any particular model element, the project model
* is returned.
*
* @return the associated location object.
* @return the model element.
*/
public Location getLocation() {
if (modelElement != null) {
return modelElement.getLocation();
public ModelElement getModelElement() {
if (modelElement == null) {
return frame.getProject();
}
return Location.UNKNOWN_LOCATION;
return modelElement;
}

/**


+ 14
- 13
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionDataService.java View File

@@ -131,6 +131,18 @@ public class ExecutionDataService implements DataService {
return frame.isDataValueSet(name);
}

/**
* Get all the properties from the frame and any references frames. This
* is an expensive operation since it must clone all of the property
* stores in all frames
*
* @return a Map containing the frames properties indexed by their full
* name.
*/
public Map getAllProperties() {
return frame.getAllProperties();
}

/**
* Replace ${} style constructions in the given value with the string
* value of the corresponding data values in the frame
@@ -157,8 +169,8 @@ public class ExecutionDataService implements DataService {
if (fragment == null) {
String propertyName = (String)j.next();
if (!isDataValueSet(propertyName)) {
throw new ExecutionException("Property " + propertyName
+ " has not been set");
throw new ExecutionException("Property \"" + propertyName
+ "\" has not been set");
}
fragment = getDataValue(propertyName).toString();
}
@@ -207,16 +219,5 @@ public class ExecutionDataService implements DataService {

return sb.toString();
}

/**
* Get all the properties from the frame and any references frames. This
* is an expensive operation since it must clone all of the property
* stores in all frames
*
* @return a Map containing the frames properties indexed by their full name.
*/
public Map getAllProperties() {
return frame.getAllProperties();
}
}


+ 182
- 308
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionFrame.java View File

@@ -59,25 +59,23 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.ant.antcore.antlib.AntLibDefinition;
import org.apache.ant.antcore.antlib.AntLibrary;
import org.apache.ant.antcore.config.AntConfig;
import org.apache.ant.antcore.model.BuildElement;
import org.apache.ant.antcore.model.Project;
import org.apache.ant.antcore.model.Target;
import org.apache.ant.antcore.util.ConfigException;
import org.apache.ant.common.antlib.AntLibFactory;
import org.apache.ant.common.antlib.Converter;
import org.apache.ant.common.antlib.ExecutionComponent;
import org.apache.ant.common.antlib.StandardLibFactory;
import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.antlib.TaskContainer;
import org.apache.ant.common.event.BuildListener;
import org.apache.ant.common.model.BuildElement;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.model.Target;
import org.apache.ant.common.service.ComponentService;
import org.apache.ant.common.service.DataService;
import org.apache.ant.common.service.FileService;
import org.apache.ant.common.util.AntException;
import org.apache.ant.common.util.ConfigException;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.FileUtils;
import org.apache.ant.common.util.Location;
import org.apache.ant.common.util.MessageLevel;
import org.apache.ant.init.InitConfig;
@@ -91,74 +89,18 @@ import org.apache.ant.init.InitConfig;
* @created 14 January 2002
*/
public class ExecutionFrame {

/**
* This class is used to maintain information about imports
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 16 January 2002
*/
private static class ImportInfo {
/** the ant library from which the import is made */
private AntLibrary library;
/** the library definition information */
private AntLibDefinition libDefinition;

/**
* ImportInfo records what has been imported from an Ant Library
*
* @param library The library from which the import was made
* @param libDefinition the library definition information
*/
public ImportInfo(AntLibrary library, AntLibDefinition libDefinition) {
this.library = library;
this.libDefinition = libDefinition;
}

/**
* Get the classname that has been imported
*
* @return the classname that was imported.
*/
public String getClassName() {
return libDefinition.getClassName();
}

/**
* Get the library from which the import was made
*
* @return the library from which the import was made
*/
public AntLibrary getAntLibrary() {
return library;
}

/**
* Get the type of the definition that was imported
*
* @return the type of definition
*/
public int getDefinitionType() {
return libDefinition.getDefinitionType();
}

}
/** A magic property which sets the execution base directory */
public final static String BASEDIR_PROP = "basedir";

/** The Ant aspect used to identify Ant metadata */
public final static String ANT_ASPECT = "ant";

/** The prefix for library ids that are automatically imported */
public final static String ANT_LIB_PREFIX = "ant.";

/** the base dir of the project */
private File baseDir;

/** The Project that this execution frame is processing */
private Project project = null;

/** The factory objects for each library, indexed by the library Id */
private Map libFactories = new HashMap();

/** The referenced frames corresponding to the referenced projects */
private Map referencedFrames = new HashMap();

@@ -183,24 +125,9 @@ public class ExecutionFrame {
*/
private Map standardLibs;

/**
* These are AntLibraries which have been loaded in this
* ExecutionFrame's build file.
*/
private Map antLibraries;

/** The definitions which have been imported into this frame. */
private Map definitions = new HashMap();

/** BuildEvent support used to fire events and manage listeners */
private BuildEventSupport eventSupport = new BuildEventSupport();

/**
* Type converters for this executionFrame. Converters are used when
* configuring Tasks to handle special type conversions.
*/
private Map converters = new HashMap();

/**
* The services map is a map of service interface classes to instances
* which provide the service.
@@ -218,6 +145,15 @@ public class ExecutionFrame {
*/
private DataService dataService;

/** The execution file service instance */
private FileService fileService;

/**
* the Component Manager used to manage the importing of library
* components from the Ant libraries
*/
private ComponentManager componentManager;

/**
* Create an Execution Frame for the given project
*
@@ -225,32 +161,17 @@ public class ExecutionFrame {
* this frame
* @param config the user config to use for this execution of Ant
* @param initConfig Ant's initialisation config
* @exception ConfigException if a component of the library cannot be
* @exception ExecutionException if a component of the library cannot be
* imported
*/
protected ExecutionFrame(Map standardLibs, InitConfig initConfig,
AntConfig config) throws ConfigException {
AntConfig config) throws ExecutionException {
this.standardLibs = standardLibs;
this.config = config;
this.initConfig = initConfig;

configureServices();

antLibraries = new HashMap(standardLibs);

try {
// go through the libraries and import all standard ant libraries
for (Iterator i = antLibraries.keySet().iterator(); i.hasNext(); ) {
String libraryId = (String)i.next();
if (libraryId.startsWith(ANT_LIB_PREFIX)) {
// standard library - import whole library
importLibrary(libraryId);
}
}
} catch (ExecutionException e) {
throw new ConfigException(e);
}

componentManager.setStandardLibraries(standardLibs);
}

/**
@@ -267,88 +188,24 @@ public class ExecutionFrame {
return currentLoader;
}

/**
* Gets the project model this frame is working with
*
* @return the project model
*/
public Project getProject() {
return project;
}


/**
* Get all the properties from the frame and any references frames. This
* is an expensive operation since it must clone all of the property
* stores in all frames
*
* @return a Map containing the frames properties indexed by their full name.
*/
public Map getAllProperties() {
Map allProperties = new HashMap(dataValues);
Iterator i = referencedFrames.keySet().iterator();
while (i.hasNext()) {
String refName = (String)i.next();
ExecutionFrame refFrame = getReferencedFrame(refName);
Map refProperties = refFrame.getAllProperties();
Iterator j = refProperties.keySet().iterator();
while (j.hasNext()) {
String name = (String)j.next();
Object value = refProperties.get(name);
allProperties.put(refName + Project.REF_DELIMITER + name,
value);
}
}
return allProperties;
}

/**
* Log a message as a build event
*
* @param message the message to be logged
* @param level the priority level of the message
*/
public void log(String message, int level) {
eventSupport.fireMessageLogged(project, message, level);
}

/**
* Sets the Project of the ExecutionFrame
*
* @param project The new Project value
* @exception ConfigException if any required sub-frames cannot be
* @exception ExecutionException if any required sub-frames cannot be
* created and configured
*/
protected void setProject(Project project) throws ConfigException {
protected void setProject(Project project) throws ExecutionException {
this.project = project;
URL projectURL = project.getSourceURL();
if (projectURL.getProtocol().equals("file")) {
File projectFile = new File(projectURL.getFile());
String base = project.getBase();
if (base == null) {
base = ".";
}
baseDir = new File(projectFile.getParentFile(), base);
} else {
baseDir = new File(".");
}

referencedFrames = new HashMap();

for (Iterator i = project.getReferencedProjectNames(); i.hasNext(); ) {
String referenceName = (String)i.next();
Project referencedProject
= project.getReferencedProject(referenceName);
ExecutionFrame referencedFrame
= new ExecutionFrame(standardLibs, initConfig, config);
referencedFrame.setProject(referencedProject);
ExecutionFrame referencedFrame = createFrame(referencedProject);
referencedFrames.put(referenceName, referencedFrame);

for (Iterator j = eventSupport.getListeners(); j.hasNext(); ) {
BuildListener listener = (BuildListener)j.next();
referencedFrame.addBuildListener(listener);
}
}
}

@@ -376,12 +233,59 @@ public class ExecutionFrame {
}

/**
* Get the collection of Ant Libraries defined for this frame
* Set the initial properties to be used when the frame starts execution
*
* @param properties a Map of named properties which may in fact be any
* object
* @exception ExecutionException if the properties cannot be set
*/
protected void setInitialProperties(Map properties)
throws ExecutionException {
if (properties == null) {
return;
}
for (Iterator i = properties.keySet().iterator(); i.hasNext(); ) {
String name = (String)i.next();
Object value = properties.get(name);
setDataValue(name, value, false);
}
}

/**
* Gets the project model this frame is working with
*
* @return the project model
*/
protected Project getProject() {
return project;
}


/**
* Get all the properties from the frame and any references frames. This
* is an expensive operation since it must clone all of the property
* stores in all frames
*
* @return a map of Ant Libraries indexed by thier library Id
* @return a Map containing the frames properties indexed by their full
* name.
*/
protected Map getAntLibraries() {
return antLibraries;
protected Map getAllProperties() {
Map allProperties = new HashMap(dataValues);
Iterator i = referencedFrames.keySet().iterator();
while (i.hasNext()) {
String refName = (String)i.next();
ExecutionFrame refFrame = getReferencedFrame(refName);
Map refProperties = refFrame.getAllProperties();
Iterator j = refProperties.keySet().iterator();
while (j.hasNext()) {
String name = (String)j.next();
Object value = refProperties.get(name);
allProperties.put(refName + Project.REF_DELIMITER + name,
value);
}
}

return allProperties;
}

/**
@@ -422,6 +326,16 @@ public class ExecutionFrame {
return service;
}

/**
* Get the EventSupport instance for this frame. This tracks the build
* listeners on this frame
*
* @return the EventSupport instance
*/
protected BuildEventSupport getEventSupport() {
return eventSupport;
}

/**
* Gets the baseDir of the ExecutionFrame
*
@@ -500,6 +414,35 @@ public class ExecutionFrame {
}
}

/**
* Create a new frame for a given project
*
* @param project the project model the frame will deal with
* @return an ExecutionFrame ready to build the project
* @exception ExecutionException if the frame cannot be created.
*/
protected ExecutionFrame createFrame(Project project)
throws ExecutionException {
ExecutionFrame newFrame
= new ExecutionFrame(standardLibs, initConfig, config);
newFrame.setProject(project);
for (Iterator j = eventSupport.getListeners(); j.hasNext(); ) {
BuildListener listener = (BuildListener)j.next();
newFrame.addBuildListener(listener);
}
return newFrame;
}

/**
* Log a message as a build event
*
* @param message the message to be logged
* @param level the priority level of the message
*/
protected void log(String message, int level) {
eventSupport.fireMessageLogged(project, message, level);
}

/**
* Add a build listener to this execution frame
*
@@ -533,9 +476,9 @@ public class ExecutionFrame {
* @exception ExecutionException if there is a problem in the build
*/
protected void runBuild(List targets) throws ExecutionException {
System.out.println("Initilizing frame");
determineBaseDirs();

initialize();
log("Initialized", MessageLevel.MSG_DEBUG);
if (targets.isEmpty()) {
// we just execute the default target if any
String defaultTarget = project.getDefaultTarget();
@@ -565,8 +508,8 @@ public class ExecutionFrame {
// to execute a target we must determine its dependencies and
// execute them in order.

// firstly build a list of fully qualified target names to execute.
try {
// firstly build a list of fully qualified target names to execute.
List dependencyOrder = project.getTargetDependencies(targetName);
for (Iterator i = dependencyOrder.iterator(); i.hasNext(); ) {
String fullTargetName = (String)i.next();
@@ -577,6 +520,7 @@ public class ExecutionFrame {
} catch (ConfigException e) {
throw new ExecutionException(e);
}

}

/**
@@ -593,7 +537,7 @@ public class ExecutionFrame {
BuildElement model = (BuildElement)taskIterator.next();
// what sort of element is this.
ImportInfo importInfo
= (ImportInfo)definitions.get(model.getType());
= componentManager.getDefinition(model.getType());
if (importInfo == null) {
throw new ExecutionException("There is no definition for the <"
+ model.getType() + "> element", model.getLocation());
@@ -620,10 +564,7 @@ public class ExecutionFrame {
} catch (AntException te) {
ExecutionException e
= new ExecutionException(te, te.getLocation());
if (e.getLocation() == null
|| e.getLocation() == Location.UNKNOWN_LOCATION) {
e.setLocation(model.getLocation());
}
e.setLocation(model.getLocation(), false);
failureCause = e;
throw e;
} catch (RuntimeException e) {
@@ -653,12 +594,7 @@ public class ExecutionFrame {
eventSupport.fireTargetStarted(target);
executeTasks(taskIterator);
} catch (ExecutionException e) {
System.out.println("Exception location is " + e.getLocation());
if (e.getLocation() == null
|| e.getLocation() == Location.UNKNOWN_LOCATION) {
e.setLocation(target.getLocation());
}
System.out.println("Exception location is now " + e.getLocation());
e.setLocation(target.getLocation(), false);
failureCause = e;
throw e;
} catch (RuntimeException e) {
@@ -686,28 +622,6 @@ public class ExecutionFrame {
}


/**
* Import a complete library into this frame
*
* @param libraryId The id of the library to be imported
* @exception ExecutionException if the library cannot be imported
*/
protected void importLibrary(String libraryId) throws ExecutionException {
AntLibrary library = (AntLibrary)antLibraries.get(libraryId);
if (library == null) {
throw new ExecutionException("Unable to import library " + libraryId
+ " as it has not been loaded");
}
Map libDefs = library.getDefinitions();
for (Iterator i = libDefs.keySet().iterator(); i.hasNext(); ) {
String defName = (String)i.next();
AntLibDefinition libdef
= (AntLibDefinition)libDefs.get(defName);
definitions.put(defName, new ImportInfo(library, libdef));
}
addLibraryConverters(library);
}

/**
* Gets the reflector for the given class
*
@@ -718,7 +632,8 @@ public class ExecutionFrame {
if (reflectors.containsKey(c)) {
return (Reflector)reflectors.get(c);
}
ClassIntrospector introspector = new ClassIntrospector(c, converters);
ClassIntrospector introspector
= new ClassIntrospector(c, componentManager.getConverters());
Reflector reflector = introspector.getReflector();
reflectors.put(c, reflector);
return reflector;
@@ -755,27 +670,36 @@ public class ExecutionFrame {
}

/**
* Gets the factory object for the given library
* Determine the base directory for each frame in the frame hierarchy
*
* @param antLibrary the library for which the factory instance is
* required.
* @return the library;s factory object
* @exception ExecutionException the factory object for the library
* cannot be created.
* @exception ExecutionException if the base directories cannot be
* determined
*/
private AntLibFactory getLibFactory(AntLibrary antLibrary)
throws ExecutionException {
String libraryId = antLibrary.getLibraryId();
if (libFactories.containsKey(libraryId)) {
return (AntLibFactory)libFactories.get(libraryId);
private void determineBaseDirs() throws ExecutionException {
if (isDataValueSet(BASEDIR_PROP)) {
baseDir = new File(getDataValue(BASEDIR_PROP).toString());
} else {
URL projectURL = project.getSourceURL();
if (projectURL.getProtocol().equals("file")) {
File projectFile = new File(projectURL.getFile());
File projectFileParent = projectFile.getParentFile();
String base = project.getBase();
if (base == null) {
baseDir = projectFileParent;
} else {
FileUtils fileUtils = new FileUtils();
baseDir = fileUtils.resolveFile(projectFileParent, base);
}
} else {
baseDir = new File(".");
}
setDataValue(BASEDIR_PROP, baseDir.getPath(), true);
}
AntLibFactory libFactory = antLibrary.getFactory();
if (libFactory == null) {
libFactory = new StandardLibFactory();

for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
ExecutionFrame refFrame = (ExecutionFrame)i.next();
refFrame.determineBaseDirs();
}
libFactories.put(libraryId, libFactory);
libFactory.init(new ExecutionContext(this, eventSupport));
return libFactory;
}

/**
@@ -784,71 +708,14 @@ public class ExecutionFrame {
*/
private void configureServices() {
// create services and make them available in our services map
services.put(FileService.class, new ExecutionFileService(this));
services.put(ComponentService.class,
new ExecutionComponentService(this, config.isRemoteLibAllowed()));
fileService = new ExecutionFileService(this);
componentManager
= new ComponentManager(this, config.isRemoteLibAllowed());
dataService = new ExecutionDataService(this);
services.put(DataService.class, dataService);
}

/**
* Add the converters from the given library to those managed by this
* frame.
*
* @param library the library from which the converters are required
* @exception ExecutionException if a converter defined in the library
* cannot be instantiated
*/
private void addLibraryConverters(AntLibrary library)
throws ExecutionException {
if (!library.hasConverters()) {
return;
}

String className = null;
try {
AntLibFactory libFactory = getLibFactory(library);
ClassLoader converterLoader = library.getClassLoader();
for (Iterator i = library.getConverterClassNames(); i.hasNext(); ) {
className = (String)i.next();
Class converterClass
= Class.forName(className, true, converterLoader);
if (!Converter.class.isAssignableFrom(converterClass)) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId() + "\" the converter class "
+ converterClass.getName()
+ " does not implement the Converter interface");
}
Converter converter
= libFactory.createConverter(converterClass);
ExecutionContext context
= new ExecutionContext(this, eventSupport);
converter.init(context);
Class[] converterTypes = converter.getTypes();
for (int j = 0; j < converterTypes.length; ++j) {
converters.put(converterTypes[j], converter);
}
}
} catch (ClassNotFoundException e) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId() + "\" converter class "
+ className + " was not found", e);
} catch (NoClassDefFoundError e) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId()
+ "\" could not load a dependent class ("
+ e.getMessage() + ") for converter " + className);
} catch (InstantiationException e) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId()
+ "\" unable to instantiate converter class "
+ className, e);
} catch (IllegalAccessException e) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId()
+ "\" unable to access converter class "
+ className, e);
}
services.put(FileService.class, fileService);
services.put(ComponentService.class, componentManager);
services.put(DataService.class, dataService);
}

/**
@@ -890,7 +757,7 @@ public class ExecutionFrame {
BuildElement nestedElementModel = (BuildElement)i.next();
String nestedElementName = nestedElementModel.getType();

ImportInfo info = (ImportInfo)definitions.get(nestedElementName);
ImportInfo info = componentManager.getDefinition(nestedElementName);
if (element instanceof TaskContainer
&& info != null
&& info.getDefinitionType() == AntLibrary.TASKDEF
@@ -937,18 +804,21 @@ public class ExecutionFrame {
String nestedElementName = model.getType();
Object nestedElement
= reflector.createElement(element, nestedElementName);
if (nestedElement instanceof ExecutionComponent) {
ExecutionComponent component = (ExecutionComponent)nestedElement;
ExecutionContext context
= new ExecutionContext(this, eventSupport);
context.setModelElement(model);
component.init(context);
}

try {
configureElement(nestedElement, model);
if (nestedElement instanceof ExecutionComponent) {
ExecutionComponent component
= (ExecutionComponent)nestedElement;
ExecutionContext context
= new ExecutionContext(this);
context.setModelElement(model);
component.init(context);
configureElement(nestedElement, model);
component.validateComponent();
} else {
configureElement(nestedElement, model);
}
} catch (ExecutionException e) {
e.setLocation(model.getLocation());
e.setLocation(model.getLocation(), false);
throw e;
}
}
@@ -1045,7 +915,7 @@ public class ExecutionFrame {
throws ExecutionException {

String taskType = model.getType();
ImportInfo taskDefInfo = (ImportInfo)definitions.get(taskType);
ImportInfo taskDefInfo = componentManager.getDefinition(taskType);
if (taskDefInfo == null
|| taskDefInfo.getDefinitionType() != AntLibrary.TASKDEF) {
throw new ExecutionException("There is no defintion for a "
@@ -1059,7 +929,8 @@ public class ExecutionFrame {
ClassLoader taskClassLoader = antLibrary.getClassLoader();
Class elementClass
= Class.forName(className, true, taskClassLoader);
AntLibFactory libFactory = getLibFactory(antLibrary);
AntLibFactory libFactory
= componentManager.getLibFactory(antLibrary);
Object element = libFactory.createTaskInstance(elementClass);

Task task = null;
@@ -1072,9 +943,10 @@ public class ExecutionFrame {

// set the context loader while configuring the element
ClassLoader currentLoader = setContextLoader(taskClassLoader);
TaskContext taskContext = new TaskContext(this, eventSupport);
TaskContext taskContext = new TaskContext(this);
taskContext.init(taskClassLoader, task, model);
configureElement(element, model);
task.validateComponent();
setContextLoader(currentLoader);
return taskContext;
} catch (ClassNotFoundException e) {
@@ -1094,7 +966,7 @@ public class ExecutionFrame {
+ className + " for task <" + taskType + ">",
e, model.getLocation());
} catch (ExecutionException e) {
e.setLocation(model.getLocation());
e.setLocation(model.getLocation(), false);
throw e;
}
}
@@ -1112,7 +984,7 @@ public class ExecutionFrame {
*/
private Object configureType(String typeName, BuildElement model)
throws ExecutionException {
ImportInfo typeDefInfo = (ImportInfo)definitions.get(typeName);
ImportInfo typeDefInfo = componentManager.getDefinition(typeName);
if (typeDefInfo == null
|| typeDefInfo.getDefinitionType() != AntLibrary.TYPEDEF) {
throw new ExecutionException("There is no defintion for a "
@@ -1128,7 +1000,8 @@ public class ExecutionFrame {
= Class.forName(className, true, typeClassLoader);

ClassLoader currentLoader = setContextLoader(typeClassLoader);
AntLibFactory libFactory = getLibFactory(antLibrary);
AntLibFactory libFactory
= componentManager.getLibFactory(antLibrary);
Object typeInstance
= createTypeInstance(typeClass, libFactory, model);
setContextLoader(currentLoader);
@@ -1169,12 +1042,14 @@ public class ExecutionFrame {
if (typeInstance instanceof ExecutionComponent) {
ExecutionComponent component = (ExecutionComponent)typeInstance;
ExecutionContext context
= new ExecutionContext(this, eventSupport);
= new ExecutionContext(this);
context.setModelElement(model);
component.init(context);
configureElement(typeInstance, model);
component.validateComponent();
} else {
configureElement(typeInstance, model);
}

configureElement(typeInstance, model);
return typeInstance;
} catch (InstantiationException e) {
throw new ExecutionException("Unable to instantiate type class "
@@ -1185,10 +1060,9 @@ public class ExecutionFrame {
+ typeClass.getName() + " for type <" + model.getType() + ">",
e, model.getLocation());
} catch (ExecutionException e) {
e.setLocation(model.getLocation());
e.setLocation(model.getLocation(), false);
throw e;
}
}

}


+ 14
- 10
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java View File

@@ -61,10 +61,10 @@ import java.util.Map;
import org.apache.ant.antcore.antlib.AntLibManager;
import org.apache.ant.antcore.antlib.AntLibrary;
import org.apache.ant.antcore.config.AntConfig;
import org.apache.ant.antcore.model.Project;
import org.apache.ant.antcore.util.ConfigException;
import org.apache.ant.common.event.BuildListener;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.util.AntException;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.init.InitConfig;

/**
@@ -105,11 +105,11 @@ public class ExecutionManager {
*
* @param initConfig Ant's configuration - classloaders etc
* @param config The user config to use - may be null
* @exception ConfigException if there is a problem with one of Ant's
* @exception ExecutionException if there is a problem with one of Ant's
* tasks
*/
public ExecutionManager(InitConfig initConfig, AntConfig config)
throws ConfigException {
throws ExecutionException {
this.config = config;
this.initConfig = initConfig;

@@ -140,7 +140,7 @@ public class ExecutionManager {

mainFrame = new ExecutionFrame(antLibraries, initConfig, config);
} catch (MalformedURLException e) {
throw new ConfigException("Unable to load Ant libraries", e);
throw new ExecutionException("Unable to load Ant libraries", e);
}
}

@@ -149,13 +149,17 @@ public class ExecutionManager {
*
* @param project the project model to be used for the build
* @param targets a list of target names to be executed.
* @param commandProperties the properties defined by the front end to
* control the build
*/
public void runBuild(Project project, List targets) {
public void runBuild(Project project, List targets, Map commandProperties) {
Throwable buildFailureCause = null;
try {
// start by validating the project we have been given.
project.validate(null);
project.validate();

mainFrame.setProject(project);
mainFrame.setInitialProperties(commandProperties);

eventSupport.fireBuildStarted(project);
mainFrame.runBuild(targets);
@@ -193,10 +197,10 @@ public class ExecutionManager {
* Add the library paths from the AntConfig instance to the Ant
* Libraries.
*
* @exception ConfigException if remote libraries are not allowed.
* @exception ExecutionException if remote libraries are not allowed.
*/
private void addConfigLibPaths()
throws ConfigException {
throws ExecutionException {
if (config == null) {
return;
}
@@ -212,7 +216,7 @@ public class ExecutionManager {
URL pathElementURL = (URL)j.next();
if (!pathElementURL.getProtocol().equals("file")
&& !config.isRemoteLibAllowed()) {
throw new ConfigException("Remote libpaths are not"
throw new ExecutionException("Remote libpaths are not"
+ " allowed: " + pathElementURL);
}
antLib.addLibraryURL(pathElementURL);


+ 110
- 0
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ImportInfo.java View File

@@ -0,0 +1,110 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 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.antcore.execution;

import org.apache.ant.antcore.antlib.AntLibDefinition;
import org.apache.ant.antcore.antlib.AntLibrary;

/**
* This class is used to maintain information about imports
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 16 January 2002
*/
public class ImportInfo {
/** the ant library from which the import is made */
private AntLibrary library;
/** the library definition information */
private AntLibDefinition libDefinition;

/**
* ImportInfo records what has been imported from an Ant Library
*
* @param library The library from which the import was made
* @param libDefinition the library definition information
*/
public ImportInfo(AntLibrary library, AntLibDefinition libDefinition) {
this.library = library;
this.libDefinition = libDefinition;
}

/**
* Get the classname that has been imported
*
* @return the classname that was imported.
*/
public String getClassName() {
return libDefinition.getClassName();
}

/**
* Get the library from which the import was made
*
* @return the library from which the import was made
*/
public AntLibrary getAntLibrary() {
return library;
}

/**
* Get the type of the definition that was imported
*
* @return the type of definition
*/
public int getDefinitionType() {
return libDefinition.getDefinitionType();
}

}


+ 6
- 8
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java View File

@@ -52,8 +52,8 @@
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.execution;
import org.apache.ant.antcore.model.ModelElement;
import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.model.ModelElement;
import org.apache.ant.common.util.ExecutionException;
/**
* This is the core's implementation of the AntContext for Tasks.
@@ -77,12 +77,9 @@ public class TaskContext extends ExecutionContext {
* Initilaise this context's environment
*
* @param frame the frame containing this context
* @param eventSupport the event support instance used to send build
* events
*/
public TaskContext(ExecutionFrame frame,
BuildEventSupport eventSupport) {
super(frame, eventSupport);
public TaskContext(ExecutionFrame frame) {
super(frame);
}

/**
@@ -109,7 +106,7 @@ public class TaskContext extends ExecutionContext {
* @param task the task to be manager
* @param loader the classloader
* @param modelElement the model element associated with this context
* @exception ExecutionException if the task cannot be initialized
* @exception ExecutionException if the task cannot be initialized
*/
public void init(ClassLoader loader, Task task, ModelElement modelElement)
throws ExecutionException {
@@ -122,7 +119,8 @@ public class TaskContext extends ExecutionContext {
/**
* execute this context's task
*
* @exception ExecutionException if there is a problem executing the task
* @exception ExecutionException if there is a problem executing the
* task
*/
public void execute() throws ExecutionException {
task.execute();


proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/BuildElementHandler.java → proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/BuildElementHandler.java View File

@@ -51,10 +51,10 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.model.xmlparser;
package org.apache.ant.antcore.modelparser;
import java.util.Iterator;

import org.apache.ant.antcore.model.BuildElement;
import org.apache.ant.common.model.BuildElement;
import org.apache.ant.antcore.xml.ElementHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXParseException;

proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/IncludeHandler.java → proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/IncludeHandler.java View File

@@ -51,11 +51,11 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.model.xmlparser;
package org.apache.ant.antcore.modelparser;

import java.net.MalformedURLException;
import java.net.URL;
import org.apache.ant.antcore.model.Project;
import org.apache.ant.common.model.Project;
import org.apache.ant.antcore.xml.ElementHandler;
import org.apache.ant.antcore.xml.XMLParseException;
import org.xml.sax.SAXParseException;

proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/NoProjectReadException.java → proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/NoProjectReadException.java View File

@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.model.xmlparser;
package org.apache.ant.antcore.modelparser;

/**
* A NoProjectReadException is used to indicate that a project was not read

proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/ProjectHandler.java → proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java View File

@@ -51,9 +51,9 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.model.xmlparser;
import org.apache.ant.antcore.model.ModelException;
import org.apache.ant.antcore.model.Project;
package org.apache.ant.antcore.modelparser;
import org.apache.ant.common.model.ModelException;
import org.apache.ant.common.model.Project;
import org.apache.ant.antcore.xml.ElementHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXParseException;

proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/RefHandler.java → proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/RefHandler.java View File

@@ -51,11 +51,11 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.model.xmlparser;
package org.apache.ant.antcore.modelparser;

import java.net.MalformedURLException;
import java.net.URL;
import org.apache.ant.antcore.model.Project;
import org.apache.ant.common.model.Project;
import org.apache.ant.antcore.xml.ElementHandler;
import org.apache.ant.antcore.xml.XMLParseException;
import org.xml.sax.SAXParseException;
@@ -129,14 +129,14 @@ public class RefHandler extends ElementHandler {
referencedProject = referencedProjectHandler.getProject();
} catch (XMLParseException e) {
throw new SAXParseException("Error parsing referenced project "
+ projectSystemId + ": " + e.getMessage(), getLocator());
+ projectSystemId + ": " + e.getMessage(), getLocator(), e);
} catch (NoProjectReadException e) {
throw new SAXParseException("No project found in the reference: "
+ projectSystemId, getLocator());
+ projectSystemId, getLocator(), e);
} catch (MalformedURLException e) {
throw new SAXParseException("Unable to reference project "
+ projectSystemId + ": " + e.getMessage(),
getLocator());
getLocator(), e);
}
}


proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/TargetHandler.java → proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/TargetHandler.java View File

@@ -51,10 +51,10 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.model.xmlparser;
package org.apache.ant.antcore.modelparser;
import java.util.StringTokenizer;

import org.apache.ant.antcore.model.Target;
import org.apache.ant.common.model.Target;
import org.apache.ant.antcore.xml.ElementHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXParseException;
@@ -75,6 +75,12 @@ public class TargetHandler extends ElementHandler {
/** The depends attribute name */
public final static String DESC_ATTR = "description";

/** The if attribute name */
public final static String IF_ATTR = "if";
/** The unless attribute name */
public final static String UNLESS_ATTR = "unless";

/** The target being configured. */
private Target target;

@@ -105,7 +111,7 @@ public class TargetHandler extends ElementHandler {
if (depends != null) {
StringTokenizer tokenizer = new StringTokenizer(depends, ",");
while (tokenizer.hasMoreTokens()) {
String dependency = tokenizer.nextToken();
String dependency = tokenizer.nextToken().trim();
target.addDependency(dependency);
}
}
@@ -143,9 +149,11 @@ public class TargetHandler extends ElementHandler {
protected void validateAttribute(String attributeName,
String attributeValue)
throws SAXParseException {
if (!attributeName.equals(NAME_ATTR) &&
!attributeName.equals(DEPENDS_ATTR) &&
!attributeName.equals(DESC_ATTR)) {
if (!attributeName.equals(NAME_ATTR)
&& !attributeName.equals(DEPENDS_ATTR)
&& !attributeName.equals(DESC_ATTR)
&& !attributeName.equals(IF_ATTR)
&& !attributeName.equals(UNLESS_ATTR)) {
throwInvalidAttribute(attributeName);
}
}

proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/XMLProjectParser.java → proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/XMLProjectParser.java View File

@@ -51,11 +51,11 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.model.xmlparser;
package org.apache.ant.antcore.modelparser;
import java.net.URL;

import org.apache.ant.common.util.Location;
import org.apache.ant.antcore.model.Project;
import org.apache.ant.common.model.Project;
import org.apache.ant.antcore.xml.ParseContext;
import org.apache.ant.antcore.xml.XMLParseException;


+ 8
- 3
proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java View File

@@ -59,8 +59,9 @@ import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.ant.common.util.Location;
import org.apache.ant.antcore.util.CircularDependencyChecker;
import org.apache.ant.antcore.util.CircularDependencyException;
import org.apache.ant.common.util.CircularDependencyChecker;
import org.apache.ant.common.util.CircularDependencyException;
import org.apache.ant.common.util.AntException;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
@@ -128,7 +129,11 @@ public class ParseContext {
Location location = new Location(e.getSystemId(),
e.getLineNumber(), e.getColumnNumber());
if (e.getException() != null) {
throw new XMLParseException(e.getException(), location);
Throwable nestedException = e.getException();
if (nestedException instanceof AntException) {
location = ((AntException)nestedException).getLocation();
}
throw new XMLParseException(nestedException, location);
} else {
throw new XMLParseException(e, location);
}


+ 138
- 9
proposal/mutant/src/java/antlibs/ant1compat/antlib.xml View File

@@ -4,20 +4,149 @@

<factory classname="org.apache.tools.ant.Ant1Factory"/>
<taskdef name="echo" classname="org.apache.tools.ant.taskdefs.Echo"/>
<taskdef name="property" classname="org.apache.tools.ant.taskdefs.Property"/>
<typedef name="patternset" classname="org.apache.tools.ant.types.PatternSet"/>
<typedef name="fileset" classname="org.apache.tools.ant.types.FileSet"/>
<typedef name="path" classname="org.apache.tools.ant.types.Path"/>
<converter classname="org.apache.tools.ant.Ant1Converter"/>

<taskdef name="ant" classname="org.apache.tools.ant.taskdefs.Ant"/>
<taskdef name="antcall" classname="org.apache.tools.ant.taskdefs.CallTarget"/>
<taskdef name="antlr" classname="org.apache.tools.ant.taskdefs.optional.ANTLR"/>
<taskdef name="antstructure" classname="org.apache.tools.ant.taskdefs.AntStructure"/>
<taskdef name="apply" classname="org.apache.tools.ant.taskdefs.Transform"/>
<taskdef name="available" classname="org.apache.tools.ant.taskdefs.Available"/>
<taskdef name="blgenclient" classname="org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient"/>
<taskdef name="bunzip2" classname="org.apache.tools.ant.taskdefs.BUnzip2"/>
<taskdef name="bzip2" classname="org.apache.tools.ant.taskdefs.BZip2"/>
<taskdef name="cab" classname="org.apache.tools.ant.taskdefs.optional.Cab"/>
<taskdef name="cccheckin" classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckin"/>
<taskdef name="cccheckout" classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckout"/>
<taskdef name="ccmcheckin" classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckin"/>
<taskdef name="ccmcheckintask" classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckinDefault"/>
<taskdef name="ccmcheckout" classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckout"/>
<taskdef name="ccmcreatetask" classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCreateTask"/>
<taskdef name="ccmreconfigure" classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMReconfigure"/>
<taskdef name="ccuncheckout" classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCUnCheckout"/>
<taskdef name="ccupdate" classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCUpdate"/>
<taskdef name="checksum" classname="org.apache.tools.ant.taskdefs.Checksum"/>
<taskdef name="chmod" classname="org.apache.tools.ant.taskdefs.Chmod"/>
<taskdef name="condition" classname="org.apache.tools.ant.taskdefs.ConditionTask"/>
<taskdef name="javac" classname="org.apache.tools.ant.taskdefs.Javac"/>
<taskdef name="mkdir" classname="org.apache.tools.ant.taskdefs.Mkdir"/>
<taskdef name="copy" classname="org.apache.tools.ant.taskdefs.Copy"/>
<taskdef name="csc" classname="org.apache.tools.ant.taskdefs.optional.dotnet.CSharp"/>
<taskdef name="cvs" classname="org.apache.tools.ant.taskdefs.Cvs"/>
<taskdef name="cvspass" classname="org.apache.tools.ant.taskdefs.CVSPass"/>
<taskdef name="ddcreator" classname="org.apache.tools.ant.taskdefs.optional.ejb.DDCreator"/>
<taskdef name="delete" classname="org.apache.tools.ant.taskdefs.Delete"/>
<taskdef name="depend" classname="org.apache.tools.ant.taskdefs.optional.depend.Depend"/>
<taskdef name="dependset" classname="org.apache.tools.ant.taskdefs.DependSet"/>
<taskdef name="ear" classname="org.apache.tools.ant.taskdefs.Ear"/>
<taskdef name="echo" classname="org.apache.tools.ant.taskdefs.Echo"/>
<taskdef name="ejbc" classname="org.apache.tools.ant.taskdefs.optional.ejb.Ejbc"/>
<taskdef name="ejbjar" classname="org.apache.tools.ant.taskdefs.optional.ejb.EjbJar"/>
<taskdef name="exec" classname="org.apache.tools.ant.taskdefs.ExecTask"/>
<taskdef name="execon" classname="org.apache.tools.ant.taskdefs.ExecuteOn"/>
<taskdef name="fail" classname="org.apache.tools.ant.taskdefs.Exit"/>
<taskdef name="filter" classname="org.apache.tools.ant.taskdefs.Filter"/>
<taskdef name="fixcrlf" classname="org.apache.tools.ant.taskdefs.FixCRLF"/>
<taskdef name="ftp" classname="org.apache.tools.ant.taskdefs.optional.net.FTP"/>
<taskdef name="genkey" classname="org.apache.tools.ant.taskdefs.GenerateKey"/>
<taskdef name="get" classname="org.apache.tools.ant.taskdefs.Get"/>
<taskdef name="gunzip" classname="org.apache.tools.ant.taskdefs.GUnzip"/>
<taskdef name="gzip" classname="org.apache.tools.ant.taskdefs.GZip"/>
<taskdef name="icontract" classname="org.apache.tools.ant.taskdefs.optional.IContract"/>
<taskdef name="ilasm" classname="org.apache.tools.ant.taskdefs.optional.dotnet.Ilasm"/>
<taskdef name="input" classname="org.apache.tools.ant.taskdefs.Input"/>
<taskdef name="iplanet-ejbc" classname="org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbcTask"/>
<taskdef name="jar" classname="org.apache.tools.ant.taskdefs.Jar"/>
<taskdef name="delete" classname="org.apache.tools.ant.taskdefs.Delete"/>
<taskdef name="java" classname="org.apache.tools.ant.taskdefs.Java"/>
<taskdef name="javac" classname="org.apache.tools.ant.taskdefs.Javac"/>
<taskdef name="javacc" classname="org.apache.tools.ant.taskdefs.optional.javacc.JavaCC"/>
<taskdef name="javadoc" classname="org.apache.tools.ant.taskdefs.Javadoc"/>
<taskdef name="javah" classname="org.apache.tools.ant.taskdefs.optional.Javah"/>
<taskdef name="jdepend" classname="org.apache.tools.ant.taskdefs.optional.jdepend.JDependTask"/>
<taskdef name="jjtree" classname="org.apache.tools.ant.taskdefs.optional.javacc.JJTree"/>
<taskdef name="jlink" classname="org.apache.tools.ant.taskdefs.optional.jlink.JlinkTask"/>
<taskdef name="jpcoverage" classname="org.apache.tools.ant.taskdefs.optional.sitraka.Coverage"/>
<taskdef name="jpcovmerge" classname="org.apache.tools.ant.taskdefs.optional.sitraka.CovMerge"/>
<taskdef name="jpcovreport" classname="org.apache.tools.ant.taskdefs.optional.sitraka.CovReport"/>
<taskdef name="jspc" classname="org.apache.tools.ant.taskdefs.optional.jsp.JspC"/>
<taskdef name="junit" classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask"/>
<taskdef name="junitreport" classname="org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator"/>
<taskdef name="loadfile" classname="org.apache.tools.ant.taskdefs.LoadFile"/>
<taskdef name="mail" classname="org.apache.tools.ant.taskdefs.SendEmail"/>
<taskdef name="manifest" classname="org.apache.tools.ant.taskdefs.Manifest"/>
<taskdef name="maudit" classname="org.apache.tools.ant.taskdefs.optional.metamata.MAudit"/>
<taskdef name="mimemail" classname="org.apache.tools.ant.taskdefs.optional.net.MimeMail"/>
<taskdef name="mkdir" classname="org.apache.tools.ant.taskdefs.Mkdir"/>
<taskdef name="mmetrics" classname="org.apache.tools.ant.taskdefs.optional.metamata.MMetrics"/>
<taskdef name="move" classname="org.apache.tools.ant.taskdefs.Move"/>
<taskdef name="mparse" classname="org.apache.tools.ant.taskdefs.optional.metamata.MParse"/>
<taskdef name="native2ascii" classname="org.apache.tools.ant.taskdefs.optional.Native2Ascii"/>
<taskdef name="netrexxc" classname="org.apache.tools.ant.taskdefs.optional.NetRexxC"/>
<taskdef name="p4add" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Add"/>
<taskdef name="p4change" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Change"/>
<taskdef name="p4counter" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Counter"/>
<taskdef name="p4edit" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Edit"/>
<taskdef name="p4have" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Have"/>
<taskdef name="p4label" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Label"/>
<taskdef name="p4submit" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Submit"/>
<taskdef name="p4sync" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Sync"/>
<taskdef name="parallel" classname="org.apache.tools.ant.taskdefs.Parallel"/>
<taskdef name="patch" classname="org.apache.tools.ant.taskdefs.Patch"/>
<taskdef name="pathconvert" classname="org.apache.tools.ant.taskdefs.PathConvert"/>
<taskdef name="property" classname="org.apache.tools.ant.taskdefs.Property"/>
<taskdef name="propertyfile" classname="org.apache.tools.ant.taskdefs.optional.PropertyFile"/>
<taskdef name="pvcs" classname="org.apache.tools.ant.taskdefs.optional.pvcs.Pvcs"/>
<taskdef name="record" classname="org.apache.tools.ant.taskdefs.Recorder"/>
<taskdef name="renameext" classname="org.apache.tools.ant.taskdefs.optional.RenameExtensions"/>
<taskdef name="replace" classname="org.apache.tools.ant.taskdefs.Replace"/>
<taskdef name="replaceregexp" classname="org.apache.tools.ant.taskdefs.optional.ReplaceRegExp"/>
<taskdef name="rmic" classname="org.apache.tools.ant.taskdefs.Rmic"/>
<taskdef name="rpm" classname="org.apache.tools.ant.taskdefs.optional.Rpm"/>
<taskdef name="script" classname="org.apache.tools.ant.taskdefs.optional.Script"/>
<taskdef name="sequential" classname="org.apache.tools.ant.taskdefs.Sequential"/>
<taskdef name="signjar" classname="org.apache.tools.ant.taskdefs.SignJar"/>
<taskdef name="sleep" classname="org.apache.tools.ant.taskdefs.Sleep"/>
<taskdef name="soscheckin" classname="org.apache.tools.ant.taskdefs.optional.sos.SOSCheckin"/>
<taskdef name="soscheckout" classname="org.apache.tools.ant.taskdefs.optional.sos.SOSCheckout"/>
<taskdef name="sosget" classname="org.apache.tools.ant.taskdefs.optional.sos.SOSGet"/>
<taskdef name="soslabel" classname="org.apache.tools.ant.taskdefs.optional.sos.SOSLabel"/>
<taskdef name="sound" classname="org.apache.tools.ant.taskdefs.optional.sound.SoundTask"/>
<taskdef name="sql" classname="org.apache.tools.ant.taskdefs.SQLExec"/>
<taskdef name="stcheckin" classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamCheckin"/>
<taskdef name="stcheckout" classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamCheckout"/>
<taskdef name="stlabel" classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamLabel"/>
<taskdef name="stlist" classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamList"/>
<taskdef name="style" classname="org.apache.tools.ant.taskdefs.XSLTProcess"/>
<taskdef name="stylebook" classname="org.apache.tools.ant.taskdefs.optional.StyleBook"/>
<taskdef name="tar" classname="org.apache.tools.ant.taskdefs.Tar"/>
<taskdef name="taskdef" classname="org.apache.tools.ant.taskdefs.Taskdef"/>
<taskdef name="telnet" classname="org.apache.tools.ant.taskdefs.optional.net.TelnetTask"/>
<taskdef name="test" classname="org.apache.tools.ant.taskdefs.optional.Test"/>
<taskdef name="touch" classname="org.apache.tools.ant.taskdefs.Touch"/>
<taskdef name="translate" classname="org.apache.tools.ant.taskdefs.optional.i18n.Translate"/>
<taskdef name="tstamp" classname="org.apache.tools.ant.taskdefs.Tstamp"/>
<taskdef name="typedef" classname="org.apache.tools.ant.taskdefs.Typedef"/>
<taskdef name="unjar" classname="org.apache.tools.ant.taskdefs.Expand"/>
<taskdef name="untar" classname="org.apache.tools.ant.taskdefs.Untar"/>
<taskdef name="unwar" classname="org.apache.tools.ant.taskdefs.Expand"/>
<taskdef name="unzip" classname="org.apache.tools.ant.taskdefs.Expand"/>
<taskdef name="uptodate" classname="org.apache.tools.ant.taskdefs.UpToDate"/>
<taskdef name="vajexport" classname="org.apache.tools.ant.taskdefs.optional.ide.VAJExport"/>
<taskdef name="vajimport" classname="org.apache.tools.ant.taskdefs.optional.ide.VAJImport"/>
<taskdef name="vajload" classname="org.apache.tools.ant.taskdefs.optional.ide.VAJLoadProjects"/>
<taskdef name="vsscheckin" classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKIN"/>
<taskdef name="vsscheckout" classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKOUT"/>
<taskdef name="vssget" classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSGET"/>
<taskdef name="vsshistory" classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSHISTORY"/>
<taskdef name="vsslabel" classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSLABEL"/>
<taskdef name="waitfor" classname="org.apache.tools.ant.taskdefs.WaitFor"/>
<taskdef name="war" classname="org.apache.tools.ant.taskdefs.War"/>
<taskdef name="wljspc" classname="org.apache.tools.ant.taskdefs.optional.jsp.WLJspc"/>
<taskdef name="wlrun" classname="org.apache.tools.ant.taskdefs.optional.ejb.WLRun"/>
<taskdef name="wlstop" classname="org.apache.tools.ant.taskdefs.optional.ejb.WLStop"/>
<taskdef name="xmlvalidate" classname="org.apache.tools.ant.taskdefs.optional.XMLValidateTask"/>
<taskdef name="zip" classname="org.apache.tools.ant.taskdefs.Zip"/>

<converter classname="org.apache.tools.ant.Ant1Converter"/>
<typedef name="patternset" classname="org.apache.tools.ant.types.PatternSet"/>
<typedef name="fileset" classname="org.apache.tools.ant.types.FileSet"/>
<typedef name="path" classname="org.apache.tools.ant.types.Path"/>

</antlib>

+ 59
- 10
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/AntClassLoader.java View File

@@ -136,7 +136,7 @@ public class AntClassLoader extends URLClassLoader
/**
* Initialize the given class
*
* @param theClass XXX Description of Parameter
* @param theClass the class to be initialised
*/
public static void initializeClass(Class theClass) {
// do nothing in Ant2
@@ -188,14 +188,6 @@ public class AntClassLoader extends URLClassLoader
public void cleanup() {
}

/**
* New build listener interface
*
* @param be the build event to be processed
*/
public void processBuildEvent(BuildEvent be) {
}

/**
* Force a class to be loaded by this loader
*
@@ -219,7 +211,64 @@ public class AntClassLoader extends URLClassLoader
}

/**
* Add a path tot his loader
* build started event
*
* @param event build started event
*/
public void buildStarted(BuildEvent event) {
}

/**
* build finished event
*
* @param event build finished event
*/
public void buildFinished(BuildEvent event) {
cleanup();
}

/**
* target started event.
*
* @param event target started event.
*/
public void targetStarted(BuildEvent event) {
}

/**
* target finished event
*
* @param event target finished event
*/
public void targetFinished(BuildEvent event) {
}

/**
* task started event
*
* @param event task started event
*/
public void taskStarted(BuildEvent event) {
}

/**
* task finished event
*
* @param event task finished event
*/
public void taskFinished(BuildEvent event) {
}

/**
* message logged event
*
* @param event message logged event
*/
public void messageLogged(BuildEvent event) {
}

/**
* Add a path to this loader
*
* @param path the path to be added to this loader
*/


+ 1
- 1
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/BuildEvent.java View File

@@ -66,7 +66,7 @@ public class BuildEvent extends org.apache.ant.common.event.BuildEvent {
* @param task the task that emitted the event.
*/
public BuildEvent(Task task) {
super(task, MESSAGE);
super(task.getContext().getModelElement(), MESSAGE);
}
}


+ 2
- 2
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java View File

@@ -629,7 +629,7 @@ public class Project {
public Hashtable getProperties() {
Map properties = dataService.getAllProperties();
Hashtable result = new Hashtable();
for (Iterator i = properties.keySet().iterator(); i.hasNext();) {
for (Iterator i = properties.keySet().iterator(); i.hasNext(); ) {
String name = (String)i.next();
Object value = properties.get(name);
if (value instanceof String) {
@@ -655,7 +655,7 @@ public class Project {
public Hashtable getReferences() {
Map properties = dataService.getAllProperties();
Hashtable result = new Hashtable();
for (Iterator i = properties.keySet().iterator(); i.hasNext();) {
for (Iterator i = properties.keySet().iterator(); i.hasNext(); ) {
String name = (String)i.next();
Object value = properties.get(name);
if (!(value instanceof String)) {


+ 10
- 1
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java View File

@@ -117,7 +117,7 @@ public abstract class ProjectComponent {
public void init(AntContext context) throws ExecutionException {
this.context = context;
org.apache.ant.common.util.Location contextLocation
= context.getLocation();
= context.getModelElement().getLocation();

if (contextLocation
== org.apache.ant.common.util.Location.UNKNOWN_LOCATION) {
@@ -153,5 +153,14 @@ public abstract class ProjectComponent {
context.log(message, Project.MSG_INFO);
}


/**
* Get the context associated with this component
*
* @return the AntContext
*/
protected AntContext getContext() {
return context;
}
}


+ 7
- 2
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java View File

@@ -121,12 +121,18 @@ public abstract class Task extends ProjectComponent
/**
* Gets the description of the Task
*
* @return the task's description
* @return the task's description
*/
public String getDescription() {
return description;
}


/** Validate this component */
public void validateComponent() {
// no default validation for Ant1 tasks
}

/**
* Handle output captured for this task
*
@@ -153,6 +159,5 @@ public abstract class Task extends ProjectComponent
void setTaskType(String type) {
this.taskType = type;
}

}


+ 6
- 0
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/types/DataType.java View File

@@ -132,6 +132,12 @@ public abstract class DataType extends ProjectComponent
return ref != null;
}

/** Validate this component */
public void validateComponent() {
// no default validation for Ant1 types
}


/**
* Performs the check for circular references and returns the referenced
* object.


+ 3
- 0
proposal/mutant/src/java/antlibs/system/antlib.xml View File

@@ -7,6 +7,9 @@
<taskdef name="typedef" classname="org.apache.ant.antlib.system.TypeDef"/>
<taskdef name="loadlib" classname="org.apache.ant.antlib.system.LoadLib"/>

<taskdef name="ant" classname="org.apache.ant.antlib.system.Ant"/>
<taskdef name="antcall" classname="org.apache.ant.antlib.system.AntCall"/>
<converter classname="org.apache.ant.antlib.system.FileConverter"/>
<converter classname="org.apache.ant.antlib.system.URLConverter"/>
<converter classname="org.apache.ant.antlib.system.PrimitiveConverter"/>


proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionComponentService.java → proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Ant.java View File

@@ -51,73 +51,69 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.execution;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.ant.antcore.antlib.AntLibManager;
import org.apache.ant.antcore.util.ConfigException;
package org.apache.ant.antlib.system;
import java.io.File;
import org.apache.ant.common.service.ComponentService;
import org.apache.ant.common.util.ExecutionException;

/**
* The instance of the ComponentServices made available by the core to the
* ant libraries.
* The Ant task - used to execute a different build file
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 27 January 2002
* @created 4 February 2002
*/
public class ExecutionComponentService implements ComponentService {
/** The ExecutionFrame this service instance is working for */
private ExecutionFrame frame;
public class Ant extends AntBase {
/** The ant file to be run */
private File antFile;
/** the base directory to use for the run */
private File baseDir;
/** File to capture any output */
private File outputFile;

/** The library manager instance used to configure libraries. */
private AntLibManager libManager;
/**
* sets the file containing the XML representation model to build
*
* @param antFile the file to build
*/
public void setAntFile(File antFile) {
this.antFile = antFile;
}

/**
* Constructor
* Set the base directory for the execution of the build
*
* @param executionFrame the frame containing this context
* @param allowRemoteLibs true if remote libraries can be loaded though
* this service.
* @param baseDir the base directory for the build
*/
public ExecutionComponentService(ExecutionFrame executionFrame,
boolean allowRemoteLibs) {
this.frame = executionFrame;
libManager = new AntLibManager(allowRemoteLibs);
public void setBaseDir(File baseDir) {
this.baseDir = baseDir;
}

/**
* Load a library or set of libraries from a location making them
* available for use
* The output file for capturing the build output
*
* @param libLocation the file or URL of the library location
* @param importAll if true all tasks are imported as the library is
* loaded
* @exception ExecutionException if the library cannot be loaded
* @param outputFile the output file for capturing the build output
*/
public void loadLib(String libLocation, boolean importAll)
throws ExecutionException {
try {
Map librarySpecs = new HashMap();
libManager.loadLib(librarySpecs, libLocation);
libManager.configLibraries(frame.getInitConfig(), librarySpecs,
frame.getAntLibraries());
public void setOutput(File outputFile) {
this.outputFile = outputFile;
}

if (importAll) {
Iterator i = librarySpecs.keySet().iterator();
while (i.hasNext()) {
String libraryId = (String)i.next();
frame.importLibrary(libraryId);
}
}
} catch (MalformedURLException e) {
throw new ExecutionException("Unable to load libraries from "
+ libLocation, e);
} catch (ConfigException e) {
throw new ExecutionException(e);
/**
* Run the sub-build
*
* @exception ExecutionException if the build can't be run
*/
public void execute() throws ExecutionException {
if (baseDir == null) {
baseDir = getContext().getBaseDir();
}
if (antFile == null) {
antFile = new File(baseDir, "build.ant");
}

ComponentService componentService
= (ComponentService)getCoreService(ComponentService.class);

componentService.runBuild(antFile, getProperties(), getTargets());
}
}


+ 293
- 0
proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/AntBase.java View File

@@ -0,0 +1,293 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 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.antlib.system;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ant.common.antlib.AbstractTask;
import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.antlib.AbstractComponent;
import org.apache.ant.common.service.DataService;
import org.apache.ant.common.util.ExecutionException;

/**
* Common Base class for the Ant and AntCall tasks
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 4 February 2002
*/
public abstract class AntBase extends AbstractTask {

/**
* Simple Property value storing class
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 5 February 2002
*/
public static class Property extends AbstractComponent {
/** The property name */
private String name;

/** The property value*/
private String value;


/**
* Sets the name of the Property
*
* @param name the new name value
*/
public void setName(String name) {
this.name = name;
}

/**
* Sets the value of the Property
*
* @param value the new value value
*/
public void setValue(String value) {
this.value = value;
}

/**
* Gets the name of the Property
*
* @return the name value
*/
public String getName() {
return name;
}

/**
* Gets the value of the Property
*
* @return the value value
*/
public String getValue() {
return value;
}
public void validateComponent() throws ExecutionException {
if (name == null) {
throw new ExecutionException("\"name\" attribute of <property> must be supplied");
}
if (value == null) {
throw new ExecutionException("\"value\" attribute of <property> must be supplied");
}
}
}

/**
* A simple class to store information about references being passed
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 5 February 2002
*/
public static class Reference extends AbstractComponent {
/** The id of the reference to be passed */
private String refId;
/** The id to be used in the sub-build for this reference */
private String toId;

/**
* Sets the refId of the Reference
*
* @param refId the new refId value
*/
public void setRefId(String refId) {
this.refId = refId;
}

/**
* Sets the toId of the Reference
*
* @param toId the new toId value
*/
public void setToId(String toId) {
this.toId = toId;
}

/**
* Gets the refId of the Reference
*
* @return the refId value
*/
public String getRefId() {
return refId;
}

/**
* Gets the toId of the Reference
*
* @return the toId value
*/
public String getToId() {
return toId;
}

public void validateComponent() throws ExecutionException {
if (refId == null) {
throw new ExecutionException("\"refid\" attribute of <reference> must be supplied");
}
}
}

/** The name of the target to be evaluated in the sub-build */
private String targetName;

/** flag which indicates if all current properties should be passed to the subbuild */
private boolean inheritAll = true;

/** flag which indicates if all current references should be passed to the subbuild */
private boolean inheritRefs = false;

/** The properties which will be passed to the sub-build */
private Map properties = new HashMap();

/** The core's data service for manipulating the properties */
private DataService dataService;

/**
* Sets the target to be executed in the subbuild
*
* @param targetName the name of the target to build
*/
public void setTarget(String targetName) {
this.targetName = targetName;
}

/**
* Indicate if all properties should be passed
*
* @param inheritAll true if all properties should be passed
*/
public void setInheritAll(boolean inheritAll) {
this.inheritAll = inheritAll;
}

/**
* Indicate if all references are to be passed to the subbuild
*
* @param inheritRefs true if the sub-build should be given all the current references
*/
public void setInheritRefs(boolean inheritRefs) {
this.inheritRefs = inheritRefs;
}

/**
* Initialise this task
*
* @param context core's context
* @exception ExecutionException if we can't access the data service
*/
public void init(AntContext context) throws ExecutionException {
super.init(context);
dataService = (DataService)getCoreService(DataService.class);
}

/**
* Add a property to be passed to the subbuild
*
* @param property descriptor for the property to be passed
*/
public void addProperty(Property property) {
properties.put(property.getName(), property.getValue());
}

/**
* Add a reference to be passed
*
* @param reference the descriptor of the reference to be passed
* @exception ExecutionException if the reference does not reference a valid object
*/
public void addReference(Reference reference) throws ExecutionException {
String refId = reference.getRefId();
if (!dataService.isDataValueSet(refId)) {
throw new ExecutionException("RefId \"" + refId + "\" is not set");
}
Object value = dataService.getDataValue(refId);
String toId = reference.getToId();
if (toId == null) {
toId = refId;
}

properties.put(toId, value);
}

/**
* Get the list of targets to be executed
*
* @return A List of string target names.
*/
protected List getTargets() {
List targets = new ArrayList();
if (targetName != null) {
targets.add(targetName);
}
return targets;
}

/**
* Get the properties to be used with the sub-build
*
* @return the properties the sub-build will start with
*/
protected Map getProperties() {
return properties;
}

}


+ 87
- 0
proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/AntCall.java View File

@@ -0,0 +1,87 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 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.antlib.system;
import org.apache.ant.common.service.ComponentService;
import org.apache.ant.common.util.ExecutionException;

/**
* The Ant task - used to execute a different build file
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 4 February 2002
*/
public class AntCall extends AntBase {
/**
* Execute the sub-build
*
* @exception ExecutionException if the build fails
*/
public void execute() throws ExecutionException {
ComponentService componentService
= (ComponentService)getCoreService(ComponentService.class);
componentService.callTarget(getProperties(), getTargets());
}

/**
* Alias to add a property to the sub-build
*
* @param param descriptor for the property to be passed
*/
public void addParam(Property param) {
super.addProperty(param);
}

}


+ 32
- 4
proposal/mutant/src/java/cli/org/apache/ant/cli/Commandline.java View File

@@ -60,18 +60,20 @@ import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.ant.antcore.config.AntConfig;
import org.apache.ant.antcore.config.AntConfigHandler;
import org.apache.ant.antcore.execution.ExecutionManager;
import org.apache.ant.antcore.model.Project;
import org.apache.ant.antcore.model.xmlparser.XMLProjectParser;
import org.apache.ant.antcore.util.ConfigException;
import org.apache.ant.antcore.modelparser.XMLProjectParser;
import org.apache.ant.antcore.xml.ParseContext;
import org.apache.ant.antcore.xml.XMLParseException;
import org.apache.ant.common.event.BuildListener;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.util.AntException;
import org.apache.ant.common.util.ConfigException;
import org.apache.ant.common.util.Location;
import org.apache.ant.common.util.MessageLevel;
import org.apache.ant.init.InitConfig;
@@ -87,6 +89,9 @@ public class Commandline {
/** The default build file name */
public final static String DEFAULT_BUILD_FILENAME = "build.ant";

/** The default build file name */
public final static String DEFAULT_ANT1_FILENAME = "build.xml";

/** The initialisation configuration for Ant */
private InitConfig config;

@@ -102,6 +107,9 @@ public class Commandline {
/** The list of targets to be evaluated in this invocation */
private List targets = new ArrayList(4);

/** The command line properties */
private Map definedProperties = new HashMap();

/**
* This is the build file to run. By default it is a file: type URL but
* other URL protocols can be used.
@@ -237,7 +245,7 @@ public class Commandline {
ExecutionManager executionManager
= new ExecutionManager(initConfig, config);
addBuildListeners(executionManager);
executionManager.runBuild(project, targets);
executionManager.runBuild(project, targets, definedProperties);
} catch (Throwable t) {
if (t instanceof AntException) {
AntException e = (AntException)t;
@@ -329,6 +337,9 @@ public class Commandline {
} else if (arg.equals("-verbose") || arg.equals("-v")) {
// printVersion();
messageOutputLevel = MessageLevel.MSG_VERBOSE;
} else if (arg.equals("-debug")) {
// printVersion();
messageOutputLevel = MessageLevel.MSG_DEBUG;
} else if (arg.equals("-listener")) {
try {
listeners.add(args[i++]);
@@ -350,6 +361,17 @@ public class Commandline {
"using the -logger argument");
return;
}
} else if (arg.startsWith("-D")) {
String name = arg.substring(2, arg.length());
String value = null;
int posEq = name.indexOf("=");
if (posEq > 0) {
value = name.substring(posEq + 1);
name = name.substring(0, posEq);
} else if (i < args.length - 1) {
value = args[++i];
}
definedProperties.put(name, value);
} else if (arg.startsWith("-")) {
// we don't have any more args to recognize!
System.out.println("Unknown option: " + arg);
@@ -362,6 +384,12 @@ public class Commandline {

if (buildFileURL == null) {
File defaultBuildFile = new File(DEFAULT_BUILD_FILENAME);
if (!defaultBuildFile.exists()) {
File ant1BuildFile = new File(DEFAULT_ANT1_FILENAME);
if (ant1BuildFile.exists()) {
defaultBuildFile = ant1BuildFile;
}
}
try {
buildFileURL = InitUtils.getFileURL(defaultBuildFile);
} catch (MalformedURLException e) {


+ 184
- 156
proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java View File

@@ -1,125 +1,103 @@
/*
* The Apache Software License, Version 1.1
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
* Copyright (c) 2002 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:
* 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.
* 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.
* 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.
* 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.
* 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.
* 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 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/>.
* 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.cli;

import java.io.PrintStream;
import org.apache.ant.common.model.BuildElement;
import org.apache.ant.common.model.Target;
import org.apache.ant.common.event.BuildEvent;
import org.apache.ant.common.util.AntException;
import org.apache.ant.common.util.Location;
import org.apache.ant.common.util.MessageLevel;
import org.apache.ant.common.event.BuildEvent;
import org.apache.ant.antcore.model.BuildElement;
import org.apache.ant.antcore.model.Target;

/**
* Writes build event to a PrintStream. Currently, it only writes which
* targets are being executed, and any messages that get logged.
* Writes build event to a PrintStream. Currently, it only writes which
* targets are being executed, and any messages that get logged.
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 15 January 2002
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 15 January 2002
*/
public class DefaultLogger implements BuildLogger {

/** Standard field separator */
private static String lSep = System.getProperty("line.separator");
/** spacing to allow for task tags */
private final static int LEFT_COLUMN_SIZE = 12;

/** The stream where output should be written */
/** The stream where output should be written */
private PrintStream out;
/** The stream to where errors should be written */
/** The stream to where errors should be written */
private PrintStream err;
/** The level of messages which should be let through */
/** The level of messages which should be let through */
private int messageOutputLevel = MessageLevel.MSG_ERR;

/** Controls whether adornments are added */
/** Controls whether adornments are added */
private boolean emacsMode = false;
/** The time at which the build started */
/** The time at which the build started */
private long startTime = System.currentTimeMillis();

/**
* Format the time into something readable
*
* @param millis Java millis value
* @return the formatted time
*/
protected static String formatTime(long millis) {
long seconds = millis / 1000;
long minutes = seconds / 60;

if (minutes > 0) {
return Long.toString(minutes) + " minute"
+ (minutes == 1 ? " " : "s ")
+ Long.toString(seconds % 60) + " second"
+ (seconds % 60 == 1 ? "" : "s");
} else {
return Long.toString(seconds) + " second"
+ (seconds % 60 == 1 ? "" : "s");
}

}
/** Standard field separator */
private static String lSep = System.getProperty("line.separator");
/** spacing to allow for task tags */
private final static int LEFT_COLUMN_SIZE = 12;

/**
* Set the messageOutputLevel this logger is to respond to. Only
* messages with a message level lower than or equal to the given level
* are output to the log. <P>
* Set the messageOutputLevel this logger is to respond to. Only
* messages with a message level lower than or equal to the given level
* are output to the log. <P>
*
* Constants for the message levels are in Project.java. The order of
* the levels, from least to most verbose, is MSG_ERR, MSG_WARN,
* MSG_INFO, MSG_VERBOSE, MSG_DEBUG. The default message level for
* DefaultLogger is Project.MSG_ERR.
* Constants for the message levels are in Project.java. The order of
* the levels, from least to most verbose, is MSG_ERR, MSG_WARN,
* MSG_INFO, MSG_VERBOSE, MSG_DEBUG. The default message level for
* DefaultLogger is Project.MSG_ERR.
*
* @param level the logging level for the logger.
* @param level the logging level for the logger.
*/
public void setMessageOutputLevel(int level) {
this.messageOutputLevel = level;
@@ -127,27 +105,28 @@ public class DefaultLogger implements BuildLogger {


/**
* Set the output stream to which this logger is to send its output.
* Set the output stream to which this logger is to send its output.
*
* @param output the output stream for the logger.
* @param output the output stream for the logger.
*/
public void setOutputPrintStream(PrintStream output) {
this.out = output;
}

/**
* Set the output stream to which this logger is to send error messages.
* Set the output stream to which this logger is to send error
* messages.
*
* @param err the error stream for the logger.
* @param err the error stream for the logger.
*/
public void setErrorPrintStream(PrintStream err) {
this.err = err;
}

/**
* Set this logger to produce emacs (and other editor) friendly output.
* Set this logger to produce emacs (and other editor) friendly output.
*
* @param emacsMode true if output is to be unadorned so that emacs and
* @param emacsMode true if output is to be unadorned so that emacs and
* other editors can parse files names, etc.
*/
public void setEmacsMode(boolean emacsMode) {
@@ -155,9 +134,9 @@ public class DefaultLogger implements BuildLogger {
}

/**
* Report an exception
* Report an exception
*
* @param t The exception to be reported.
* @param t The exception to be reported.
*/
public void reportException(Throwable t) {
if (t instanceof AntException) {
@@ -182,72 +161,121 @@ public class DefaultLogger implements BuildLogger {
}

/**
* Process an incoming build event
* Description of the Method
*
* @param event the build event to be processed
* @param event Description of Parameter
*/
public void processBuildEvent(BuildEvent event) {
switch (event.getEventType()) {
case BuildEvent.BUILD_STARTED:
startTime = System.currentTimeMillis();
break;
case BuildEvent.BUILD_FINISHED:
Throwable cause = event.getCause();

if (cause == null) {
out.println(lSep + "BUILD SUCCESSFUL");
} else {
err.println(lSep + "BUILD FAILED" + lSep);

reportException(cause);
}
public void buildStarted(BuildEvent event) {
startTime = System.currentTimeMillis();
}

out.println(lSep + "Total time: "
+ formatTime(System.currentTimeMillis() - startTime));
break;
case BuildEvent.TARGET_STARTED:
if (MessageLevel.MSG_INFO <= messageOutputLevel) {
Target target = (Target)event.getSource();
out.println(lSep + target.getName() + ":");
}
break;
case BuildEvent.TARGET_FINISHED:
break;
case BuildEvent.TASK_STARTED:
break;
case BuildEvent.TASK_FINISHED:
break;
case BuildEvent.MESSAGE:
PrintStream logTo
= event.getPriority() == MessageLevel.MSG_ERR ? err : out;

// Filter out messages based on priority
if (event.getPriority() <= messageOutputLevel
&& event.getSource() instanceof BuildElement) {
// Print out the name of the task if we're in one
BuildElement buildElement
= (BuildElement)event.getSource();
String name = buildElement.getType();

if (!emacsMode) {
String msg = "[" + name + "] ";
int indentSize = LEFT_COLUMN_SIZE - msg.length();
for (int i = 0; i < indentSize; i++) {
logTo.print(" ");
}
logTo.print(msg);
}

// Print the message
logTo.println(event.getMessage());
/**
* Description of the Method
*
* @param event Description of Parameter
*/
public void buildFinished(BuildEvent event) {
Throwable cause = event.getCause();

if (cause == null) {
out.println(lSep + "BUILD SUCCESSFUL");
} else {
err.println(lSep + "BUILD FAILED" + lSep);

reportException(cause);
}

out.println(lSep + "Total time: "
+ formatTime(System.currentTimeMillis() - startTime));
}

/**
* Description of the Method
*
* @param event Description of Parameter
*/
public void targetStarted(BuildEvent event) {
if (MessageLevel.MSG_INFO <= messageOutputLevel) {
Target target = (Target)event.getSource();
out.println(lSep + target.getName() + ":");
}
}

/**
* Description of the Method
*
* @param event Description of Parameter
*/
public void targetFinished(BuildEvent event) {
}

/**
* Description of the Method
*
* @param event Description of Parameter
*/
public void taskStarted(BuildEvent event) {
}

/**
* Description of the Method
*
* @param event Description of Parameter
*/
public void taskFinished(BuildEvent event) {
}

/**
* Description of the Method
*
* @param event Description of Parameter
*/
public void messageLogged(BuildEvent event) {
PrintStream logTo
= event.getPriority() == MessageLevel.MSG_ERR ? err : out;

// Filter out messages based on priority
if (event.getPriority() <= messageOutputLevel
&& event.getModelElement() instanceof BuildElement) {
// Print out the name of the task if we're in one
BuildElement buildElement
= (BuildElement)event.getModelElement();
String name = buildElement.getType();

if (!emacsMode) {
String msg = "[" + name + "] ";
int indentSize = LEFT_COLUMN_SIZE - msg.length();
for (int i = 0; i < indentSize; i++) {
logTo.print(" ");
}
break;
default:
err.println("Unrecognized event type = " +
event.getEventType());
break;
logTo.print(msg);
}
// Print the message
logTo.println(event.getMessage());
}
}

/**
* Format the time into something readable
*
* @param millis Java millis value
* @return the formatted time
*/
protected static String formatTime(long millis) {
long seconds = millis / 1000;
long minutes = seconds / 60;

if (minutes > 0) {
return Long.toString(minutes) + " minute"
+ (minutes == 1 ? " " : "s ")
+ Long.toString(seconds % 60) + " second"
+ (seconds % 60 == 1 ? "" : "s");
} else {
return Long.toString(seconds) + " second"
+ (seconds % 60 == 1 ? "" : "s");
}

}
}


+ 122
- 0
proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java View File

@@ -0,0 +1,122 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 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.common.antlib;

import org.apache.ant.common.util.ExecutionException;

/**
* Abstract implementation of the ExecutionComponent
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 5 February 2002
*/
public abstract class AbstractComponent implements ExecutionComponent {
/** The components's context */
private AntContext context;

/**
* Initialise the component. The component may use the AntContext to
* request services from the Ant core.
*
* @param context the component's context
* @exception ExecutionException if initialisation fails
*/
public void init(AntContext context) throws ExecutionException {
this.context = context;
}

/**
* Validate the component. This is called after the element has been
* configured from its build model. The element may perform validation
* of its configuration

*
* @exception ExecutionException if validation fails
*/
public void validateComponent() throws ExecutionException {
// no validation by default
}

/**
* Get this component's context
*
* @return the component context
*/
protected AntContext getContext() {
return context;
}

/**
* Short cut to get a core service instance
*
* @param serviceClass the required interface of which an instance is required
* @return the core's instance of the requested service
* @exception ExecutionException if the core does not support the requested service
*/
protected Object getCoreService(Class serviceClass)
throws ExecutionException {
return context.getCoreService(serviceClass);
}

/**
* Log a message as a build event
*
* @param message the message to be logged
* @param level the priority level of the message
*/
protected void log(String message, int level) {
context.log(message, level);
}
}


+ 1
- 33
proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java View File

@@ -59,42 +59,10 @@ package org.apache.ant.common.antlib;
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 16 January 2002
*/
public abstract class AbstractTask implements Task {
/** The task's context */
private AntContext context;

/**
* Initialise the task. The task may use the AntContext to request
* services from the Ant core.
*
* @param context the Task's context
*/
public void init(AntContext context) {
this.context = context;
}

public abstract class AbstractTask extends AbstractComponent implements Task {
/** Task is about to be cleaned up */
public void destroy() {
// do nothing here
}

/**
* Get this task's context
*
* @return the task context
*/
protected AntContext getContext() {
return context;
}

/**
* Log a message as a build event
*
* @param message the message to be logged
* @param level the priority level of the message
*/
protected void log(String message, int level) {
context.log(message, level);
}
}


+ 7
- 7
proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java View File

@@ -53,9 +53,9 @@
*/
package org.apache.ant.common.antlib;
import java.io.File;
import org.apache.ant.common.model.ModelElement;

import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.Location;

/**
* The AntContext is the interface through which the Ant container and the
@@ -88,17 +88,17 @@ public interface AntContext {
throws ExecutionException;

/**
* Get the build file location with which this context is associated.
* Get the basedir for the current execution
*
* @return the associated build file location
* @return the base directory for this execution of Ant
*/
Location getLocation();
File getBaseDir();

/**
* Get the basedir for the current execution
* Get the model element associated with this context
*
* @return the base directory for this execution of Ant
* @return the modelElement associated with this context
*/
File getBaseDir();
ModelElement getModelElement();
}


+ 11
- 2
proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java View File

@@ -55,8 +55,8 @@ package org.apache.ant.common.antlib;
import org.apache.ant.common.util.ExecutionException;

/**
* An execution component is a component from an AntLibrary which is used in the
* execution of an Ant build. A component can have a context.
* An execution component is a component from an AntLibrary which is used in
* the execution of an Ant build. A component can have a context.
*
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 1 February 2002
@@ -70,5 +70,14 @@ public interface ExecutionComponent {
* @exception ExecutionException if the component cannot be initialised
*/
void init(AntContext context) throws ExecutionException;

/**
* Validate the component. This is called after the element has been
* configured from its build model. The element may perform validation
* of its configuration
*
* @exception ExecutionException if the component is not validly configured
*/
void validateComponent() throws ExecutionException;
}


+ 14
- 5
proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java View File

@@ -54,6 +54,7 @@
package org.apache.ant.common.event;

import java.util.EventObject;
import org.apache.ant.common.model.ModelElement;

/**
* A BuildEvent indicates the occurence of a significant event in the build.
@@ -96,7 +97,7 @@ public class BuildEvent extends EventObject {
* @param eventType the type of the buildEvent.
* @param source the element with which this event is associated
*/
public BuildEvent(Object source, int eventType) {
public BuildEvent(ModelElement source, int eventType) {
super(source);
this.eventType = eventType;
}
@@ -108,7 +109,7 @@ public class BuildEvent extends EventObject {
* @param cause An exception if associated with the event
* @param source the object with which this event is associated
*/
public BuildEvent(Object source, int eventType,
public BuildEvent(ModelElement source, int eventType,
Throwable cause) {
this(source, eventType);
this.cause = cause;
@@ -117,12 +118,11 @@ public class BuildEvent extends EventObject {
/**
* Create a build event for a message
*
* @param source the object with which the event is
* associated.
* @param source the object with which the event is associated.
* @param message the message associated with this event
* @param priority the message priority
*/
public BuildEvent(Object source, String message,
public BuildEvent(ModelElement source, String message,
int priority) {
this(source, MESSAGE);
this.message = message;
@@ -168,5 +168,14 @@ public class BuildEvent extends EventObject {
public Throwable getCause() {
return cause;
}

/**
* Gets the modelElement of the BuildEvent
*
* @return the model element this event is associated with
*/
public ModelElement getModelElement() {
return (ModelElement)getSource();
}
}


+ 48
- 3
proposal/mutant/src/java/common/org/apache/ant/common/event/BuildListener.java View File

@@ -65,10 +65,55 @@ import java.util.EventListener;
*/
public interface BuildListener extends EventListener {
/**
* Process an incoming build event
* Fired before any targets are started.
*
* @param event the event to be processed.
* @param event the build event for this notification
*/
void processBuildEvent(BuildEvent event);
void buildStarted(BuildEvent event);

/**
* Fired after the last target has finished. This event will still be
* thrown if an error occured during the build.
*
* @param event the build event for this notification
*/
void buildFinished(BuildEvent event);

/**
* Fired when a target is started.
*
* @param event the build event for this notification
*/
void targetStarted(BuildEvent event);

/**
* Fired when a target has finished. This event will still be thrown if
* an error occured during the build.
*
* @param event the build event for this notification
*/
void targetFinished(BuildEvent event);

/**
* Fired when a task is started.
*
* @param event the build event for this notification
*/
void taskStarted(BuildEvent event);

/**
* Fired when a task has finished. This event will still be throw if an
* error occured during the build.
*
* @param event the build event for this notification
*/
void taskFinished(BuildEvent event);

/**
* Fired whenever a message is logged.
*
* @param event the build event for this notification
*/
void messageLogged(BuildEvent event);
}


proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/BuildElement.java → proposal/mutant/src/java/common/org/apache/ant/common/model/BuildElement.java View File

@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.model;
package org.apache.ant.common.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/ModelElement.java → proposal/mutant/src/java/common/org/apache/ant/common/model/ModelElement.java View File

@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.model;
package org.apache.ant.common.model;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/ModelException.java → proposal/mutant/src/java/common/org/apache/ant/common/model/ModelException.java View File

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

import org.apache.ant.common.util.AntException;
import org.apache.ant.common.util.Location;

proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/Project.java → proposal/mutant/src/java/common/org/apache/ant/common/model/Project.java View File

@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.model;
package org.apache.ant.common.model;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
@@ -61,10 +61,10 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.apache.ant.common.util.CircularDependencyChecker;
import org.apache.ant.common.util.CircularDependencyException;
import org.apache.ant.common.util.ConfigException;
import org.apache.ant.common.util.Location;
import org.apache.ant.antcore.util.CircularDependencyChecker;
import org.apache.ant.antcore.util.CircularDependencyException;
import org.apache.ant.antcore.util.ConfigException;

/**
* A project is a collection of targets and global tasks. A project may
@@ -366,42 +366,12 @@ public class Project extends ModelElement {
}

/**
* Validate that this build element is configured correctly
* Validate this project
*
* @param globalName The name of this project in the reference name
* space
* @exception ModelException if the element is invalid
* @exception ModelException if the project is not valid
*/
public void validate(String globalName) throws ModelException {
Set keys = referencedProjects.keySet();
for (Iterator i = keys.iterator(); i.hasNext(); ) {
String refName = (String)i.next();
Project referencedProject
= (Project)referencedProjects.get(refName);
String refGlobalName = refName;
if (globalName != null) {
refGlobalName = globalName + REF_DELIMITER + refName;
}
referencedProject.validate(refGlobalName);
}

// we now check whether all of dependencies for our targets
// exist in the model

// visited contains the targets we have already visited and verified
Set visited = new HashSet();
// checker records the targets we are currently visiting
CircularDependencyChecker checker
= new CircularDependencyChecker("checking target dependencies");
// dependency order is purely recorded for debug purposes
List dependencyOrder = new ArrayList();

for (Iterator i = getTargets(); i.hasNext(); ) {
Target target = (Target)i.next();
target.validate();
fillinDependencyOrder(globalName, target, dependencyOrder,
visited, checker);
}
public void validate() throws ModelException {
validate(null);
}

/**
@@ -466,8 +436,47 @@ public class Project extends ModelElement {
}

/**
* Given a fully qualified target name, this method simply returns the
* fully qualified name of the project
* Validate that this build element is configured correctly
*
* @param globalName The name of this project in the reference name
* space
* @exception ModelException if the element is invalid
*/
protected void validate(String globalName) throws ModelException {
Set keys = referencedProjects.keySet();
for (Iterator i = keys.iterator(); i.hasNext(); ) {
String refName = (String)i.next();
Project referencedProject
= (Project)referencedProjects.get(refName);
String refGlobalName = refName;
if (globalName != null) {
refGlobalName = globalName + REF_DELIMITER + refName;
}
referencedProject.validate(refGlobalName);
}

// we now check whether all of dependencies for our targets
// exist in the model

// visited contains the targets we have already visited and verified
Set visited = new HashSet();
// checker records the targets we are currently visiting
CircularDependencyChecker checker
= new CircularDependencyChecker("checking target dependencies");
// dependency order is purely recorded for debug purposes
List dependencyOrder = new ArrayList();

for (Iterator i = getTargets(); i.hasNext(); ) {
Target target = (Target)i.next();
target.validate();
fillinDependencyOrder(globalName, target, dependencyOrder,
visited, checker);
}
}

/**
* Given a fully qualified target name, this method returns the fully
* qualified name of the project
*
* @param fullTargetName the full qualified target name
* @return the full name of the containing project

proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/Target.java → proposal/mutant/src/java/common/org/apache/ant/common/model/Target.java View File

@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.model;
package org.apache.ant.common.model;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

+ 36
- 0
proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java View File

@@ -52,6 +52,10 @@
* <http://www.apache.org/>.
*/
package org.apache.ant.common.service;
import java.io.File;
import java.util.List;
import java.util.Map;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.util.ExecutionException;

/**
@@ -80,5 +84,37 @@ public interface ComponentService {
*/
void loadLib(String libLocation, boolean importAll)
throws ExecutionException;

/**
* Run a sub-build.
*
* @param antFile the file containing the XML description of the model
* @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
* @exception ExecutionException if the subbuild cannot be run
*/
void runBuild(File antFile, Map properties, List targets)
throws ExecutionException;

/**
* Run a sub-build.
*
* @param model the project model to be used for the build
* @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
* @exception ExecutionException if the subbuild cannot be run
*/
void runBuild(Project model, Map properties, List targets)
throws ExecutionException;

/**
* Run a sub-build using the current frame's project model
*
* @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
* @exception ExecutionException if the subbuild cannot be run
*/
void callTarget(Map properties, List targets)
throws ExecutionException;
}


+ 4
- 3
proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java View File

@@ -133,9 +133,10 @@ public interface DataService {
* is an expensive operation since it must clone all of the property
* stores in all frames
*
* @return a Map containing the frames properties indexed by their full name.
* @return a Map containing the frames properties indexed by their full
* name.
*/
Map getAllProperties();
Map getAllProperties();
}


+ 12
- 9
proposal/mutant/src/java/common/org/apache/ant/common/util/AntException.java View File

@@ -105,7 +105,7 @@ public abstract class AntException extends Exception {
*/
public AntException(String msg, Throwable cause, Location location) {
this(msg, cause);
setLocation(location);
setLocation(location, true);
}

/**
@@ -127,7 +127,7 @@ public abstract class AntException extends Exception {
*/
public AntException(String msg, Location location) {
super(msg);
setLocation(location);
setLocation(location, true);
}

/**
@@ -139,19 +139,22 @@ public abstract class AntException extends Exception {
*/
public AntException(Throwable cause, Location location) {
this(cause);
setLocation(location);
setLocation(location, true);
}

/**
* Sets the file location where the error occured.
*
* @param location the new location value
* @param newLocation the new location value
* @param override true if the location should override any currently set location
*/
public void setLocation(Location location) {
if (location == null) {
this.location = Location.UNKNOWN_LOCATION;
} else {
this.location = location;
public void setLocation(Location newLocation, boolean override) {
if (override || location == Location.UNKNOWN_LOCATION) {
if (newLocation == null) {
this.location = Location.UNKNOWN_LOCATION;
} else {
this.location = newLocation;
}
}
}



proposal/mutant/src/java/antcore/org/apache/ant/antcore/util/CircularDependencyChecker.java → proposal/mutant/src/java/common/org/apache/ant/common/util/CircularDependencyChecker.java View File

@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.util;
package org.apache.ant.common.util;
import java.util.Stack;

/**

proposal/mutant/src/java/antcore/org/apache/ant/antcore/util/CircularDependencyException.java → proposal/mutant/src/java/common/org/apache/ant/common/util/CircularDependencyException.java View File

@@ -51,10 +51,7 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.util;

import org.apache.ant.common.util.AntException;
import org.apache.ant.common.util.Location;
package org.apache.ant.common.util;

/**
* A CircularDependencyException indicates that a circular dependency has

proposal/mutant/src/java/antcore/org/apache/ant/antcore/util/ConfigException.java → proposal/mutant/src/java/common/org/apache/ant/common/util/ConfigException.java View File

@@ -51,10 +51,7 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.util;

import org.apache.ant.common.util.AntException;
import org.apache.ant.common.util.Location;
package org.apache.ant.common.util;

/**
* A ConfigException indicates a problem with Ant's configuration or the

+ 140
- 0
proposal/mutant/src/java/common/org/apache/ant/common/util/StringUtils.java View File

@@ -0,0 +1,140 @@
/*
* 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.common.util;
import java.io.PrintWriter;

import java.io.StringWriter;
import java.util.List;
import java.util.ArrayList;

/**
* A set of helper methods related to string manipulation.
*
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
*/
public final class StringUtils {

/** the line separator for this OS */
public final static String LINE_SEP = System.getProperty("line.separator");

/**
* Convenient method to retrieve the full stacktrace from a given
* exception.
*
* @param t the exception to get the stacktrace from.
* @return the stacktrace from the given exception.
*/
public static String getStackTrace(Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
t.printStackTrace(pw);
pw.flush();
pw.close();
return sw.toString();
}

/**
* Splits up a string into a list of lines. It is equivalent to <tt>
* split(data, '\n')</tt> .
*
* @param data the string to split up into lines.
* @return the list of lines available in the string.
*/
public static List lineSplit(String data) {
return split(data, '\n');
}

/**
* Splits up a string where elements are separated by a specific
* character and return all elements.
*
* @param data the string to split up.
* @param ch the separator character.
* @return the list of elements.
*/
public static List split(String data, int ch) {
List elems = new ArrayList();
int pos = -1;
int i = 0;
while ((pos = data.indexOf(ch, i)) != -1) {
String elem = data.substring(i, pos);
elems.add(elem);
i = pos + 1;
}
elems.add(data.substring(i));
return elems;
}

/**
* Replace occurrences into a string.
*
* @param data the string to replace occurrences into
* @param from the occurrence to replace.
* @param to the occurrence to be used as a replacement.
* @return the new string with replaced occurrences.
*/
public static String replace(String data, String from, String to) {
StringBuffer buf = new StringBuffer(data.length());
int pos = -1;
int i = 0;
while ((pos = data.indexOf(from, i)) != -1) {
buf.append(data.substring(i, pos)).append(to);
i = pos + from.length();
}
buf.append(data.substring(i));
return buf.toString();
}

}


Loading…
Cancel
Save