Browse Source

Make Projectref's dynamic and task based

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272494 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 23 years ago
parent
commit
c2f14ffad1
12 changed files with 368 additions and 501 deletions
  1. +39
    -4
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
  2. +100
    -38
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
  3. +2
    -13
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java
  4. +0
    -161
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/RefHandler.java
  5. +2
    -0
      proposal/mutant/src/java/antlibs/system/antlib.xml
  6. +18
    -8
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java
  7. +127
    -0
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java
  8. +1
    -1
      proposal/mutant/src/java/bootstrap/org/apache/ant/builder/BuildHelper.java
  9. +43
    -253
      proposal/mutant/src/java/common/org/apache/ant/common/model/Project.java
  10. +1
    -1
      proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
  11. +35
    -19
      proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java
  12. +0
    -3
      proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java

+ 39
- 4
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java View File

@@ -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. * 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 properties the initiali properties to be used in the build
* @param model XXX Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
* @exception ExecutionException if the subbuild cannot be run * @exception ExecutionException if the subbuild cannot be run
*/ */
/*
public Object setupBuild(File antFile, Map properties) public Object setupBuild(File antFile, Map properties)
throws ExecutionException { throws ExecutionException {
try { try {
@@ -213,7 +250,6 @@ public class CoreExecService implements ExecService {
XMLProjectParser parser = new XMLProjectParser(); XMLProjectParser parser = new XMLProjectParser();
Project project Project project
= parser.parseBuildFile(InitUtils.getFileURL(antFile)); = parser.parseBuildFile(InitUtils.getFileURL(antFile));

return setupBuild(project, properties); return setupBuild(project, properties);
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
throw new ExecutionException(e); throw new ExecutionException(e);
@@ -221,8 +257,7 @@ public class CoreExecService implements ExecService {
throw new ExecutionException(e); throw new ExecutionException(e);
} }
} }


*/
/** /**
* Setup a sub-build. * Setup a sub-build.
* *


+ 100
- 38
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java View File

@@ -56,9 +56,10 @@ import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.List;
import java.util.ArrayList;
import org.apache.ant.antcore.config.AntConfig; import org.apache.ant.antcore.config.AntConfig;
import org.apache.ant.common.antlib.Task; import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.event.BuildListener; 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.ExecService;
import org.apache.ant.common.service.FileService; import org.apache.ant.common.service.FileService;
import org.apache.ant.common.service.MagicProperties; 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.DemuxOutputReceiver;
import org.apache.ant.common.util.ExecutionException; import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.FileUtils; import org.apache.ant.common.util.FileUtils;
@@ -173,7 +173,8 @@ public class Frame implements DemuxOutputReceiver {
* @return the string with all property references replaced * @return the string with all property references replaced
* @exception ExecutionException if any of the properties do not exist * @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); return dataService.replacePropertyRefs(value);
} }


@@ -189,15 +190,6 @@ public class Frame implements DemuxOutputReceiver {
this.project = project; this.project = project;
referencedFrames = new HashMap(); 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(); configureServices();
componentManager.setStandardLibraries(standardLibs); componentManager.setStandardLibraries(standardLibs);
setMagicProperties(); setMagicProperties();
@@ -209,7 +201,7 @@ public class Frame implements DemuxOutputReceiver {
* *
* @return the project's name * @return the project's name
*/ */
public String getProjectName() {
protected String getProjectName() {
if (project != null) { if (project != null) {
return project.getName(); 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 * 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 * @exception ExecutionException if there is a problem in the build
*/ */
protected void runBuild(List targets) throws ExecutionException { protected void runBuild(List targets) throws ExecutionException {
determineBaseDirs();

initialize(); initialize();
if (targets.isEmpty()) { if (targets.isEmpty()) {
// we just execute the default target if any // 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 * 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 * of the target
*/ */
protected void executeTarget(String targetName) throws ExecutionException { protected void executeTarget(String targetName) throws ExecutionException {

// to execute a target we must determine its dependencies and // to execute a target we must determine its dependencies and
// execute them in order. // 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 * failed
*/ */
protected void initialize() throws ExecutionException { protected void initialize() throws ExecutionException {
for (Iterator i = getReferencedFrames(); i.hasNext();) {
Frame referencedFrame = (Frame) i.next();

referencedFrame.initialize();
}
determineBaseDir();


Iterator taskIterator = project.getTasks(); Iterator taskIterator = project.getTasks();


@@ -785,7 +853,7 @@ public class Frame implements DemuxOutputReceiver {
* @exception ExecutionException if the base directories cannot be * @exception ExecutionException if the base directories cannot be
* determined * determined
*/ */
private void determineBaseDirs() throws ExecutionException {
private void determineBaseDir() throws ExecutionException {
if (isDataValueSet(MagicProperties.BASEDIR)) { if (isDataValueSet(MagicProperties.BASEDIR)) {
baseDir baseDir
= new File(getDataValue(MagicProperties.BASEDIR).toString()); = new File(getDataValue(MagicProperties.BASEDIR).toString());
@@ -809,12 +877,6 @@ public class Frame implements DemuxOutputReceiver {
} }
} }
setDataValue(MagicProperties.BASEDIR, baseDir.getAbsolutePath(), true); setDataValue(MagicProperties.BASEDIR, baseDir.getAbsolutePath(), true);

for (Iterator i = getReferencedFrames(); i.hasNext();) {
Frame refFrame = (Frame) i.next();

refFrame.determineBaseDirs();
}
} }






+ 2
- 13
proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java View File

@@ -158,18 +158,7 @@ public class ProjectHandler extends ModelElementHandler {
Attributes attributes) Attributes attributes)
throws SAXParseException { 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 includeHandler = new IncludeHandler(project);
includeHandler.start(getParseContext(), getXMLReader(), includeHandler.start(getParseContext(), getXMLReader(),
this, getLocator(), attributes, getElementSource(), this, getLocator(), attributes, getElementSource(),
@@ -193,7 +182,7 @@ public class ProjectHandler extends ModelElementHandler {
project.addTask(buildElementHandler.getBuildElement()); project.addTask(buildElementHandler.getBuildElement());
} else { } else {
// ignore namespaced elements // ignore namespaced elements
throw new SAXParseException("Only the \"ant\" namespace is "
throw new SAXParseException("namespace support is not "
+ "currently recognized (" + qualifiedName + ")", getLocator()); + "currently recognized (" + qualifiedName + ")", getLocator());
} }
} }


+ 0
- 161
proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/RefHandler.java View File

@@ -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
* <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 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 <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);
}
}
}



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

@@ -7,6 +7,8 @@


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

<taskdef name="ref" classname="org.apache.ant.antlib.system.Ref"/>
<taskdef name="parallel" classname="org.apache.ant.antlib.system.Parallel"/> <taskdef name="parallel" classname="org.apache.ant.antlib.system.Parallel"/>
<taskdef name="sequential" classname="org.apache.ant.antlib.system.Sequential"/> <taskdef name="sequential" classname="org.apache.ant.antlib.system.Sequential"/>


+ 18
- 8
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java View File

@@ -53,8 +53,10 @@
*/ */
package org.apache.ant.antlib.system; package org.apache.ant.antlib.system;
import java.io.File; 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.service.MagicProperties;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.FileUtils; import org.apache.ant.common.util.FileUtils;


/** /**
@@ -71,6 +73,7 @@ public class Ant extends AntBase {
/** File to capture any output */ /** File to capture any output */
private File outputFile; private File outputFile;



/** /**
* sets the file containing the XML representation model to build * sets the file containing the XML representation model to build
* *
@@ -80,6 +83,7 @@ public class Ant extends AntBase {
this.antFileName = antFileName; this.antFileName = antFileName;
} }



/** /**
* Set the base directory for the execution of the build * Set the base directory for the execution of the build
* *
@@ -89,6 +93,7 @@ public class Ant extends AntBase {
this.baseDir = baseDir; this.baseDir = baseDir;
} }



/** /**
* The output file for capturing the build output * The output file for capturing the build output
* *
@@ -98,6 +103,7 @@ public class Ant extends AntBase {
this.outputFile = outputFile; this.outputFile = outputFile;
} }



/** /**
* Run the sub-build * Run the sub-build
* *
@@ -107,23 +113,27 @@ public class Ant extends AntBase {
if (baseDir == null) { if (baseDir == null) {
baseDir = getExecService().getBaseDir(); baseDir = getExecService().getBaseDir();
} }
File antFile = null; File antFile = null;

if (antFileName == null) { if (antFileName == null) {
antFile = new File(baseDir, "build.ant"); antFile = new File(baseDir, "build.ant");
if (!antFile.exists()) { if (!antFile.exists()) {
antFile = new File(baseDir, "build.xml"); antFile = new File(baseDir, "build.xml");
} }
} else { } else {
antFile
= FileUtils.newFileUtils().resolveFile(baseDir, antFileName);
antFile
= FileUtils.newFileUtils().resolveFile(baseDir, antFileName);
} }
setProperty(MagicProperties.BASEDIR, baseDir.getAbsolutePath()); 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); setSubBuildKey(key);
getExecService().runBuild(key, getTargets());
execService.runBuild(key, getTargets());
} }
} }



+ 127
- 0
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java View File

@@ -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
* <http://www.apache.org/>.
*/
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);
}
}


+ 1
- 1
proposal/mutant/src/java/bootstrap/org/apache/ant/builder/BuildHelper.java View File

@@ -202,7 +202,7 @@ public class BuildHelper {
args[index++] = "-classpath"; args[index++] = "-classpath";
args[index++] = path; args[index++] = path;
} }
for (Iterator i = javaFiles.iterator(); i.hasNext(); ) {
for (Iterator i = javaFiles.iterator(); i.hasNext();) {
args[index++] = ((File) i.next()).getPath(); args[index++] = ((File) i.next()).getPath();
} }




+ 43
- 253
proposal/mutant/src/java/common/org/apache/ant/common/model/Project.java View File

@@ -60,10 +60,8 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.StringTokenizer;
import org.apache.ant.common.util.CircularDependencyChecker; import org.apache.ant.common.util.CircularDependencyChecker;
import org.apache.ant.common.util.CircularDependencyException; import org.apache.ant.common.util.CircularDependencyException;
import org.apache.ant.common.util.ConfigException;
import org.apache.ant.common.util.Location; import org.apache.ant.common.util.Location;


/** /**
@@ -98,25 +96,17 @@ public class Project extends ModelElement {


/** /**
* These are the targets which belong to the project. They will have * 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(); private Map targets = new HashMap();


/** /**
* The global tasks for this project. These are the tasks that will get * 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(); 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. */ /** The URL where the project is defined. */
private URL sourceURL; private URL sourceURL;


@@ -192,6 +182,7 @@ public class Project extends ModelElement {
return base; return base;
} }



/** /**
* Get the name of the project element * Get the name of the project element
* *
@@ -200,7 +191,8 @@ public class Project extends ModelElement {
public String getName() { public String getName() {
return name; return name;
} }


/** /**
* Get the targets in this project. * 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 * Get the initialisation tasks for this project
* *
@@ -255,85 +224,6 @@ public class Project extends ModelElement {
return tasks.iterator(); 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. * Add a target to the project.
* *
@@ -361,47 +251,44 @@ public class Project extends ModelElement {
tasks.add(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 * Validate this project
* *
* @exception ModelException if the project is not valid * @exception ModelException if the project is not valid
*/ */
public void validate() throws ModelException { 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 target The target being examined
* @param dependencyOrder The dependency order of targets * @param dependencyOrder The dependency order of targets
* @param visited Set of targets in this project already visited. * @param visited Set of targets in this project already visited.
* @param checker A circular dependency checker * @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, List dependencyOrder, Set visited,
CircularDependencyChecker checker) CircularDependencyChecker checker)
throws ModelException { throws ModelException {
@@ -411,38 +298,31 @@ public class Project extends ModelElement {


try { try {
String targetName = target.getName(); 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();) { for (Iterator i = target.getDependencies(); i.hasNext();) {
String dependency = (String) i.next(); String dependency = (String) i.next();
boolean localTarget = (dependency.indexOf(REF_DELIMITER) == -1); 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 // need to check the targets we depend on
fillinDependencyOrder(globalName, dependencyTarget,
fillinDependencyOrder(dependencyTarget,
dependencyOrder, visited, checker); dependencyOrder, visited, checker);
} }
} }


visited.add(targetName); visited.add(targetName);
checker.leaveNode(targetGlobalName);
checker.leaveNode(targetName);
dependencyOrder.add(targetName); dependencyOrder.add(targetName);
} catch (CircularDependencyException e) { } catch (CircularDependencyException e) {
throw new ModelException(e.getMessage(), 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);
}
}
} }



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

