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;