You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by co...@apache.org on 2002/02/05 12:49:07 UTC

cvs commit: jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/util CircularDependencyChecker.java CircularDependencyException.java ConfigException.java StringUtils.java AntException.java

conor       02/02/05 03:49:06

  Modified:    proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib
                        AntLibHandler.java AntLibManager.java
                        AntLibrarySpec.java
               proposal/mutant/src/java/antcore/org/apache/ant/antcore/config
                        AntConfig.java AntConfigHandler.java
               proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution
                        BuildEventSupport.java ClassIntrospector.java
                        ExecutionContext.java ExecutionDataService.java
                        ExecutionFrame.java ExecutionManager.java
                        TaskContext.java
               proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml
                        ParseContext.java
               proposal/mutant/src/java/antlibs/ant1compat antlib.xml
               proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant
                        AntClassLoader.java BuildEvent.java Project.java
                        ProjectComponent.java Task.java
               proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/types
                        DataType.java
               proposal/mutant/src/java/antlibs/system antlib.xml
               proposal/mutant/src/java/cli/org/apache/ant/cli
                        Commandline.java DefaultLogger.java
               proposal/mutant/src/java/common/org/apache/ant/common/antlib
                        AbstractTask.java AntContext.java
                        ExecutionComponent.java
               proposal/mutant/src/java/common/org/apache/ant/common/event
                        BuildEvent.java BuildListener.java
               proposal/mutant/src/java/common/org/apache/ant/common/service
                        ComponentService.java DataService.java
               proposal/mutant/src/java/common/org/apache/ant/common/util
                        AntException.java
  Added:       proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution
                        ComponentManager.java ImportInfo.java
               proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser
                        BuildElementHandler.java IncludeHandler.java
                        NoProjectReadException.java ProjectHandler.java
                        RefHandler.java TargetHandler.java
                        XMLProjectParser.java
               proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system
                        Ant.java AntBase.java AntCall.java
               proposal/mutant/src/java/common/org/apache/ant/common/antlib
                        AbstractComponent.java
               proposal/mutant/src/java/common/org/apache/ant/common/model
                        BuildElement.java ModelElement.java
                        ModelException.java Project.java Target.java
               proposal/mutant/src/java/common/org/apache/ant/common/util
                        CircularDependencyChecker.java
                        CircularDependencyException.java
                        ConfigException.java StringUtils.java
  Removed:     proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution
                        ExecutionComponentService.java
               proposal/mutant/src/java/antcore/org/apache/ant/antcore/model
                        BuildElement.java ModelElement.java
                        ModelException.java Project.java Target.java
               proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser
                        BuildElementHandler.java IncludeHandler.java
                        NoProjectReadException.java ProjectHandler.java
                        RefHandler.java TargetHandler.java
                        XMLProjectParser.java
               proposal/mutant/src/java/antcore/org/apache/ant/antcore/util
                        CircularDependencyChecker.java
                        CircularDependencyException.java
                        ConfigException.java
  Log:
  Mutant can now build itself - although it cannot bootstrap
  
  Revision  Changes    Path
  1.4       +1 -2      jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java
  
  Index: AntLibHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -w -u -r1.3 -r1.4
  --- AntLibHandler.java	2 Feb 2002 14:50:30 -0000	1.3
  +++ AntLibHandler.java	5 Feb 2002 11:49:04 -0000	1.4
  @@ -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;
  
  
  
  1.2       +18 -18    jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java
  
  Index: AntLibManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- AntLibManager.java	2 Feb 2002 14:50:30 -0000	1.1
  +++ AntLibManager.java	5 Feb 2002 11:49:04 -0000	1.2
  @@ -60,11 +60,11 @@
   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 @@
        * @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 @@
                   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 @@
                   // 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 @@
        * @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 @@
               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 @@
        * @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 @@
                   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 @@
        *      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 @@
               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 @@
               libraries.put(libraryId, antLibrary);
               configuring.leaveNode(libraryId);
           } catch (CircularDependencyException e) {
  -            throw new ConfigException(e);
  +            throw new ExecutionException(e);
           }
       }
   
  
  
  
  1.4       +1 -1      jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrarySpec.java
  
  Index: AntLibrarySpec.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrarySpec.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -w -u -r1.3 -r1.4
  --- AntLibrarySpec.java	2 Feb 2002 14:50:30 -0000	1.3
  +++ AntLibrarySpec.java	5 Feb 2002 11:49:04 -0000	1.4
  @@ -57,7 +57,7 @@
   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.4       +1 -1      jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfig.java
  
  Index: AntConfig.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfig.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -w -u -r1.3 -r1.4
  --- AntConfig.java	2 Feb 2002 14:50:30 -0000	1.3
  +++ AntConfig.java	5 Feb 2002 11:49:04 -0000	1.4
  @@ -60,7 +60,7 @@
   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.4       +1 -1      jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfigHandler.java
  
  Index: AntConfigHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfigHandler.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -w -u -r1.3 -r1.4
  --- AntConfigHandler.java	2 Feb 2002 14:50:31 -0000	1.3
  +++ AntConfigHandler.java	5 Feb 2002 11:49:04 -0000	1.4
  @@ -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;
  
  
  
  1.2       +29 -21    jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java
  
  Index: BuildEventSupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- BuildEventSupport.java	2 Feb 2002 14:50:31 -0000	1.1
  +++ BuildEventSupport.java	5 Feb 2002 11:49:04 -0000	1.2
  @@ -56,7 +56,7 @@
   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;
   
  @@ -102,26 +102,16 @@
       }
   
       /**
  -     * 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
        *
        * @param element the build element with which the event is associated
        */
       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 @@
                                     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 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 @@
                                      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 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 @@
                                    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 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);
  +        }
       }
   }
   
  
  
  
  1.4       +11 -2     jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ClassIntrospector.java
  
  Index: ClassIntrospector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ClassIntrospector.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -w -u -r1.3 -r1.4
  --- ClassIntrospector.java	2 Feb 2002 14:50:31 -0000	1.3
  +++ ClassIntrospector.java	5 Feb 2002 11:49:04 -0000	1.4
  @@ -95,6 +95,15 @@
                    && !args[0].isArray()) {
                   reflector.addAttributeMethod(m, getPropertyName(name, "set"),
                       converters);
  +            } 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)
  
  
  
  1.3       +11 -13    jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java
  
  Index: ExecutionContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -u -r1.2 -r1.3
  --- ExecutionContext.java	2 Feb 2002 14:50:31 -0000	1.2
  +++ ExecutionContext.java	5 Feb 2002 11:49:04 -0000	1.3
  @@ -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 @@
        * 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 @@
       }
   
       /**
  -     * 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;
       }
   
       /**
  
  
  
  1.3       +14 -13    jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionDataService.java
  
  Index: ExecutionDataService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionDataService.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -u -r1.2 -r1.3
  --- ExecutionDataService.java	3 Feb 2002 12:52:58 -0000	1.2
  +++ ExecutionDataService.java	5 Feb 2002 11:49:04 -0000	1.3
  @@ -132,6 +132,18 @@
       }
   
       /**
  +     * 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 @@
               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 @@
   
           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();
  -    }         
   }
   
  
  
  
  1.5       +184 -310  jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionFrame.java
  
  Index: ExecutionFrame.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionFrame.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -w -u -r1.4 -r1.5
  --- ExecutionFrame.java	3 Feb 2002 12:52:58 -0000	1.4
  +++ ExecutionFrame.java	5 Feb 2002 11:49:04 -0000	1.5
  @@ -59,25 +59,23 @@
   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 @@
    * @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,25 +125,10 @@
        */
       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 @@
        */
       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 @@
        *      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);
       }
   
       /**
  @@ -268,87 +189,23 @@
       }
   
       /**
  -     * 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 @@
       }
   
       /**
  -     * Get the collection of Ant Libraries defined for this frame
  +     * Set the initial properties to be used when the frame starts execution
        *
  -     * @return a map of Ant Libraries indexed by thier library Id
  +     * @param properties a Map of named properties which may in fact be any
  +     *      object
  +     * @exception ExecutionException if the properties cannot be set
        */
  -    protected Map getAntLibraries() {
  -        return antLibraries;
  +    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 containing the frames properties indexed by their full
  +     *      name.
  +     */
  +    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;
       }
   
       /**
  @@ -423,6 +327,16 @@
       }
   
       /**
  +     * 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
        *
        * @return the baseDir value
  @@ -501,6 +415,35 @@
       }
   
       /**
  +     * 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
        *
        * @param listener the listener to be added to the frame
  @@ -533,9 +476,9 @@
        * @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 @@
           // 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 @@
           } catch (ConfigException e) {
               throw new ExecutionException(e);
           }
  +
       }
   
       /**
  @@ -593,7 +537,7 @@
               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 @@
               } 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 @@
               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) {
  @@ -687,28 +623,6 @@
   
   
       /**
  -     * 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
        *
        * @param c the class for which the reflector is desired
  @@ -718,7 +632,8 @@
           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 @@
       }
   
       /**
  -     * 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);
           }
  -        AntLibFactory libFactory = antLibrary.getFactory();
  -        if (libFactory == null) {
  -            libFactory = new StandardLibFactory();
  +            } else {
  +                baseDir = new File(".");
  +            }
  +            setDataValue(BASEDIR_PROP, baseDir.getPath(), true);
  +        }
  +
  +        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 @@
        */
       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 @@
               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 @@
           String nestedElementName = model.getType();
           Object nestedElement
                = reflector.createElement(element, nestedElementName);
  +        try {
           if (nestedElement instanceof ExecutionComponent) {
  -            ExecutionComponent component = (ExecutionComponent)nestedElement;
  +                ExecutionComponent component
  +                     = (ExecutionComponent)nestedElement;
               ExecutionContext context
  -                 = new ExecutionContext(this, eventSupport);
  +                     = new ExecutionContext(this);
               context.setModelElement(model);
               component.init(context);
  -        }
  -
  -        try {
               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 @@
            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 @@
               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 @@
   
               // 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 @@
                    + 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 @@
        */
       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 @@
                    = 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 @@
               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);
  +            }
               return typeInstance;
           } catch (InstantiationException e) {
               throw new ExecutionException("Unable to instantiate type class "
  @@ -1185,10 +1060,9 @@
                    + typeClass.getName() + " for type <" + model.getType() + ">",
                   e, model.getLocation());
           } catch (ExecutionException e) {
  -            e.setLocation(model.getLocation());
  +            e.setLocation(model.getLocation(), false);
               throw e;
           }
       }
  -
   }
   
  
  
  
  1.4       +14 -10    jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java
  
  Index: ExecutionManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -w -u -r1.3 -r1.4
  --- ExecutionManager.java	2 Feb 2002 14:50:31 -0000	1.3
  +++ ExecutionManager.java	5 Feb 2002 11:49:04 -0000	1.4
  @@ -61,10 +61,10 @@
   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 @@
        *
        * @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 @@
   
               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 @@
        *
        * @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 @@
        * 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 @@
                       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);
  
  
  
  1.3       +6 -8      jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java
  
  Index: TaskContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -u -r1.2 -r1.3
  --- TaskContext.java	2 Feb 2002 14:50:31 -0000	1.2
  +++ TaskContext.java	5 Feb 2002 11:49:04 -0000	1.3
  @@ -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 @@
        * 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);
       }
   
       /**
  @@ -122,7 +119,8 @@
       /**
        * 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();
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java
  
  Index: ComponentManager.java
  ===================================================================
  /*
   * 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);
          }
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ImportInfo.java
  
  Index: ImportInfo.java
  ===================================================================
  /*
   * 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();
      }
  
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/BuildElementHandler.java
  
  Index: BuildElementHandler.java
  ===================================================================
  /*
   * 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.modelparser;
  import java.util.Iterator;
  
  import org.apache.ant.common.model.BuildElement;
  import org.apache.ant.antcore.xml.ElementHandler;
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXParseException;
  
  /**
   * A BuildElementHandler parses the task elements of a build. Task elements
   * include tasks themselves plus all their nested elements to any depth.
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 9 January 2002
   */
  public class BuildElementHandler extends ElementHandler {
      /** The task element being parsed by this handler. */
      private BuildElement buildElement;
  
      /**
       * Get the task element being parsed by this handler.
       *
       * @return the BuildElement being parsed.
       */
      public BuildElement getBuildElement() {
          return buildElement;
      }
  
      /**
       * Create a task element handler to parse a task element
       *
       * @param elementName the name of the element - always target
       */
      public void processElement(String elementName) {
          buildElement
               = new BuildElement(getLocation(), elementName);
  
          for (Iterator i = getAttributes(); i.hasNext(); ) {
              String attributeName = (String)i.next();
              buildElement.addAttribute(attributeName,
                  getAttribute(attributeName));
          }
          buildElement.setAspects(getAspects());
      }
  
  
      /**
       * Process a nested element of this task element. All nested elements of
       * a buildElement are themselves buildElements.
       *
       * @param uri The Namespace URI.
       * @param localName The local name (without prefix).
       * @param qualifiedName The qualified name (with prefix)
       * @param attributes The attributes attached to the element.
       * @throws SAXParseException if there is a parsing problem.
       */
      public void startElement(String uri, String localName, String qualifiedName,
                               Attributes attributes)
           throws SAXParseException {
          // everything within a task element is also a task element
          BuildElementHandler nestedHandler
               = new BuildElementHandler();
          nestedHandler.start(getParseContext(), getXMLReader(),
              this, getLocator(), attributes, getElementSource(), qualifiedName);
          buildElement.addNestedElement(nestedHandler.getBuildElement());
      }
  
  
      /**
       * This method is called when this element is finished being processed.
       * This is a template method allowing subclasses to complete any
       * necessary processing.
       */
      protected void finish() {
          String content = getContent();
          if (content != null && content.trim().length() != 0) {
              buildElement.addText(getContent());
          }
      }
  
      /**
       * Validate that the given attribute and value are valid.
       *
       * @param attributeName The name of the attributes
       * @param attributeValue The value of the attributes
       */
      protected void validateAttribute(String attributeName,
                                       String attributeValue) {
          // do nothing - all attributes are OK by default.
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/IncludeHandler.java
  
  Index: IncludeHandler.java
  ===================================================================
  /*
   * 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.modelparser;
  
  import java.net.MalformedURLException;
  import java.net.URL;
  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;
  
  /**
   * The include handler is used to read in included projects or fragments
   * into a project.
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 11 January 2002
   */
  public class IncludeHandler extends ElementHandler {
      /** The attribute name which identifies the fragment to be included */
      public final static String SYSTEMID_ATTR = "fragment";
  
      /** The including project */
      private Project project;
  
  
      /**
       * Create an IncludeHandler.
       *
       * @param project the project into which the include fragment is to be
       *      placed
       */
      public IncludeHandler(Project project) {
          this.project = project;
      }
  
  
      /**
       * Process the element.
       *
       * @param elementName the name of the element
       * @exception SAXParseException if there is a problem parsing the
       *      element
       */
      public void processElement(String elementName)
           throws SAXParseException {
  
          String includeSystemId = getAttribute(SYSTEMID_ATTR);
          if (includeSystemId == null) {
              throw new SAXParseException("Attribute " + SYSTEMID_ATTR +
                  " is required in an <include> element", getLocator());
          }
  
          // create a new parser to read this project relative to the
          // project's URI
          try {
              URL includeURL = new URL(getElementSource(), includeSystemId);
              ProjectHandler includedProjectHandler = new ProjectHandler(project);
              getParseContext().parse(includeURL,
                  new String[]{"project", "fragment"},
                  includedProjectHandler);
          } catch (MalformedURLException e) {
              throw new SAXParseException("Unable to include " + includeSystemId
                   + ": " + e.getMessage(), getLocator());
          } catch (XMLParseException e) {
              throw new SAXParseException("Error parsing included project "
                   + includeSystemId + ": " + e.getMessage(), getLocator());
          }
      }
  
      /**
       * Validate that the given attribute and value are valid.
       *
       * @param attributeName The name of the attributes
       * @param attributeValue The value of the attributes
       * @exception SAXParseException if the attribute is not allowed on the
       *      element.
       */
      protected void validateAttribute(String attributeName,
                                       String attributeValue)
           throws SAXParseException {
          if (!attributeName.equals(SYSTEMID_ATTR)) {
              throwInvalidAttribute(attributeName);
          }
      }
  }
  
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/NoProjectReadException.java
  
  Index: NoProjectReadException.java
  ===================================================================
  /*
   * 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.modelparser;
  
  /**
   * A NoProjectReadException is used to indicate that a project was not read
   * from the particular source. This will happen if the source is empty.
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 15 January 2002
   */
  public class NoProjectReadException extends Exception {
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java
  
  Index: ProjectHandler.java
  ===================================================================
  /*
   * 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.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;
  
  /**
   * Element to parse the project element. The project handler creates a
   * number of different handlers to which it delegates processing of child
   * elements.
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 9 January 2002
   */
  public class ProjectHandler extends ElementHandler {
      /** The basedir attribute tag */
      public final static String BASEDIR_ATTR = "basedir";
  
      /** The name attribute */
      public final static String NAME_ATTR = "name";
  
      /** The default attribute name */
      public final static String DEFAULT_ATTR = "default";
  
      /** The project being parsed. */
      private Project project;
  
      /** Constructor parsing a new project */
      public ProjectHandler() {
          project = null;
      }
  
      /**
       * Constructor for including a project or fragment into an existing
       * project
       *
       * @param project The project to be configured by the handler
       */
      public ProjectHandler(Project project) {
          this.project = project;
      }
  
      /**
       * Get the project that has been parsed from the element
       *
       * @return the project that has been parsed from the build source
       * @throws NoProjectReadException thrown if no project was read in.
       */
      public Project getProject()
           throws NoProjectReadException {
          if (project == null) {
              throw new NoProjectReadException();
          }
          return project;
      }
  
  
      /**
       * Process the project element
       *
       * @param elementName the name of the element
       * @exception SAXParseException if there is a problem parsing the
       *      element
       */
      public void processElement(String elementName)
           throws SAXParseException {
          if (project == null) {
              project = new Project(getElementSource(), getLocation());
  
              project.setDefaultTarget(getAttribute(DEFAULT_ATTR));
              project.setBase(getAttribute(BASEDIR_ATTR));
              project.setName(getAttribute(NAME_ATTR));
              project.setAspects(getAspects());
          }
      }
  
  
      /**
       * Start a new element in the project. Project currently handles the
       * following elements
       * <ul>
       *   <li> ref</li>
       *   <li> include</li>
       *   <li> target</li>
       * </ul>
       * Everything else is treated as a task.
       *
       * @param uri The Namespace URI.
       * @param localName The local name (without prefix).
       * @param qualifiedName The qualified name (with prefix)
       * @param attributes The attributes attached to the element.
       * @throws SAXParseException if there is a parsing problem.
       */
      public void startElement(String uri, String localName, String qualifiedName,
                               Attributes attributes)
           throws SAXParseException {
               
          if (qualifiedName.equals("ref")) {
              RefHandler refHandler = new RefHandler();
              refHandler.start(getParseContext(), getXMLReader(), this,
                  getLocator(), attributes, getElementSource(),
                  qualifiedName);
              try {
                  project.referenceProject(refHandler.getRefName(),
                      refHandler.getReferencedProject());
              } catch (ModelException e) {
                  throw new SAXParseException(e.getMessage(), getLocator(), e);
              }
          } else if (qualifiedName.equals("include")) {
              IncludeHandler includeHandler = new IncludeHandler(project);
              includeHandler.start(getParseContext(), getXMLReader(),
                  this, getLocator(), attributes, getElementSource(),
                  qualifiedName);
          } else if (qualifiedName.equals("target")) {
              TargetHandler targetHandler = new TargetHandler();
              targetHandler.start(getParseContext(), getXMLReader(),
                  this, getLocator(), attributes,
                  getElementSource(), qualifiedName);
              try {
                  project.addTarget(targetHandler.getTarget());
              } catch (ModelException e) {
                  throw new SAXParseException(e.getMessage(), getLocator(), e);
              }
          } else {
              // everything else is a task
              BuildElementHandler buildElementHandler = new BuildElementHandler();
              buildElementHandler.start(getParseContext(), getXMLReader(),
                  this, getLocator(), attributes, getElementSource(),
                  qualifiedName);
              project.addTask(buildElementHandler.getBuildElement());
          }
      }
  
      /**
       * Validate that the given attribute and value are valid.
       *
       * @param attributeName The name of the attributes
       * @param attributeValue The value of the attributes
       * @exception SAXParseException if the attribute is not allowed on the
       *      element.
       */
      protected void validateAttribute(String attributeName,
                                       String attributeValue)
           throws SAXParseException {
          if (!attributeName.equals(BASEDIR_ATTR) &&
              !attributeName.equals(NAME_ATTR) &&
              !attributeName.equals(DEFAULT_ATTR)) {
              throwInvalidAttribute(attributeName);
          }
      }
  }
  
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/RefHandler.java
  
  Index: RefHandler.java
  ===================================================================
  /*
   * 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.modelparser;
  
  import java.net.MalformedURLException;
  import java.net.URL;
  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;
  
  /**
   * The Ref handler handles the reference of one project to another. The
   * project to be references is parsed with a new parser and then added to
   * the current project under the given alias
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 10 January 2002
   */
  public class RefHandler extends ElementHandler {
      /** The attribute used to name the ref. */
      public final static String NAME_ATTR = "name";
  
      /** The attribute name used to locate the project to be referenced. */
      public final static String SYSTEMID_ATTR = "project";
  
      /** The project that has been referenced. */
      private Project referencedProject;
  
      /**
       * Get the project referenced.
       *
       * @return an referenced Project.
       */
      public Project getReferencedProject() {
          return referencedProject;
      }
  
  
      /**
       * Get the name under which the project is referenced.
       *
       * @return the ref name of the project
       */
      public String getRefName() {
          return getAttribute(NAME_ATTR);
      }
  
  
      /**
       * Create an ref handler to reference a project.
       *
       * @param elementName the name of the ref element
       * @exception SAXParseException if the ref element could not be parsed
       */
      public void processElement(String elementName)
           throws SAXParseException {
          String refName = getAttribute(NAME_ATTR);
          if (refName == null) {
              throw new SAXParseException("Attribute " + NAME_ATTR +
                  " is required in a <ref> element", getLocator());
          }
  
          String projectSystemId = getAttribute(SYSTEMID_ATTR);
          if (projectSystemId == null) {
              throw new SAXParseException("Attribute " + SYSTEMID_ATTR +
                  " is required in a <ref> element", getLocator());
          }
  
          // create a new parser to read this project relative to the
          // project's URI
          try {
              URL refURL = new URL(getElementSource(), projectSystemId);
              ProjectHandler referencedProjectHandler = new ProjectHandler();
              getParseContext().parse(refURL, "project",
                  referencedProjectHandler);
  
              referencedProject = referencedProjectHandler.getProject();
          } catch (XMLParseException e) {
              throw new SAXParseException("Error parsing referenced project "
                   + projectSystemId + ": " + e.getMessage(), getLocator(), e);
          } catch (NoProjectReadException e) {
              throw new SAXParseException("No project found in the reference: "
                   + projectSystemId, getLocator(), e);
          } catch (MalformedURLException e) {
              throw new SAXParseException("Unable to reference project "
                   + projectSystemId + ": " + e.getMessage(),
                  getLocator(), e);
          }
      }
  
      /**
       * Validate that the given attribute and value are valid.
       *
       * @param attributeName The name of the attributes
       * @param attributeValue The value of the attributes
       * @exception SAXParseException if the attribute is not allowed on the
       *      element.
       */
      protected void validateAttribute(String attributeName,
                                       String attributeValue)
           throws SAXParseException {
          if (!attributeName.equals(SYSTEMID_ATTR) &&
              !attributeName.equals(NAME_ATTR)) {
              throwInvalidAttribute(attributeName);
          }
      }
  }
  
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/TargetHandler.java
  
  Index: TargetHandler.java
  ===================================================================
  /*
   * 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.modelparser;
  import java.util.StringTokenizer;
  
  import org.apache.ant.common.model.Target;
  import org.apache.ant.antcore.xml.ElementHandler;
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXParseException;
  
  /**
   * Element handler for the target element
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 9 January 2002
   */
  public class TargetHandler extends ElementHandler {
      /** The name attribute */
      public final static String NAME_ATTR = "name";
  
      /** The depends attribute name */
      public final static String DEPENDS_ATTR = "depends";
  
      /** 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;
  
      /**
       * Get the target parsed by this handler.
       *
       * @return the Target model object parsed by this handler.
       */
      public Target getTarget() {
          return target;
      }
  
  
      /**
       * Process the target element.
       *
       * @param elementName the name of the element
       * @exception SAXParseException if there is a problem parsing the
       *      element
       */
      public void processElement(String elementName)
           throws SAXParseException {
          target = new Target(getLocation(), getAttribute(NAME_ATTR));
          target.setDescription(getAttribute(DESC_ATTR));
          target.setAspects(getAspects());
  
          String depends = getAttribute(DEPENDS_ATTR);
          if (depends != null) {
              StringTokenizer tokenizer = new StringTokenizer(depends, ",");
              while (tokenizer.hasMoreTokens()) {
                  String dependency = tokenizer.nextToken().trim();
                  target.addDependency(dependency);
              }
          }
      }
  
  
      /**
       * Process an element within this target. All elements within the target
       * are treated as tasks.
       *
       * @param uri The Namespace URI.
       * @param localName The local name (without prefix).
       * @param qualifiedName The qualified name (with prefix)
       * @param attributes The attributes attached to the element.
       * @throws SAXParseException if there is a parsing problem.
       */
      public void startElement(String uri, String localName, String qualifiedName,
                               Attributes attributes)
           throws SAXParseException {
          // everything is a task
          BuildElementHandler taskHandler = new BuildElementHandler();
          taskHandler.start(getParseContext(), getXMLReader(), this, getLocator(),
              attributes, getElementSource(), qualifiedName);
          target.addTask(taskHandler.getBuildElement());
      }
  
      /**
       * Validate that the given attribute and value are valid.
       *
       * @param attributeName The name of the attributes
       * @param attributeValue The value of the attributes
       * @exception SAXParseException if the attribute is not allowed on the
       *      element.
       */
      protected void validateAttribute(String attributeName,
                                       String attributeValue)
           throws SAXParseException {
          if (!attributeName.equals(NAME_ATTR) 
              && !attributeName.equals(DEPENDS_ATTR) 
              && !attributeName.equals(DESC_ATTR) 
              && !attributeName.equals(IF_ATTR)
              && !attributeName.equals(UNLESS_ATTR)) {
              throwInvalidAttribute(attributeName);
          }
      }
  }
  
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/XMLProjectParser.java
  
  Index: XMLProjectParser.java
  ===================================================================
  /*
   * 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.modelparser;
  import java.net.URL;
  
  import org.apache.ant.common.util.Location;
  import org.apache.ant.common.model.Project;
  import org.apache.ant.antcore.xml.ParseContext;
  import org.apache.ant.antcore.xml.XMLParseException;
  
  /**
   * Parses an Ant project model from an XML source using a SAX Parser.
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 9 January 2002
   */
  public class XMLProjectParser {
      /**
       * Parse a build file from the given URL.
       *
       * @param buildSource the URL from where the build source may be read.
       * @return a project model representing the project
       * @exception XMLParseException if there is an problem parsing the XML
       *      representation
       */
      public Project parseBuildFile(URL buildSource)
           throws XMLParseException {
          try {
              ParseContext context = new ParseContext();
              ProjectHandler projectHandler = new ProjectHandler();
  
              context.parse(buildSource, "project", projectHandler);
  
              return projectHandler.getProject();
          } catch (NoProjectReadException e) {
              throw new XMLParseException("No project defined in build source ",
                  e, new Location(buildSource.toString()));
          }
      }
  }
  
  
  
  
  1.4       +8 -3      jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java
  
  Index: ParseContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -w -u -r1.3 -r1.4
  --- ParseContext.java	2 Feb 2002 14:50:31 -0000	1.3
  +++ ParseContext.java	5 Feb 2002 11:49:05 -0000	1.4
  @@ -59,8 +59,9 @@
   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 @@
               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);
               }
  
  
  
  1.2       +138 -9    jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/antlib.xml
  
  Index: antlib.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/antlib.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- antlib.xml	2 Feb 2002 14:50:32 -0000	1.1
  +++ antlib.xml	5 Feb 2002 11:49:05 -0000	1.2
  @@ -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>
  
  
  
  1.2       +59 -10    jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/AntClassLoader.java
  
  Index: AntClassLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/AntClassLoader.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- AntClassLoader.java	2 Feb 2002 14:50:32 -0000	1.1
  +++ AntClassLoader.java	5 Feb 2002 11:49:05 -0000	1.2
  @@ -136,7 +136,7 @@
       /**
        * 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
  @@ -189,14 +189,6 @@
       }
   
       /**
  -     * 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
        *
        * @param classname the name of the class to be loaded
  @@ -219,6 +211,63 @@
       }
   
       /**
  +     * 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 tot his loader
        *
        * @param path the path to be added to this loader
  
  
  
  1.2       +1 -1      jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/BuildEvent.java
  
  Index: BuildEvent.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/BuildEvent.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- BuildEvent.java	2 Feb 2002 14:50:32 -0000	1.1
  +++ BuildEvent.java	5 Feb 2002 11:49:05 -0000	1.2
  @@ -66,7 +66,7 @@
        * @param task the task that emitted the event.
        */
       public BuildEvent(Task task) {
  -        super(task, MESSAGE);
  +        super(task.getContext().getModelElement(), MESSAGE);
       }
   }
   
  
  
  
  1.3       +2 -2      jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java
  
  Index: Project.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -u -r1.2 -r1.3
  
  
  
  1.2       +10 -1     jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java
  
  Index: ProjectComponent.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- ProjectComponent.java	2 Feb 2002 14:50:32 -0000	1.1
  +++ ProjectComponent.java	5 Feb 2002 11:49:05 -0000	1.2
  @@ -117,7 +117,7 @@
       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 @@
           context.log(message, Project.MSG_INFO);
       }
   
  +
  +    /**
  +     * Get the context associated with this component
  +     *
  +     * @return the AntContext 
  +     */
  +    protected AntContext getContext() {
  +        return context;
  +    }
   }
   
  
  
  
  1.2       +7 -2      jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java
  
  Index: Task.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- Task.java	2 Feb 2002 14:50:32 -0000	1.1
  +++ Task.java	5 Feb 2002 11:49:05 -0000	1.2
  @@ -127,6 +127,12 @@
           return description;
       }
   
  +
  +    /** Validate this component */
  +    public void validateComponent() {
  +        // no default validation for Ant1 tasks
  +    }
  +
       /**
        * Handle output captured for this task
        *
  @@ -153,6 +159,5 @@
       void setTaskType(String type) {
           this.taskType = type;
       }
  -
   }
   
  
  
  
  1.2       +6 -0      jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/types/DataType.java
  
  Index: DataType.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/types/DataType.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- DataType.java	2 Feb 2002 14:50:32 -0000	1.1
  +++ DataType.java	5 Feb 2002 11:49:05 -0000	1.2
  @@ -132,6 +132,12 @@
           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.
  
  
  
  1.2       +3 -0      jakarta-ant/proposal/mutant/src/java/antlibs/system/antlib.xml
  
  Index: antlib.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/antlibs/system/antlib.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- antlib.xml	2 Feb 2002 14:50:32 -0000	1.1
  +++ antlib.xml	5 Feb 2002 11:49:06 -0000	1.2
  @@ -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"/>          
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Ant.java
  
  Index: Ant.java
  ===================================================================
  /*
   * 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.io.File;
  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 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;
  
      /**
       * sets the file containing the XML representation model to build
       *
       * @param antFile the file to build
       */
      public void setAntFile(File antFile) {
          this.antFile = antFile;
      }
  
      /**
       * Set the base directory for the execution of the build
       *
       * @param baseDir the base directory for the build
       */
      public void setBaseDir(File baseDir) {
          this.baseDir = baseDir;
      }
  
      /**
       * The output file for capturing the build output
       *
       * @param outputFile the output file for capturing the build output
       */
      public void setOutput(File outputFile) {
          this.outputFile = outputFile;
      }
  
      /**
       * 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());
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/AntBase.java
  
  Index: AntBase.java
  ===================================================================
  /*
   * 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;
      }
  
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/AntCall.java
  
  Index: AntCall.java
  ===================================================================
  /*
   * 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);
      }
  
  }
  
  
  
  
  1.4       +32 -4     jakarta-ant/proposal/mutant/src/java/cli/org/apache/ant/cli/Commandline.java
  
  Index: Commandline.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/cli/org/apache/ant/cli/Commandline.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -w -u -r1.3 -r1.4
  --- Commandline.java	2 Feb 2002 14:50:33 -0000	1.3
  +++ Commandline.java	5 Feb 2002 11:49:06 -0000	1.4
  @@ -60,18 +60,20 @@
   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 @@
       /** 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 @@
       /** 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 @@
               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 @@
               } 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 @@
                           "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 @@
   
           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) {
  
  
  
  1.4       +190 -162  jakarta-ant/proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java
  
  Index: DefaultLogger.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -w -u -r1.3 -r1.4
  --- DefaultLogger.java	2 Feb 2002 14:50:33 -0000	1.3
  +++ DefaultLogger.java	5 Feb 2002 11:49:06 -0000	1.4
  @@ -54,12 +54,12 @@
   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
  @@ -70,11 +70,6 @@
    */
   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 */
       private PrintStream out;
       /** The stream to where errors should be written */
  @@ -87,27 +82,10 @@
       /** 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
  @@ -136,7 +114,8 @@
       }
   
       /**
  -     * 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.
        */
  @@ -182,16 +161,20 @@
       }
   
       /**
  -     * 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:
  +    public void buildStarted(BuildEvent event) {
                   startTime = System.currentTimeMillis();
  -                break;
  -            case BuildEvent.BUILD_FINISHED:
  +    }
  +
  +    /**
  +     *  Description of the Method
  +     *
  +     * @param  event Description of Parameter
  +     */
  +    public void buildFinished(BuildEvent event) {
                   Throwable cause = event.getCause();
   
                   if (cause == null) {
  @@ -204,29 +187,59 @@
   
                   out.println(lSep + "Total time: "
                        + formatTime(System.currentTimeMillis() - startTime));
  -                break;
  -            case BuildEvent.TARGET_STARTED:
  +    }
  +
  +    /**
  +     *  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() + ":");
                   }
  -                break;
  -            case BuildEvent.TARGET_FINISHED:
  -                break;
  -            case BuildEvent.TASK_STARTED:
  -                break;
  -            case BuildEvent.TASK_FINISHED:
  -                break;
  -            case BuildEvent.MESSAGE:
  +    }
  +
  +    /**
  +     *  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.getSource() instanceof BuildElement) {
  +            && event.getModelElement() instanceof BuildElement) {
                       // Print out the name of the task if we're in one
                       BuildElement buildElement
  -                         = (BuildElement)event.getSource();
  +                 = (BuildElement)event.getModelElement();
                       String name = buildElement.getType();
   
                       if (!emacsMode) {
  @@ -241,13 +254,28 @@
                       // Print the message
                       logTo.println(event.getMessage());
                   }
  -                break;
  -            default:
  -                err.println("Unrecognized event type = " +
  -                    event.getEventType());
  -                break;
           }
  +
  +    /**
  +     *  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");
       }
   
  +    }
   }
   
  
  
  
  1.2       +1 -33     jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java
  
  Index: AbstractTask.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- AbstractTask.java	2 Feb 2002 14:50:33 -0000	1.1
  +++ AbstractTask.java	5 Feb 2002 11:49:06 -0000	1.2
  @@ -59,42 +59,10 @@
    * @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);
       }
   }
   
  
  
  
  1.2       +7 -7      jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java
  
  Index: AntContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- AntContext.java	2 Feb 2002 14:50:33 -0000	1.1
  +++ AntContext.java	5 Feb 2002 11:49:06 -0000	1.2
  @@ -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 @@
            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();
   }
   
  
  
  
  1.2       +11 -2     jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java
  
  Index: ExecutionComponent.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- ExecutionComponent.java	2 Feb 2002 14:50:33 -0000	1.1
  +++ ExecutionComponent.java	5 Feb 2002 11:49:06 -0000	1.2
  @@ -55,8 +55,8 @@
   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 @@
        * @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;
   }
   
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java
  
  Index: AbstractComponent.java
  ===================================================================
  /*
   * 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.2       +14 -5     jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java
  
  Index: BuildEvent.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- BuildEvent.java	2 Feb 2002 14:50:33 -0000	1.1
  +++ BuildEvent.java	5 Feb 2002 11:49:06 -0000	1.2
  @@ -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 @@
        * @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 @@
        * @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 @@
       /**
        * 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;
  @@ -167,6 +167,15 @@
        */
       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();
       }
   }
   
  
  
  
  1.2       +48 -3     jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildListener.java
  
  Index: BuildListener.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildListener.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- BuildListener.java	2 Feb 2002 14:50:33 -0000	1.1
  +++ BuildListener.java	5 Feb 2002 11:49:06 -0000	1.2
  @@ -65,10 +65,55 @@
    */
   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);
   }
   
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/model/BuildElement.java
  
  Index: BuildElement.java
  ===================================================================
  /*
   * 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.model;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  
  import org.apache.ant.common.util.Location;
  
  /**
   * A BuildElement is a holder configuration information for an element of
   * the build. BuildElements may be grouped into a hierarchy to capture any
   * level of element nesting.
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 20 January 2002
   */
  public class BuildElement extends ModelElement {
      /** The attributes of this build element */
      private Map attributes = new HashMap();
  
      /** The element's name or type  */
      private String type;
  
      /** The nested task elements that make up this task element.  */
      private List nestedElements = new ArrayList();
  
      /** The content (text) of this element */
      private String text = "";
  
      /**
       * Create a Build Element of the given type
       *
       * @param location the location of the element
       * @param type the element's type
       */
      public BuildElement(Location location, String type) {
          super(location);
          this.type = type;
      }
  
      /**
       * Get the text of this element
       *
       * @return the elements's text.
       */
      public String getText() {
          return text;
      }
  
      /**
       * Get an iterator over this element's nested elements
       *
       * @return an iterator which provides BuildElement instances
       */
      public Iterator getNestedElements() {
          return nestedElements.iterator();
      }
  
      /**
       * Get the type of this element
       *
       * @return the element's type
       */
      public String getType() {
          return type;
      }
  
      /**
       * Get an iterator over the elements's attributes
       *
       * @return an iterator which provide's attribute names
       */
      public Iterator getAttributeNames() {
          return attributes.keySet().iterator();
      }
  
      /**
       * Get the value of an attribute.
       *
       * @param attributeName the name of the attribute
       * @return the value of the attribute or null if there is no such
       *      attribute.
       */
      public String getAttributeValue(String attributeName) {
          return (String)attributes.get(attributeName);
      }
  
      /**
       * Add text to this element.
       *
       * @param text the element text to add.
       */
      public void addText(String text) {
          this.text += text;
      }
  
      /**
       * Add a nested element to this element
       *
       * @param nestedElement the build element to be added.
       */
      public void addNestedElement(BuildElement nestedElement) {
          nestedElements.add(nestedElement);
      }
  
      /**
       * Add an attribute to this element
       *
       * @param attributeName the name of the attribute
       * @param attributeValue the attribute's value.
       */
      public void addAttribute(String attributeName, String attributeValue) {
          attributes.put(attributeName, attributeValue);
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/model/ModelElement.java
  
  Index: ModelElement.java
  ===================================================================
  /*
   * 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.model;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.apache.ant.common.util.Location;
  
  /**
   * A ModelElement is an element of a build model. A location may be
   * associated with the model element for error reporting and debugging
   * purposes.
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 11 January 2002
   */
  public abstract class ModelElement {
      /** The aspects defined for this element. */
      private Map aspectMaps;
  
      /** The location of this element */
      private Location location;
  
      /** A comment associated with this element, if any */
      private String comment;
  
      /**
       * Create a model element giving its location.
       *
       * @param location identifies where this element is defined
       */
      public ModelElement(Location location) {
          this.location = location;
      }
  
      /**
       * Set a comment associated with this element
       *
       * @param comment the comment to be associated with this element.
       */
      public void setComment(String comment) {
          this.comment = comment;
      }
  
      /**
       * Set the aspects of this element
       *
       * @param aspects a Map of apects that relate to this model element.
       */
      public void setAspects(Map aspects) {
          aspectMaps = new HashMap();
          for (Iterator i = aspects.keySet().iterator(); i.hasNext(); ) {
              String aspectName = (String)i.next();
              int separator = aspectName.indexOf(":");
              if (separator != -1) {
                  String prefix = aspectName.substring(0, separator);
                  String name = aspectName.substring(separator + 1);
                  if (prefix.length() != 0 && name.length() != 0) {
                      Map prefixMap = (Map)aspectMaps.get(prefix);
                      if (prefixMap == null) {
                          prefixMap = new HashMap();
                          aspectMaps.put(prefix, prefixMap);
                      }
                      prefixMap.put(name, aspects.get(aspectName));
                  }
              }
          }
      }
  
      /**
       * Get the location of the source where this element is defined
       *
       * @return the element's location
       */
      public Location getLocation() {
          return location;
      }
  
      /**
       * Get the comment associated with this element.
       *
       * @return the element's comment which may be null.
       */
      public String getComment() {
          return comment;
      }
  
      /**
       * Get an iterator on the aspects which have been given values on this
       * element
       *
       * @return an iterator of Strings , being the aspects which have been
       *      given values on this element.
       */
      public Iterator getAspectNames() {
          return aspectMaps.keySet().iterator();
      }
  
      /**
       * Get the set of attribute values related to the given aspect
       *
       * @param aspectPrefix the aspect identifier
       * @return a map of the attribute values for the given aspect.
       */
      public Map getAspectAttributes(String aspectPrefix) {
          return (Map)aspectMaps.get(aspectPrefix);
      }
  
      /**
       * Get the value of a single aspect attribute
       *
       * @param aspectPrefix the prefix which identifies the aspectr
       * @param keyName the attribute name
       * @return the aspect value
       */
      public String getAspectValue(String aspectPrefix, String keyName) {
          Map aspectAttributes = getAspectAttributes(aspectPrefix);
          if (aspectAttributes == null) {
              return null;
          }
          return (String)aspectAttributes.get(keyName);
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/model/ModelException.java
  
  Index: ModelException.java
  ===================================================================
  /*
   * 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.model;
  
  import org.apache.ant.common.util.AntException;
  import org.apache.ant.common.util.Location;
  
  /**
   * A model exception is thrown when an operation is attempted which would
   * violate the integrity of the Project/Target/Task object model
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 16 January 2002
   */
  public class ModelException extends AntException {
      /**
       * Constructs an exception with the given descriptive message.
       *
       * @param msg Description of or information about the exception.
       */
      public ModelException(String msg) {
          super(msg);
      }
  
      /**
       * Constructs an exception with the given descriptive message and a
       * location in a file.
       *
       * @param msg Description of or information about the exception.
       * @param location Location in the project file where the error occured.
       */
      public ModelException(String msg, Location location) {
          super(msg, location);
      }
  
      /**
       * Constructs an exception with the given message and exception as a
       * root cause.
       *
       * @param msg Description of or information about the exception.
       * @param cause Throwable that might have cause this one.
       */
      public ModelException(String msg, Throwable cause) {
          super(msg, cause);
      }
  
      /**
       * Constructs an exception with the given message and exception as a
       * root cause and a location in a file.
       *
       * @param msg Description of or information about the exception.
       * @param cause Exception that might have cause this one.
       * @param location Location in the project file where the error occured.
       */
      public ModelException(String msg, Throwable cause,
                            Location location) {
          super(msg, cause, location);
      }
  
      /**
       * Constructs an exception with the given exception as a root cause.
       *
       * @param cause Exception that might have caused this one.
       */
      public ModelException(Throwable cause) {
          super(cause);
      }
  
      /**
       * Constructs an exception with the given exception as a root cause and
       * a location in a file.
       *
       * @param cause Exception that might have cause this one.
       * @param location Location in the project file where the error occured.
       */
      public ModelException(Throwable cause, Location location) {
          super(cause, location);
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/model/Project.java
  
  Index: Project.java
  ===================================================================
  /*
   * 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.model;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  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;
  
  /**
   * A project is a collection of targets and global tasks. A project may
   * reference objects in other projects using named references of the form
   * refname:object
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 9 January 2002
   */
  public class Project extends ModelElement {
      /**
       * The delimiter used to separate reference names in target names, data
       * values, etc
       */
      public final static String REF_DELIMITER = ":";
  
      /** The default target in this project. */
      private String defaultTarget = null;
  
      /**
       * The base URL of this project. Relative locations are relative to this
       * base.
       */
      private String base;
  
      /**
       * The name of this project when referenced by a script within this
       * project.
       */
      private String name;
  
      /**
       * These are the targets which belong to the project. They will have
       * interdependencies which are used to determine which targets need to
       * be executed before a given target.
       */
      private Map targets = new HashMap();
  
      /**
       * The global tasks for this project. These are the tasks that will get
       * executed whenever an execution context is associated with this
       * project.
       */
      private List tasks = new ArrayList();
  
      /**
       * The projects referenced into this project. Each referenced project is
       * given a name which is used to identify access to that project's
       * elements.
       */
      private Map referencedProjects = new HashMap();
  
      /** The URL where the project is defined. */
      private URL sourceURL;
  
  
      /**
       * Create a Project
       *
       * @param sourceURL the URL where the project is defined.
       * @param location the location of this element within the source.
       */
      public Project(URL sourceURL, Location location) {
          super(location);
          this.sourceURL = sourceURL;
      }
  
  
      /**
       * Set the defautl target of this project.
       *
       * @param defaultTarget the name of the defaultTarget of this project.
       */
      public void setDefaultTarget(String defaultTarget) {
          this.defaultTarget = defaultTarget;
      }
  
  
      /**
       * Set the base URL for this project.
       *
       * @param base the baseURL for this project.
       */
      public void setBase(String base) {
          this.base = base;
      }
  
  
      /**
       * Set the name of this project.
       *
       * @param name the name for this project.
       */
      public void setName(String name) {
          this.name = name;
      }
  
  
      /**
       * Get the URL where this project is defined
       *
       * @return the project source URL
       */
      public URL getSourceURL() {
          return sourceURL;
      }
  
  
      /**
       * Get the Project's default Target, if any
       *
       * @return the project's defautl target or null if there is no default.
       */
      public String getDefaultTarget() {
          return defaultTarget;
      }
  
  
      /**
       * Get the base URL for this project.
       *
       * @return the baseURL for this project as a string.
       */
      public String getBase() {
          return base;
      }
  
  
      /**
       * Get the targets in this project.
       *
       * @return an iterator returning Target objects.
       */
      public Iterator getTargets() {
          return targets.values().iterator();
      }
  
  
      /**
       * Get the target with the given name
       *
       * @param targetName the name of the desired target.
       * @return the target with the given name or null if there is no such
       *      target.
       */
      public Target getTarget(String targetName) {
          return (Target)targets.get(targetName);
      }
  
  
      /**
       * Get the names of the referenced projects.
       *
       * @return an iterator which returns the name sof the referenced
       *      projects.
       */
      public Iterator getReferencedProjectNames() {
          return referencedProjects.keySet().iterator();
      }
  
  
      /**
       * Get a referenced project by name
       *
       * @param alias the name under which the project was referenced.
       * @return the project asscociated with the given reference alias or
       *      null if there is no such project.
       */
      public Project getReferencedProject(String alias) {
          return (Project)referencedProjects.get(alias);
      }
  
  
      /**
       * Get the initialisation tasks for this project
       *
       * @return an iterator over the set of tasks for this project.
       */
      public Iterator getTasks() {
          return tasks.iterator();
      }
  
      /**
       * Get a target by its reference name - references may span multiple
       * references.
       *
       * @param fullTargetName The name of the target relative to this project
       * @return the Target object with the given name
       */
      public Target getRefTarget(String fullTargetName) {
          Project containingProject = getRefProject(fullTargetName);
          if (containingProject == this) {
              return getTarget(fullTargetName);
          }
  
          int index = fullTargetName.lastIndexOf(REF_DELIMITER);
          String targetName
               = fullTargetName.substring(index + REF_DELIMITER.length());
  
          return containingProject.getTarget(targetName);
      }
  
      /**
       * Get the project which directly contains the target specified by its
       * full name.
       *
       * @param fullTargetName the full name of the target for which the
       *      containing project is required.
       * @return The RefProject value
       */
      public Project getRefProject(String fullTargetName) {
          int index = fullTargetName.lastIndexOf(REF_DELIMITER);
          if (index == -1) {
              return this;
          }
  
          Project currentProject = this;
          String relativeName = fullTargetName.substring(0, index);
          StringTokenizer tokenizer
               = new StringTokenizer(relativeName, REF_DELIMITER);
          while (tokenizer.hasMoreTokens()) {
              String refName = tokenizer.nextToken();
              currentProject = currentProject.getReferencedProject(refName);
              if (currentProject == null) {
                  return null;
              }
          }
  
          return currentProject;
      }
  
      /**
       * get the list of dependent targets which must be evaluated for the
       * given target.
       *
       * @param fullTargetName the full name (in reference space) of the
       *      target
       * @return the flattened list of targets
       * @exception ConfigException if the given target could not be found
       */
      public List getTargetDependencies(String fullTargetName)
           throws ConfigException {
          try {
              List flattenedList = new ArrayList();
              flattenDependency(flattenedList, fullTargetName);
              flattenedList.add(fullTargetName);
              return flattenedList;
          } catch (ConfigException e) {
              throw new ConfigException(fullTargetName
                   + " does not exist in project");
          }
      }
  
  
      /**
       * Add a target to the project.
       *
       * @param target the Target to be added
       * @throws ModelException if a target with the same name already exists.
       */
      public void addTarget(Target target) throws ModelException {
          if (targets.containsKey(target.getName())) {
              throw new ModelException("A target with name '"
                   + target.getName() +
                  "' has already been defined in this project",
                  target.getLocation());
          }
          targets.put(target.getName(), target);
      }
  
  
      /**
       * Add a task to the list of global tasks for this project.
       *
       * @param task a task to be executed when an execution context is
       *      associated with the Project (a non-target task)
       */
      public void addTask(BuildElement task) {
          tasks.add(task);
      }
  
  
      /**
       * Reference a project using the given name.
       *
       * @param referenceName the name under which the project will be
       *      referenced.
       * @param project the referenced project.
       * @throws ModelException if an existing project has already been
       *      referenced with that name.
       */
      public void referenceProject(String referenceName, Project project)
           throws ModelException {
          if (referencedProjects.containsKey(referenceName)) {
              throw new ModelException("A project has already been "
                   + "introduced with name '" + referenceName + "'");
          }
          referencedProjects.put(referenceName, project);
      }
  
      /**
       * Validate this project
       *
       * @exception ModelException if the project is not valid
       */
      public void validate() throws ModelException {
          validate(null);
      }
  
      /**
       * Determine target dependency order within this porject and verify that
       * references to targets in other projects are valid
       *
       * @param globalName The global name of this project
       * @param target The target being examined
       * @param dependencyOrder The dependency order of targets
       * @param visited Set of targets in this project already visited.
       * @param checker A circular dependency checker
       * @exception ModelException if the dependencies of the project's
       *      targets are not valid.
       */
      public void fillinDependencyOrder(String globalName, Target target,
                                        List dependencyOrder, Set visited,
                                        CircularDependencyChecker checker)
           throws ModelException {
          if (visited.contains(target.getName())) {
              return;
          }
  
          try {
              String targetName = target.getName();
              String targetGlobalName = targetName;
              if (globalName != null) {
                  targetGlobalName = globalName + REF_DELIMITER + targetName;
              }
              checker.visitNode(targetGlobalName);
              for (Iterator i = target.getDependencies(); i.hasNext(); ) {
                  String dependency = (String)i.next();
                  boolean localTarget = (dependency.indexOf(REF_DELIMITER) == -1);
                  Target dependencyTarget
                       = localTarget ? getTarget(dependency)
                       : getRefTarget(dependency);
  
                  if (dependencyTarget == null) {
                      StringBuffer sb = new StringBuffer("Target '");
                      if (globalName != null) {
                          sb.append(globalName + REF_DELIMITER);
                      }
                      sb.append(dependency);
                      sb.append("' does not exist in this project. ");
                      throw new ModelException(new String(sb),
                          target.getLocation());
                  }
  
                  if (localTarget) {
                      // need to check the targets we depend on
                      fillinDependencyOrder(globalName, dependencyTarget,
                          dependencyOrder, visited, checker);
                  }
              }
  
              visited.add(targetName);
              checker.leaveNode(targetGlobalName);
              dependencyOrder.add(targetName);
          } catch (CircularDependencyException e) {
              throw new ModelException(e.getMessage(),
                  target.getLocation());
          }
      }
  
      /**
       * 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
       */
      private String getFullProjectName(String fullTargetName) {
          int index = fullTargetName.lastIndexOf(REF_DELIMITER);
          if (index == -1) {
              return null;
          }
  
          return fullTargetName.substring(0, index);
      }
  
      /**
       * Flatten the dependencies to the given target
       *
       * @param flattenedList the List of targets that must be executed before
       *      the given target
       * @param fullTargetName the fully qualified name of the target
       * @exception ConfigException if the given target does not exist in the
       *      project hierarchy
       */
      private void flattenDependency(List flattenedList, String fullTargetName)
           throws ConfigException {
          if (flattenedList.contains(fullTargetName)) {
              return;
          }
          String fullProjectName = getFullProjectName(fullTargetName);
          Target target = getRefTarget(fullTargetName);
          if (target == null) {
              throw new ConfigException("Target " + fullTargetName
                   + " does not exist");
          }
          for (Iterator i = target.getDependencies(); i.hasNext(); ) {
              String localDependencyName = (String)i.next();
              String fullDependencyName
                   = fullProjectName == null ? localDependencyName
                   : fullProjectName + REF_DELIMITER + localDependencyName;
              flattenDependency(flattenedList, fullDependencyName);
              flattenedList.add(fullDependencyName);
          }
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/model/Target.java
  
  Index: Target.java
  ===================================================================
  /*
   * 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.model;
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  
  import org.apache.ant.common.util.Location;
  
  /**
   * A Target is a collection of tasks. It may have dependencies on other
   * targets
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 12 January 2002
   */
  public class Target extends ModelElement {
      /** This target's dependencies on other targets, if any */
      private List dependencies = new ArrayList();
  
      /** This target's list of tasks */
      private List tasks = new ArrayList();
  
      /** The target's name. */
      private String name;
  
      /** The Target's description */
      private String description;
  
      /**
       * Construct the target, given its name
       *
       * @param location the location of the element
       * @param name the target's name.
       */
      public Target(Location location, String name) {
          super(location);
          this.name = name;
      }
  
      /**
       * Sets the Target's description
       *
       * @param description The new description value
       */
      public void setDescription(String description) {
          this.description = description;
      }
  
      /**
       * Get this target's name.
       *
       * @return the target's name.
       */
      public String getName() {
          return name;
      }
  
      /**
       * Gets the Target's description
       *
       * @return The description value
       */
      public String getDescription() {
          return description;
      }
  
  
      /**
       * Get this target's dependencies.
       *
       * @return an iterator over the target's dependencies.
       */
      public Iterator getDependencies() {
          return dependencies.iterator();
      }
  
      /**
       * Get the tasks for this target
       *
       * @return an iterator over the set of tasks for this target.
       */
      public Iterator getTasks() {
          return tasks.iterator();
      }
  
      /**
       * Add a task to this target
       *
       * @param task the task to be added to the target.
       */
      public void addTask(BuildElement task) {
          tasks.add(task);
      }
  
      /**
       * Add a dependency to this target
       *
       * @param dependency the name of a target upon which this target depends
       */
      public void addDependency(String dependency) {
          dependencies.add(dependency);
      }
  
      /**
       * Validate that this build element is configured correctly
       *
       * @exception ModelException if the element is invalid
       */
      public void validate() throws ModelException {
          if (name == null) {
              throw new ModelException("Target must have a name",
                  getLocation());
          }
      }
  }
  
  
  
  
  1.2       +36 -0     jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
  
  Index: ComponentService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -u -r1.1 -r1.2
  --- ComponentService.java	2 Feb 2002 14:50:33 -0000	1.1
  +++ ComponentService.java	5 Feb 2002 11:49:06 -0000	1.2
  @@ -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;
   
   /**
  @@ -79,6 +83,38 @@
        *      imported.
        */
       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;
   }
   
  
  
  
  1.3       +4 -3      jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java
  
  Index: DataService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -u -r1.2 -r1.3
  --- DataService.java	3 Feb 2002 12:52:58 -0000	1.2
  +++ DataService.java	5 Feb 2002 11:49:06 -0000	1.3
  @@ -133,7 +133,8 @@
        * 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();         
            
  
  
  
  1.3       +12 -9     jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/util/AntException.java
  
  Index: AntException.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/util/AntException.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -u -r1.2 -r1.3
  --- AntException.java	22 Jan 2002 23:03:14 -0000	1.2
  +++ AntException.java	5 Feb 2002 11:49:06 -0000	1.3
  @@ -105,7 +105,7 @@
        */
       public AntException(String msg, Throwable cause, Location location) {
           this(msg, cause);
  -        setLocation(location);
  +        setLocation(location, true);
       }
   
       /**
  @@ -127,7 +127,7 @@
        */
       public AntException(String msg, Location location) {
           super(msg);
  -        setLocation(location);
  +        setLocation(location, true);
       }
   
       /**
  @@ -139,19 +139,22 @@
        */
       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) {
  +    public void setLocation(Location newLocation, boolean override) {
  +        if (override || location == Location.UNKNOWN_LOCATION) {
  +            if (newLocation == null) {
               this.location = Location.UNKNOWN_LOCATION;
           } else {
  -            this.location = location;
  +                this.location = newLocation;
  +            }
           }
       }
   
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/util/CircularDependencyChecker.java
  
  Index: CircularDependencyChecker.java
  ===================================================================
  /*
   * 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.util;
  import java.util.Stack;
  
  /**
   * Checks for circular dependencies when visiting nodes of an object
   * hierarchy
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 14 January 2002
   */
  public class CircularDependencyChecker {
      /**
       * The activity being undertaken which checking for circular
       * redundancies. This is used for reporting exceptions
       */
      private String activity;
  
      /** The nodes which we are currently visiting */
      private Stack nodes = new Stack();
  
      /**
       * Constructor for the CircularDependencyChecker object
       *
       * @param activity the activity being undertaken
       */
      public CircularDependencyChecker(String activity) {
          this.activity = activity;
      }
  
      /**
       * Visit a Node to check its relationships to other nodes
       *
       * @param node an object which is being visited and analyzed
       * @exception CircularDependencyException if this node is alreay being
       *      visited.
       */
      public void visitNode(Object node) throws CircularDependencyException {
          if (nodes.contains(node)) {
              throw new CircularDependencyException(getDescription(node));
          }
          nodes.push(node);
      }
  
      /**
       * Complete the examination of the node and leave.
       *
       * @param node an object for which the examination of relationships has
       *      been completed
       * @exception CircularDependencyException if the given node was not
       *      expected.
       */
      public void leaveNode(Object node) throws CircularDependencyException {
          if (!nodes.pop().equals(node)) {
              throw new CircularDependencyException("Internal error: popped " +
                  "element was unexpected");
          }
      }
  
      /**
       * Gets the description of the circular dependency
       *
       * @param endNode the node which was revisited and where the circular
       *      dependency was detected
       * @return the description of the circular dependency
       */
      private String getDescription(Object endNode) {
          StringBuffer sb = new StringBuffer("Circular dependency while "
               + activity + ": ");
          sb.append(endNode);
          Object o = null;
          do {
              o = nodes.pop();
              sb.append(" <- ");
              sb.append(o.toString());
          } while (!(o.equals(endNode)));
  
          return new String(sb);
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/util/CircularDependencyException.java
  
  Index: CircularDependencyException.java
  ===================================================================
  /*
   * 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.util;
  
  /**
   * A CircularDependencyException indicates that a circular dependency has
   * been detected
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 9 January 2002
   */
  public class CircularDependencyException extends AntException {
      /**
       * Constructs an exception with the given descriptive message.
       *
       * @param msg Description of or information about the exception.
       */
      public CircularDependencyException(String msg) {
          super(msg);
      }
  
  
      /**
       * Constructs an exception with the given descriptive message and a
       * location in a file.
       *
       * @param msg Description of or information about the exception.
       * @param location Location in the project file where the error occured.
       */
      public CircularDependencyException(String msg, Location location) {
          super(msg, location);
      }
  
  
      /**
       * Constructs an exception with the given message and exception as a
       * root cause.
       *
       * @param msg Description of or information about the exception.
       * @param cause Throwable that might have cause this one.
       */
      public CircularDependencyException(String msg, Throwable cause) {
          super(msg, cause);
      }
  
  
      /**
       * Constructs an exception with the given message and exception as a
       * root cause and a location in a file.
       *
       * @param msg Description of or information about the exception.
       * @param cause Exception that might have cause this one.
       * @param location Location in the project file where the error occured.
       */
      public CircularDependencyException(String msg, Throwable cause,
                                         Location location) {
          super(msg, cause, location);
      }
  
  
      /**
       * Constructs an exception with the given exception as a root cause.
       *
       * @param cause Exception that might have caused this one.
       */
      public CircularDependencyException(Throwable cause) {
          super(cause);
      }
  
  
      /**
       * Constructs an exception with the given exception as a root cause and
       * a location in a file.
       *
       * @param cause Exception that might have cause this one.
       * @param location Location in the project file where the error occured.
       */
      public CircularDependencyException(Throwable cause, Location location) {
          super(cause, location);
      }
  
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/util/ConfigException.java
  
  Index: ConfigException.java
  ===================================================================
  /*
   * 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.util;
  
  /**
   * A ConfigException indicates a problem with Ant's configuration or the
   * commandline used to start Ant.
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 9 January 2002
   */
  public class ConfigException extends AntException {
      /**
       * Constructs an exception with the given descriptive message.
       *
       * @param msg Description of or information about the exception.
       */
      public ConfigException(String msg) {
          super(msg);
      }
  
  
      /**
       * Constructs an exception with the given descriptive message and a
       * location in a file.
       *
       * @param msg Description of or information about the exception.
       * @param location Location in the project file where the error occured.
       */
      public ConfigException(String msg, Location location) {
          super(msg, location);
      }
  
  
      /**
       * Constructs an exception with the given message and exception as a
       * root cause.
       *
       * @param msg Description of or information about the exception.
       * @param cause Throwable that might have cause this one.
       */
      public ConfigException(String msg, Throwable cause) {
          super(msg, cause);
      }
  
  
      /**
       * Constructs an exception with the given message and exception as a
       * root cause and a location in a file.
       *
       * @param msg Description of or information about the exception.
       * @param cause Exception that might have cause this one.
       * @param location Location in the project file where the error occured.
       */
      public ConfigException(String msg, Throwable cause, Location location) {
          super(msg, cause, location);
      }
  
  
      /**
       * Constructs an exception with the given exception as a root cause.
       *
       * @param cause Exception that might have caused this one.
       */
      public ConfigException(Throwable cause) {
          super(cause);
      }
  
  
      /**
       * Constructs an exception with the given exception as a root cause and
       * a location in a file.
       *
       * @param cause Exception that might have cause this one.
       * @param location Location in the project file where the error occured.
       */
      public ConfigException(Throwable cause, Location location) {
          super(cause, location);
      }
  
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/util/StringUtils.java
  
  Index: StringUtils.java
  ===================================================================
  /*
   *  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();
      }
  
  }
  
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>