@@ -147,7 +147,7 @@ public interface ComponentService {
void importLibrary(String libraryId) throws ExecutionException; 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 * @param relativeName the qualified name of the component relative to
* this execution frame * this execution frame


+ 35
- 19
proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java View File

@@ -67,56 +67,71 @@ import org.apache.ant.common.util.ExecutionException;
*/ */
public interface ExecService { 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; throws ExecutionException;



/** /**
* Setup a sub-build. * Setup a sub-build.
* *
* @param model the project model to be used for the build * @param model the project model to be used for the build
* @param properties the initiali properties to be used in 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 * @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) Object setupBuild(Project model, Map properties)
throws ExecutionException; throws ExecutionException;



/** /**
* Setup a sub-build using the current frame's project model * Setup a sub-build using the current frame's project model
* *
* @param properties the initiali properties to be used in 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 * @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) Object setupBuild(Map properties)
throws ExecutionException; throws ExecutionException;



/** /**
* Run a build which have been previously setup * Run a build which have been previously setup
* *
* @param buildKey the buildKey returned previously when the build was * @param buildKey the buildKey returned previously when the build was
* setup
* setup
* @param targets A list of targets to be run * @param targets A list of targets to be run
* @exception ExecutionException if the build cannot 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. * @exception ExecutionException if there is a problem in execution.
*/ */
void executeTask(Task task) throws ExecutionException; void executeTask(Task task) throws ExecutionException;


/** /**
* get the name of the project associated with this execution. * get the name of the project associated with this execution.
* *
@@ -124,23 +139,24 @@ public interface ExecService {
*/ */
String getProjectName(); String getProjectName();



/** /**
* Get the basedir for the current execution * Get the basedir for the current execution
* *
* @return the base directory for this execution of Ant * @return the base directory for this execution of Ant
*/ */
File getBaseDir(); File getBaseDir();


/** /**
* Handle subbuild output. * Handle subbuild output.
* *
* @param subbuildKey the core's key for managing the subbuild. * @param subbuildKey the core's key for managing the subbuild.
* @param line the content produce by the current thread. * @param line the content produce by the current thread.
* @param isErr true if this content is from the thread's error stream. * @param isErr true if this content is from the thread's error stream.
*
* @exception ExecutionException if the subbuild cannot be found. * @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;
} }



+ 0
- 3
proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java View File

@@ -53,7 +53,6 @@
*/ */
package org.apache.ant.cli; package org.apache.ant.cli;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
@@ -66,10 +65,8 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.ant.antcore.config.AntConfig; 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.execution.ExecutionManager;
import org.apache.ant.antcore.modelparser.XMLProjectParser; 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.antcore.xml.XMLParseException;
import org.apache.ant.common.event.BuildEvent; import org.apache.ant.common.event.BuildEvent;
import org.apache.ant.common.event.BuildListener; import org.apache.ant.common.event.BuildListener;


Loading…
Cancel
Save