diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
index 54f3434fa..a3200af42 100644
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
@@ -198,14 +198,51 @@ public class CoreExecService implements ExecService {
}
+ /**
+ * Parse an XML file into a build model.
+ *
+ * @param xmlBuildFile The file containing the XML build description.
+ * @return A Project model for the build.
+ * @exception ExecutionException if the build cannot be parsed
+ */
+ public Project parseXMLBuildFile(File xmlBuildFile)
+ throws ExecutionException {
+ try {
+ // Parse the build file into a project
+ XMLProjectParser parser = new XMLProjectParser();
+
+ return parser.parseBuildFile(InitUtils.getFileURL(xmlBuildFile));
+ } catch (MalformedURLException e) {
+ throw new ExecutionException(e);
+ } catch (XMLParseException e) {
+ throw new ExecutionException(e);
+ }
+ }
+
+
+ /**
+ * Create a project reference.
+ *
+ * @param referenceName the name under which the project will be
+ * referenced.
+ * @param model the project model.
+ * @exception ExecutionException if the project cannot be referenced.
+ */
+ public void createProjectReference(String referenceName, Project model)
+ throws ExecutionException {
+ frame.createProjectReference(referenceName, model);
+ }
+
+
/**
* Setup a sub-build.
*
- * @param antFile the file containing the XML description of the model
* @param properties the initiali properties to be used in the build
+ * @param model XXX Description of the Parameter
* @return Description of the Return Value
* @exception ExecutionException if the subbuild cannot be run
*/
+ /*
public Object setupBuild(File antFile, Map properties)
throws ExecutionException {
try {
@@ -213,7 +250,6 @@ public class CoreExecService implements ExecService {
XMLProjectParser parser = new XMLProjectParser();
Project project
= parser.parseBuildFile(InitUtils.getFileURL(antFile));
-
return setupBuild(project, properties);
} catch (MalformedURLException e) {
throw new ExecutionException(e);
@@ -221,8 +257,7 @@ public class CoreExecService implements ExecService {
throw new ExecutionException(e);
}
}
-
-
+*/
/**
* Setup a sub-build.
*
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
index 29ed6e912..1f4a75627 100644
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
@@ -56,9 +56,10 @@ import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
+import java.util.List;
+import java.util.ArrayList;
import org.apache.ant.antcore.config.AntConfig;
import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.event.BuildListener;
@@ -72,7 +73,6 @@ import org.apache.ant.common.service.EventService;
import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.service.FileService;
import org.apache.ant.common.service.MagicProperties;
-import org.apache.ant.common.util.ConfigException;
import org.apache.ant.common.util.DemuxOutputReceiver;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.FileUtils;
@@ -173,7 +173,8 @@ public class Frame implements DemuxOutputReceiver {
* @return the string with all property references replaced
* @exception ExecutionException if any of the properties do not exist
*/
- public String replacePropertyRefs(String value) throws ExecutionException {
+ protected String replacePropertyRefs(String value)
+ throws ExecutionException {
return dataService.replacePropertyRefs(value);
}
@@ -189,15 +190,6 @@ public class Frame implements DemuxOutputReceiver {
this.project = project;
referencedFrames = new HashMap();
- for (Iterator i = project.getReferencedProjectNames(); i.hasNext();) {
- String referenceName = (String) i.next();
- Project referencedProject
- = project.getReferencedProject(referenceName);
- Frame referencedFrame = createFrame(referencedProject);
-
- referencedFrames.put(referenceName, referencedFrame);
- }
-
configureServices();
componentManager.setStandardLibraries(standardLibs);
setMagicProperties();
@@ -209,7 +201,7 @@ public class Frame implements DemuxOutputReceiver {
*
* @return the project's name
*/
- public String getProjectName() {
+ protected String getProjectName() {
if (project != null) {
return project.getName();
}
@@ -547,6 +539,20 @@ public class Frame implements DemuxOutputReceiver {
}
}
+ /**
+ * Create a project reference.
+ *
+ * @param name the name under which the project will be
+ * referenced.
+ * @param project the project model.
+ * @exception ExecutionException if the project cannot be referenced.
+ */
+ protected void createProjectReference(String name, Project project)
+ throws ExecutionException {
+ Frame referencedFrame = createFrame(project);
+ referencedFrames.put(name, referencedFrame);
+ referencedFrame.initialize();
+ }
/**
* Create a new frame for a given project
@@ -618,8 +624,6 @@ public class Frame implements DemuxOutputReceiver {
* @exception ExecutionException if there is a problem in the build
*/
protected void runBuild(List targets) throws ExecutionException {
- determineBaseDirs();
-
initialize();
if (targets.isEmpty()) {
// we just execute the default target if any
@@ -641,6 +645,77 @@ public class Frame implements DemuxOutputReceiver {
}
+
+ /**
+ * 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(Project.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 ExecutionException if the given target does not exist in the
+ * project hierarchy
+ */
+ private void flattenDependency(List flattenedList, String fullTargetName)
+ throws ExecutionException {
+ if (flattenedList.contains(fullTargetName)) {
+ return;
+ }
+ String fullProjectName = getFullProjectName(fullTargetName);
+ Frame frame = getContainingFrame(fullTargetName);
+ String localTargetName = getNameInFrame(fullTargetName);
+ Target target = frame.getProject().getTarget(localTargetName);
+ if (target == null) {
+ throw new ExecutionException("Target " + fullTargetName
+ + " does not exist");
+ }
+ for (Iterator i = target.getDependencies(); i.hasNext();) {
+ String localDependencyName = (String) i.next();
+ String fullDependencyName = localDependencyName;
+ if (fullProjectName != null) {
+ fullDependencyName = fullProjectName + Project.REF_DELIMITER
+ + localDependencyName;
+ }
+ flattenDependency(flattenedList, fullDependencyName);
+ if (!flattenedList.contains(fullDependencyName)) {
+ flattenedList.add(fullDependencyName);
+ }
+ }
+ }
+
+ /**
+ * 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 ExecutionException if the given target could not be found
+ */
+ protected List getTargetDependencies(String fullTargetName)
+ throws ExecutionException {
+ List flattenedList = new ArrayList();
+ flattenDependency(flattenedList, fullTargetName);
+ flattenedList.add(fullTargetName);
+ return flattenedList;
+ }
+
+
/**
* Execute the tasks of a target in this frame with the given name
*
@@ -649,22 +724,19 @@ public class Frame implements DemuxOutputReceiver {
* of the target
*/
protected void executeTarget(String targetName) throws ExecutionException {
+
// to execute a target we must determine its dependencies and
// execute them in order.
- try {
- // firstly build a list of fully qualified target names to execute.
- List dependencyOrder = project.getTargetDependencies(targetName);
+ // firstly build a list of fully qualified target names to execute.
+ List dependencyOrder = getTargetDependencies(targetName);
- for (Iterator i = dependencyOrder.iterator(); i.hasNext();) {
- String fullTargetName = (String) i.next();
- Frame frame = getContainingFrame(fullTargetName);
- String localTargetName = getNameInFrame(fullTargetName);
+ for (Iterator i = dependencyOrder.iterator(); i.hasNext();) {
+ String fullTargetName = (String) i.next();
+ Frame frame = getContainingFrame(fullTargetName);
+ String localTargetName = getNameInFrame(fullTargetName);
- frame.executeTargetTasks(localTargetName);
- }
- } catch (ConfigException e) {
- throw new ExecutionException(e);
+ frame.executeTargetTasks(localTargetName);
}
}
@@ -767,11 +839,7 @@ public class Frame implements DemuxOutputReceiver {
* failed
*/
protected void initialize() throws ExecutionException {
- for (Iterator i = getReferencedFrames(); i.hasNext();) {
- Frame referencedFrame = (Frame) i.next();
-
- referencedFrame.initialize();
- }
+ determineBaseDir();
Iterator taskIterator = project.getTasks();
@@ -785,7 +853,7 @@ public class Frame implements DemuxOutputReceiver {
* @exception ExecutionException if the base directories cannot be
* determined
*/
- private void determineBaseDirs() throws ExecutionException {
+ private void determineBaseDir() throws ExecutionException {
if (isDataValueSet(MagicProperties.BASEDIR)) {
baseDir
= new File(getDataValue(MagicProperties.BASEDIR).toString());
@@ -809,12 +877,6 @@ public class Frame implements DemuxOutputReceiver {
}
}
setDataValue(MagicProperties.BASEDIR, baseDir.getAbsolutePath(), true);
-
- for (Iterator i = getReferencedFrames(); i.hasNext();) {
- Frame refFrame = (Frame) i.next();
-
- refFrame.determineBaseDirs();
- }
}
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java
index 1addd9b41..e30b55a28 100644
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java
@@ -158,18 +158,7 @@ public class ProjectHandler extends ModelElementHandler {
Attributes attributes)
throws SAXParseException {
- if (qualifiedName.equals(REF_ELEMENT)) {
- 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_ELEMENT)) {
+ if (qualifiedName.equals(INCLUDE_ELEMENT)) {
IncludeHandler includeHandler = new IncludeHandler(project);
includeHandler.start(getParseContext(), getXMLReader(),
this, getLocator(), attributes, getElementSource(),
@@ -193,7 +182,7 @@ public class ProjectHandler extends ModelElementHandler {
project.addTask(buildElementHandler.getBuildElement());
} else {
// ignore namespaced elements
- throw new SAXParseException("Only the \"ant\" namespace is "
+ throw new SAXParseException("namespace support is not "
+ "currently recognized (" + qualifiedName + ")", getLocator());
}
}
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/RefHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/RefHandler.java
deleted file mode 100644
index 111016181..000000000
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/RefHandler.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * 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
- * .
- */
-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 Conor MacNeill
- * @created 10 January 2002
- */
-public class RefHandler extends ElementHandler {
- /** The attribute used to name the ref. */
- public static final String NAME_ATTR = "name";
-
- /** The attribute name used to locate the project to be referenced. */
- public static final 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 [ element", getLocator());
- }
-
- String projectSystemId = getAttribute(SYSTEMID_ATTR);
- if (projectSystemId == null) {
- throw new SAXParseException("Attribute " + SYSTEMID_ATTR +
- " is required in a ][ 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);
- }
- }
-}
-
-
diff --git a/proposal/mutant/src/java/antlibs/system/antlib.xml b/proposal/mutant/src/java/antlibs/system/antlib.xml
index ab38325ea..21424666e 100644
--- a/proposal/mutant/src/java/antlibs/system/antlib.xml
+++ b/proposal/mutant/src/java/antlibs/system/antlib.xml
@@ -7,6 +7,8 @@
+
+
diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java
index 1bd45fd16..09ee90db6 100644
--- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java
+++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java
@@ -53,8 +53,10 @@
*/
package org.apache.ant.antlib.system;
import java.io.File;
-import org.apache.ant.common.util.ExecutionException;
+import org.apache.ant.common.model.Project;
+import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.service.MagicProperties;
+import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.FileUtils;
/**
@@ -71,6 +73,7 @@ public class Ant extends AntBase {
/** File to capture any output */
private File outputFile;
+
/**
* sets the file containing the XML representation model to build
*
@@ -80,6 +83,7 @@ public class Ant extends AntBase {
this.antFileName = antFileName;
}
+
/**
* Set the base directory for the execution of the build
*
@@ -89,6 +93,7 @@ public class Ant extends AntBase {
this.baseDir = baseDir;
}
+
/**
* The output file for capturing the build output
*
@@ -98,6 +103,7 @@ public class Ant extends AntBase {
this.outputFile = outputFile;
}
+
/**
* Run the sub-build
*
@@ -107,23 +113,27 @@ public class Ant extends AntBase {
if (baseDir == null) {
baseDir = getExecService().getBaseDir();
}
-
+
File antFile = null;
+
if (antFileName == null) {
antFile = new File(baseDir, "build.ant");
if (!antFile.exists()) {
antFile = new File(baseDir, "build.xml");
}
} else {
- antFile
- = FileUtils.newFileUtils().resolveFile(baseDir, antFileName);
+ antFile
+ = FileUtils.newFileUtils().resolveFile(baseDir, antFileName);
}
-
+
setProperty(MagicProperties.BASEDIR, baseDir.getAbsolutePath());
-
- Object key = getExecService().setupBuild(antFile, getProperties());
+
+ ExecService execService = getExecService();
+ Project model = execService.parseXMLBuildFile(antFile);
+ Object key = execService.setupBuild(model, getProperties());
+
setSubBuildKey(key);
- getExecService().runBuild(key, getTargets());
+ execService.runBuild(key, getTargets());
}
}
diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java
new file mode 100644
index 000000000..053a29a9e
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java
@@ -0,0 +1,127 @@
+/*
+ * 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
+ * .
+ */
+package org.apache.ant.antlib.system;
+import java.io.File;
+import org.apache.ant.common.antlib.AbstractTask;
+import org.apache.ant.common.antlib.AntContext;
+import org.apache.ant.common.model.Project;
+import org.apache.ant.common.service.ExecService;
+import org.apache.ant.common.util.ExecutionException;
+
+/**
+ * A Task to create a project reference.
+ *
+ * @author Conor MacNeill
+ * @created 17 April 2002
+ */
+public class Ref extends AbstractTask {
+
+ /** The project file containing the project to be referenced. */
+ private File projectFile;
+
+ /** THe name under which this project is to be referenced. */
+ private String name;
+
+ /** The core's ExecutionService for running builds and external programs */
+ private ExecService execService;
+
+
+ /**
+ * Initialise this task
+ *
+ * @param context core's context
+ * @param componentType the component type of this component (i.e its
+ * defined name in the build file)
+ * @exception ExecutionException if we can't access the data service
+ */
+ public void init(AntContext context, String componentType)
+ throws ExecutionException {
+ super.init(context, componentType);
+ execService = (ExecService) getCoreService(ExecService.class);
+ }
+
+
+ /**
+ * Sets the file containing the XML representation model of the referenced
+ * project
+ *
+ * @param projectFile the file to build
+ */
+ public void setProject(File projectFile) {
+ this.projectFile = projectFile;
+ }
+
+
+ /**
+ * Set the name under which the project will be referenced
+ *
+ * @param name the reference label
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+ /**
+ * Create the project reference
+ *
+ * @exception ExecutionException if the project cannot be referenced.
+ */
+ public void execute() throws ExecutionException {
+ Project model = execService.parseXMLBuildFile(projectFile);
+
+ execService.createProjectReference(name, model);
+ }
+}
+
diff --git a/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/BuildHelper.java b/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/BuildHelper.java
index 5131ddada..673669b32 100644
--- a/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/BuildHelper.java
+++ b/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/BuildHelper.java
@@ -202,7 +202,7 @@ public class BuildHelper {
args[index++] = "-classpath";
args[index++] = path;
}
- for (Iterator i = javaFiles.iterator(); i.hasNext(); ) {
+ for (Iterator i = javaFiles.iterator(); i.hasNext();) {
args[index++] = ((File) i.next()).getPath();
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/model/Project.java b/proposal/mutant/src/java/common/org/apache/ant/common/model/Project.java
index ac0a8a9e9..8646374ae 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/model/Project.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/model/Project.java
@@ -60,10 +60,8 @@ 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;
/**
@@ -98,25 +96,17 @@ public class Project extends ModelElement {
/**
* 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.
+ * 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.
+ * 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;
@@ -192,6 +182,7 @@ public class Project extends ModelElement {
return base;
}
+
/**
* Get the name of the project element
*
@@ -200,7 +191,8 @@ public class Project extends ModelElement {
public String getName() {
return name;
}
-
+
+
/**
* Get the targets in this project.
*
@@ -223,29 +215,6 @@ public class Project extends ModelElement {
}
- /**
- * 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
*
@@ -255,85 +224,6 @@ public class Project extends ModelElement {
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
- * @exception ModelException if the given target does not exist in this
- * project
- */
- public Target getRefTarget(String fullTargetName) throws ModelException {
- Project containingProject = getRefProject(fullTargetName);
- if (containingProject == null) {
- throw new ModelException("The target name \"" + fullTargetName
- + "\" does not exist in this project");
- }
-
- 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.
*
@@ -361,47 +251,44 @@ public class Project extends ModelElement {
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);
+ // 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(target, dependencyOrder,
+ visited, checker);
+ }
}
+
/**
- * Determine target dependency order within this porject and verify that
- * references to targets in other projects are valid
+ * Determine target dependency order within this project.
*
- * @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.
+ * @exception ModelException if the dependencies of the project's targets
+ * are not valid.
*/
- public void fillinDependencyOrder(String globalName, Target target,
+ public void fillinDependencyOrder(Target target,
List dependencyOrder, Set visited,
CircularDependencyChecker checker)
throws ModelException {
@@ -411,38 +298,31 @@ public class Project extends ModelElement {
try {
String targetName = target.getName();
- String targetGlobalName = targetName;
- if (globalName != null) {
- targetGlobalName = globalName + REF_DELIMITER + targetName;
- }
- checker.visitNode(targetGlobalName);
+ checker.visitNode(targetName);
+
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);
+ if (localTarget) {
+ Target dependencyTarget = getTarget(dependency);
+
+ if (dependencyTarget == null) {
+ StringBuffer sb = new StringBuffer("Target '");
+
+ sb.append(dependency);
+ sb.append("' does not exist in this project. ");
+ throw new ModelException(new String(sb),
+ target.getLocation());
}
- 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,
+ fillinDependencyOrder(dependencyTarget,
dependencyOrder, visited, checker);
}
}
visited.add(targetName);
- checker.leaveNode(targetGlobalName);
+ checker.leaveNode(targetName);
dependencyOrder.add(targetName);
} catch (CircularDependencyException e) {
throw new ModelException(e.getMessage(),
@@ -450,95 +330,5 @@ public class Project extends ModelElement {
}
}
- /**
- * 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;
- }
- try {
- 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);
- if (!flattenedList.contains(fullDependencyName)) {
- flattenedList.add(fullDependencyName);
- }
- }
- } catch (ModelException e) {
- throw new ConfigException(e);
- }
- }
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
index e46fa248c..35f997e6f 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
@@ -147,7 +147,7 @@ public interface ComponentService {
void importLibrary(String libraryId) throws ExecutionException;
/**
- * Imports a component defined in a nother frame.
+ * Imports a component defined in another frame.
*
* @param relativeName the qualified name of the component relative to
* this execution frame
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java
index a4deb6279..1621ef943 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java
@@ -67,56 +67,71 @@ import org.apache.ant.common.util.ExecutionException;
*/
public interface ExecService {
/**
- * Setup a sub-build.
+ * Parse an XML file into a build model.
*
- * @param antFile the file containing the XML description of the model
- * @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be setup
- * @return a key to the build allowing it to be executed and managed
+ * @param xmlBuildFile The file containing the XML build description.
+ * @return A Project model for the build.
+ * @exception ExecutionException if the build cannot be parsed
*/
- Object setupBuild(File antFile, Map properties)
+ Project parseXMLBuildFile(File xmlBuildFile) throws ExecutionException;
+
+
+ /**
+ * Create a project reference.
+ *
+ * @param referenceName the name under which the project will be
+ * referenced.
+ * @param model the project model.
+ * @exception ExecutionException if the project cannot be referenced.
+ */
+ void createProjectReference(String referenceName, Project model)
throws ExecutionException;
+
/**
* Setup a sub-build.
*
* @param model the project model to be used for the build
* @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be setup
* @return a key to the build allowing it to be executed and managed
+ * @exception ExecutionException if the subbuild cannot be setup
*/
Object setupBuild(Project model, Map properties)
throws ExecutionException;
+
/**
* Setup a sub-build using the current frame's project model
*
* @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be setup
* @return a key to the build allowing it to be executed and managed
+ * @exception ExecutionException if the subbuild cannot be setup
*/
Object setupBuild(Map properties)
throws ExecutionException;
+
/**
* Run a build which have been previously setup
*
* @param buildKey the buildKey returned previously when the build was
- * setup
+ * setup
* @param targets A list of targets to be run
* @exception ExecutionException if the build cannot be run
*/
- void runBuild(Object buildKey, List targets) throws ExecutionException;
-
+ void runBuild(Object buildKey, List targets) throws ExecutionException;
+
+
/**
- * execute a task. The task should have already been initialised by
- * the core
+ * execute a task. The task should have already been initialised by the
+ * core
*
- * @param task the task to be executed.
+ * @param task the task to be executed.
* @exception ExecutionException if there is a problem in execution.
*/
void executeTask(Task task) throws ExecutionException;
-
+
+
/**
* get the name of the project associated with this execution.
*
@@ -124,23 +139,24 @@ public interface ExecService {
*/
String getProjectName();
+
/**
* Get the basedir for the current execution
*
* @return the base directory for this execution of Ant
*/
File getBaseDir();
-
+
+
/**
* Handle subbuild output.
*
* @param subbuildKey the core's key for managing the subbuild.
* @param line the content produce by the current thread.
* @param isErr true if this content is from the thread's error stream.
- *
* @exception ExecutionException if the subbuild cannot be found.
*/
- void handleBuildOutput(Object subbuildKey, String line, boolean isErr)
- throws ExecutionException;
+ void handleBuildOutput(Object subbuildKey, String line, boolean isErr)
+ throws ExecutionException;
}
diff --git a/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java b/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java
index dd5c1a7d1..ca11830f7 100755
--- a/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java
+++ b/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java
@@ -53,7 +53,6 @@
*/
package org.apache.ant.cli;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
@@ -66,10 +65,8 @@ 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.modelparser.XMLProjectParser;
-import org.apache.ant.antcore.xml.ParseContext;
import org.apache.ant.antcore.xml.XMLParseException;
import org.apache.ant.common.event.BuildEvent;
import org.apache.ant.common.event.BuildListener;
]