Browse Source

Move all top level elements to an implicit target named "" and make

all othere targets depend on that one.

As a side effect, <description> is now handled by ProjectHelperImpl,
the data type has become unused.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@273116 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 23 years ago
parent
commit
706007fa7f
11 changed files with 160 additions and 175 deletions
  1. +5
    -0
      WHATSNEW
  2. +0
    -14
      build.xml
  3. +4
    -0
      src/etc/testcases/taskdefs/ant.xml
  4. +2
    -1
      src/main/org/apache/tools/ant/DefaultLogger.java
  5. +9
    -2
      src/main/org/apache/tools/ant/Main.java
  6. +1
    -1
      src/main/org/apache/tools/ant/Project.java
  7. +113
    -150
      src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java
  8. +8
    -1
      src/main/org/apache/tools/ant/taskdefs/Ant.java
  9. +2
    -2
      src/testcases/org/apache/tools/ant/TopLevelTaskTest.java
  10. +14
    -1
      src/testcases/org/apache/tools/ant/taskdefs/AntTest.java
  11. +2
    -3
      src/testcases/org/apache/tools/ant/taskdefs/TypedefTest.java

+ 5
- 0
WHATSNEW View File

@@ -1,6 +1,11 @@
Changes from Ant 1.5 to current CVS version
===========================================

Changes that could break older environments:
--------------------------------------------

* Targets cannot have the empty string as their name any longer.

Fixed bugs:
-----------



+ 0
- 14
build.xml View File

@@ -326,20 +326,6 @@
<include name="${ant.package}/types/AbstractFileSetTest*" />
</patternset>
<!--
===================================================================
Set up a patternsets that matches the parts of our JUnit testsuite
that may be useful for task developers.
===================================================================
-->
<patternset id="useful.tests">
<include name="${ant.package}/BuildFileTest*" />
<include name="${regexp.package}/RegexpMatcherTest*" />
<include name="${regexp.package}/RegexpTest*" />
<include name="${optional.package}/AbstractXSLTLiaisonTest*" />
<include name="${ant.package}/types/AbstractFileSetTest*" />
</patternset>

<!--
===================================================================
Check to see what optional dependencies are available


+ 4
- 0
src/etc/testcases/taskdefs/ant.xml View File

@@ -31,6 +31,10 @@
<antcall target=""/>
</target>

<target name="test4b">
<antcall target="does-not-exist"/>
</target>

<target name="test5">
<antcall target="dummy"/>
</target>


+ 2
- 1
src/main/org/apache/tools/ant/DefaultLogger.java View File

@@ -208,7 +208,8 @@ public class DefaultLogger implements BuildLogger {
* Must not be <code>null</code>.
*/
public void targetStarted(BuildEvent event) {
if (Project.MSG_INFO <= msgOutputLevel) {
if (Project.MSG_INFO <= msgOutputLevel
&& !event.getTarget().getName().equals("")) {
String msg = StringUtils.LINE_SEP
+ event.getTarget().getName() + ":";
printMessage(msg, out, event.getPriority());


+ 9
- 2
src/main/org/apache/tools/ant/Main.java View File

@@ -604,8 +604,12 @@ public class Main {
}

// make sure that we have a target to execute
if (targets.size() == 0 && project.getDefaultTarget() != null) {
targets.addElement(project.getDefaultTarget());
if (targets.size() == 0) {
if (project.getDefaultTarget() != null) {
targets.addElement(project.getDefaultTarget());
} else {
targets.addElement(""); // implicit target
}
}

project.executeTargets(targets);
@@ -845,6 +849,9 @@ public class Main {
while (ptargets.hasMoreElements()) {
currentTarget = (Target) ptargets.nextElement();
targetName = currentTarget.getName();
if (targetName.equals("")) {
continue;
}
targetDescription = currentTarget.getDescription();
// maintain a sorted list of targets
if (targetDescription == null) {


+ 1
- 1
src/main/org/apache/tools/ant/Project.java View File

@@ -1773,7 +1773,7 @@ public class Project {
// no warning, this is not changing anything
return;
}
if (old != null) {
if (old != null && !(old instanceof UnknownElement)) {
log("Overriding previous definition of reference to " + name,
MSG_WARN);
}


+ 113
- 150
src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java View File

@@ -108,6 +108,17 @@ public class ProjectHelperImpl extends ProjectHelper {
* Used for giving locations of errors etc.
*/
private Locator locator;
/**
* Target that all other targets will depend upon implicitly.
*
* <p>This holds all tasks and data type definitions that have
* been placed outside of targets.</p>
*/
private Target implicitTarget = new Target();

public ProjectHelperImpl() {
implicitTarget.setName("");
}

/**
* Parses the project file, configuring the project as it goes.
@@ -276,12 +287,6 @@ public class ProjectHelperImpl extends ProjectHelper {
}
}

/**
* Called when this element and all elements nested into it have been
* handled.
*/
protected void finished() {}

/**
* Handles the end of an element. Any required clean-up is performed
* by the finished() method and then the original handler is restored to
@@ -292,12 +297,8 @@ public class ProjectHelperImpl extends ProjectHelper {
*
* @exception SAXException in case of error (not thrown in
* this implementation)
*
* @see #finished()
*/
public void endElement(String name) throws SAXException {

finished();
// Let parent resume handling SAX events
helperImpl.parser.setDocumentHandler(parentHandler);
}
@@ -451,7 +452,7 @@ public class ProjectHelperImpl extends ProjectHelper {
}
}

if (def != null) {
if (def != null && !def.equals("")) {
helperImpl.project.setDefaultTarget(def);
}

@@ -461,7 +462,7 @@ public class ProjectHelperImpl extends ProjectHelper {
}

if (id != null) {
helperImpl.project.addReference(id, helperImpl.project);
helperImpl.project.addReference(id, helperImpl.project);
}

if (helperImpl.project.getProperty("basedir") != null) {
@@ -480,6 +481,7 @@ public class ProjectHelperImpl extends ProjectHelper {
}
}

helperImpl.project.addTarget("", helperImpl.implicitTarget);
}

/**
@@ -500,32 +502,12 @@ public class ProjectHelperImpl extends ProjectHelper {
public void startElement(String name, AttributeList attrs) throws SAXParseException {
if (name.equals("target")) {
handleTarget(name, attrs);
} else if (helperImpl.project.getDataTypeDefinitions().get(name) != null) {
handleDataType(name, attrs);
} else if (helperImpl.project.getTaskDefinitions().get(name) != null) {
handleTask(name, attrs);
} else {
throw new SAXParseException("Unexpected element \"" + name + "\"", helperImpl.locator);
handleElement(helperImpl, this, helperImpl.implicitTarget,
name, attrs);
}
}

/**
* Handles a task by creating a task handler and initialising
* is with the details of the element.
*
* @param name The name of the element to be handled.
* Will not be <code>null</code>.
* @param attrs Attributes of the element to be handled.
* Will not be <code>null</code>.
*
* @exception SAXParseException if an error occurs when initialising
* the task handler
*
*/
private void handleTask(String name, AttributeList attrs) throws SAXParseException {
(new TaskHandler(helperImpl, this, null, null, null)).init(name, attrs);
}

/**
* Handles a target defintion element by creating a target handler
* and initialising is with the details of the element.
@@ -541,21 +523,6 @@ public class ProjectHelperImpl extends ProjectHelper {
private void handleTarget(String tag, AttributeList attrs) throws SAXParseException {
new TargetHandler(helperImpl, this).init(tag, attrs);
}
/**
* Handles a data type defintion element by creating a data type
* handler and initialising is with the details of the element.
*
* @param name The name of the element to be handled.
* Will not be <code>null</code>.
* @param attrs Attributes of the element to be handled.
* Will not be <code>null</code>.
*
* @exception SAXParseException if an error occurs initialising
* the handler
*/
private void handleDataType(String name, AttributeList attrs) throws SAXParseException {
new DataTypeHandler(helperImpl, this).init(name, attrs);
}

}

@@ -607,6 +574,10 @@ public class ProjectHelperImpl extends ProjectHelper {

if (key.equals("name")) {
name = value;
if (name.equals("")) {
throw new BuildException("name attribute must not"
+ " be empty");
}
} else if (key.equals("depends")) {
depends = value;
} else if (key.equals("if")) {
@@ -628,6 +599,10 @@ public class ProjectHelperImpl extends ProjectHelper {
}

target = new Target();

// implicit target must be first on dependency list
target.addDependency("");

target.setName(name);
target.setIf(ifCond);
target.setUnless(unlessCond);
@@ -657,12 +632,70 @@ public class ProjectHelperImpl extends ProjectHelper {
* the appropriate child handler
*/
public void startElement(String name, AttributeList attrs) throws SAXParseException {
if (helperImpl.project.getDataTypeDefinitions().get(name) != null) {
new DataTypeHandler(helperImpl, this, target).init(name, attrs);
handleElement(helperImpl, this, target, name, attrs);
}
}

/**
* Start a new DataTypeHandler if element is known to be a
* data-type and a TaskHandler otherwise.
*
* <p>Factored out of TargetHandler.</p>
*
* @since Ant 1.6
*/
private static void handleElement(ProjectHelperImpl helperImpl,
DocumentHandler parent,
Target target, String elementName,
AttributeList attrs)
throws SAXParseException {
if (elementName.equals("description")) {
new DescriptionHandler(helperImpl, parent);
} else if (helperImpl.project.getDataTypeDefinitions()
.get(elementName) != null) {
new DataTypeHandler(helperImpl, parent, target)
.init(elementName, attrs);
} else {
new TaskHandler(helperImpl, parent, target, null, target)
.init(elementName, attrs);
}
}

/**
* Handler for "description" elements.
*/
static class DescriptionHandler extends AbstractHandler {

/**
* Constructor which just delegates to the superconstructor.
*
* @param parentHandler The handler which should be restored to the
* parser at the end of the element.
* Must not be <code>null</code>.
*/
public DescriptionHandler(ProjectHelperImpl helperImpl,
DocumentHandler parentHandler) {
super(helperImpl, parentHandler);
}

/**
* Adds the text as description to the project.
*
* @param buf A character array of the text within the element.
* Will not be <code>null</code>.
* @param start The start element in the array.
* @param count The number of characters to read from the array.
*/
public void characters(char[] buf, int start, int count) {
String text = new String(buf, start, count);
String currentDescription = helperImpl.project.getDescription();
if (currentDescription == null) {
helperImpl.project.setDescription(text);
} else {
new TaskHandler(helperImpl, this, target, null, target).init(name, attrs);
helperImpl.project.setDescription(currentDescription + text);
}
}

}

/**
@@ -701,18 +734,13 @@ public class ProjectHelperImpl extends ProjectHelper {
* Must not be <code>null</code>.
*
* @param container Container for the element.
* May be <code>null</code> if the target is
* <code>null</code> as well. If the
* target is <code>null</code>, this parameter
* is effectively ignored.
* Must not be <code>null</code>.
*
* @param parentWrapper Wrapper for the parent element, if any.
* May be <code>null</code>. If the
* target is <code>null</code>, this parameter
* is effectively ignored.
* May be <code>null</code>.
*
* @param target Target this element is part of.
* May be <code>null</code>.
* Must not be <code>null</code>.
*/
public TaskHandler(ProjectHelperImpl helperImpl, DocumentHandler parentHandler,
TaskContainer container, RuntimeConfigurable parentWrapper, Target target) {
@@ -757,35 +785,18 @@ public class ProjectHelperImpl extends ProjectHelper {
helperImpl.locator.getColumnNumber()));
helperImpl.configureId(task, attrs);

// Top level tasks don't have associated targets
if (target != null) {
task.setOwningTarget(target);
container.addTask(task);
task.init();
wrapper = task.getRuntimeConfigurableWrapper();
wrapper.setAttributes(attrs);
if (parentWrapper != null) {
parentWrapper.addChild(wrapper);
}
} else {
task.init();
configure(task, attrs, helperImpl.project);
}
}

/**
* Executes the task if it is a top-level one.
*/
protected void finished() {
if (task != null && target == null) {
task.execute();
task.setOwningTarget(target);
container.addTask(task);
task.init();
wrapper = task.getRuntimeConfigurableWrapper();
wrapper.setAttributes(attrs);
if (parentWrapper != null) {
parentWrapper.addChild(wrapper);
}
}

/**
* Adds text to the task, using the wrapper if one is
* available (in other words if the task is within a target)
* or using addText otherwise.
* Adds text to the task, using the wrapper.
*
* @param buf A character array of the text within the element.
* Will not be <code>null</code>.
@@ -793,19 +804,9 @@ public class ProjectHelperImpl extends ProjectHelper {
* @param count The number of characters to read from the array.
*
* @exception SAXParseException if the element doesn't support text
*
* @see ProjectHelper#addText(Project,Object,char[],int,int)
*/
public void characters(char[] buf, int start, int count) throws SAXParseException {
if (wrapper == null) {
try {
ProjectHelper.addText(helperImpl.project, task, buf, start, count);
} catch (BuildException exc) {
throw new SAXParseException(exc.getMessage(), helperImpl.locator, exc);
}
} else {
wrapper.addText(buf, start, count);
}
public void characters(char[] buf, int start, int count) {
wrapper.addText(buf, start, count);
}

/**
@@ -867,10 +868,10 @@ public class ProjectHelperImpl extends ProjectHelper {
* Must not be <code>null</code>.
*
* @param parentWrapper Wrapper for the parent element, if any.
* May be <code>null</code>.
* Must not be <code>null</code>.
*
* @param target Target this element is part of.
* May be <code>null</code>.
* Must not be <code>null</code>.
*/
public NestedElementHandler(ProjectHelperImpl helperImpl,
DocumentHandler parentHandler,
@@ -922,22 +923,16 @@ public class ProjectHelperImpl extends ProjectHelper {

helperImpl.configureId(child, attrs);

if (parentWrapper != null) {
childWrapper = new RuntimeConfigurable(child, propType);
childWrapper.setAttributes(attrs);
parentWrapper.addChild(childWrapper);
} else {
configure(child, attrs, helperImpl.project);
ih.storeElement(helperImpl.project, parent, child, elementName);
}
childWrapper = new RuntimeConfigurable(child, propType);
childWrapper.setAttributes(attrs);
parentWrapper.addChild(childWrapper);
} catch (BuildException exc) {
throw new SAXParseException(exc.getMessage(), helperImpl.locator, exc);
}
}

/**
* Adds text to the element, using the wrapper if one is
* available or using addText otherwise.
* Adds text to the element, using the wrapper.
*
* @param buf A character array of the text within the element.
* Will not be <code>null</code>.
@@ -945,19 +940,9 @@ public class ProjectHelperImpl extends ProjectHelper {
* @param count The number of characters to read from the array.
*
* @exception SAXParseException if the element doesn't support text
*
* @see ProjectHelper#addText(Project,Object,char[],int,int)
*/
public void characters(char[] buf, int start, int count) throws SAXParseException {
if (parentWrapper == null) {
try {
ProjectHelper.addText(helperImpl.project, child, buf, start, count);
} catch (BuildException exc) {
throw new SAXParseException(exc.getMessage(), helperImpl.locator, exc);
}
} else {
childWrapper.addText(buf, start, count);
}
public void characters(char[] buf, int start, int count) {
childWrapper.addText(buf, start, count);
}

/**
@@ -997,17 +982,6 @@ public class ProjectHelperImpl extends ProjectHelper {
/** Wrapper for this element, if it's part of a target. */
private RuntimeConfigurable wrapper = null;

/**
* Constructor with no target specified.
*
* @param parentHandler The handler which should be restored to the
* parser at the end of the element.
* Must not be <code>null</code>.
*/
public DataTypeHandler(ProjectHelperImpl helperImpl, DocumentHandler parentHandler) {
this(helperImpl, parentHandler, null);
}

/**
* Constructor with a target specified.
*
@@ -1016,7 +990,7 @@ public class ProjectHelperImpl extends ProjectHelper {
* Must not be <code>null</code>.
*
* @param target The parent target of this element.
* May be <code>null</code>.
* Must not be <code>null</code>.
*/
public DataTypeHandler(ProjectHelperImpl helperImpl, DocumentHandler parentHandler, Target target) {
super(helperImpl, parentHandler);
@@ -1046,23 +1020,16 @@ public class ProjectHelperImpl extends ProjectHelper {
throw new BuildException("Unknown data type " + propType);
}

if (target != null) {
wrapper = new RuntimeConfigurable(element, propType);
wrapper.setAttributes(attrs);
target.addDataType(wrapper);
} else {
configure(element, attrs, helperImpl.project);
helperImpl.configureId(element, attrs);
}
wrapper = new RuntimeConfigurable(element, propType);
wrapper.setAttributes(attrs);
target.addDataType(wrapper);
} catch (BuildException exc) {
throw new SAXParseException(exc.getMessage(), helperImpl.locator, exc);
}
}

// XXX: (Jon Skeet) Any reason why this doesn't use the wrapper
// if one is available, whereas NestedElementHandler.characters does?
/**
* Adds text to the element.
* Adds text to the using the wrapper.
*
* @param buf A character array of the text within the element.
* Will not be <code>null</code>.
@@ -1073,12 +1040,8 @@ public class ProjectHelperImpl extends ProjectHelper {
*
* @see ProjectHelper#addText(Project,Object,char[],int,int)
*/
public void characters(char[] buf, int start, int count) throws SAXParseException {
try {
ProjectHelper.addText(helperImpl.project, element, buf, start, count);
} catch (BuildException exc) {
throw new SAXParseException(exc.getMessage(), helperImpl.locator, exc);
}
public void characters(char[] buf, int start, int count) {
wrapper.addText(buf, start, count);
}

/**


+ 8
- 1
src/main/org/apache/tools/ant/taskdefs/Ant.java View File

@@ -360,7 +360,8 @@ public class Ant extends Task {
// the build file if this is a top level task)?
if (newProject.getBaseDir().equals(project.getBaseDir()) &&
newProject.getProperty("ant.file").equals(project.getProperty("ant.file"))
&& (getOwningTarget() == null ||
&& getOwningTarget() != null
&& (getOwningTarget().getName().equals("") ||
getOwningTarget().getName().equals(target))) {
throw new BuildException("ant task calling its own parent "
+ "target");
@@ -370,6 +371,8 @@ public class Ant extends Task {

if (target != null) {
newProject.executeTarget(target);
} else {
newProject.executeTarget("");
}
} finally {
// help the gc
@@ -518,6 +521,10 @@ public class Ant extends Task {
* Defaults to the new project's default target.
*/
public void setTarget(String s) {
if (s.equals("")) {
throw new BuildException("target attribute must not be empty");
}
this.target = s;
}



+ 2
- 2
src/testcases/org/apache/tools/ant/TopLevelTaskTest.java View File

@@ -68,12 +68,12 @@ public class TopLevelTaskTest extends BuildFileTest {

public void testNoTarget() {
configureProject("src/etc/testcases/core/topleveltasks/notarget.xml");
assertEquals("Called", getLog());
expectLog("", "Called");
}

public void testCalledFromTopLevelAnt() {
configureProject("src/etc/testcases/core/topleveltasks/toplevelant.xml");
assertEquals("Called", getLog());
expectLog("", "Called");
}

public void testCalledFromTargetLevelAnt() {


+ 14
- 1
src/testcases/org/apache/tools/ant/taskdefs/AntTest.java View File

@@ -99,7 +99,11 @@ public class AntTest extends BuildFileTest {
}

public void test4() {
expectBuildException("test4", "target doesn't exist");
expectBuildException("test4", "target attribute must not be empty");
}

public void test4b() {
expectBuildException("test4b", "target doesn't exist");
}

public void test5() {
@@ -308,6 +312,9 @@ public class AntTest extends BuildFileTest {
public void messageLogged(BuildEvent event) {}

public void targetStarted(BuildEvent event) {
if (event.getTarget().getName().equals("")) {
return;
}
if (error == null) {
try {
assertEquals(expectedBasedirs[calls++],
@@ -345,6 +352,9 @@ public class AntTest extends BuildFileTest {
public void messageLogged(BuildEvent event) {}

public void targetStarted(BuildEvent event) {
if (event.getTarget().getName().equals("")) {
return;
}
if (error == null) {
try {
String msg =
@@ -457,6 +467,9 @@ public class AntTest extends BuildFileTest {
public void messageLogged(BuildEvent event) {}

public void targetStarted(BuildEvent event) {
if (event.getTarget().getName().equals("")) {
return;
}
if (error == null) {
try {
assertEquals(expectedValues[calls++],


+ 2
- 3
src/testcases/org/apache/tools/ant/taskdefs/TypedefTest.java View File

@@ -1,7 +1,7 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* Copyright (c) 2001-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -97,8 +97,7 @@ public class TypedefTest extends BuildFileTest {
}

public void testLocal() {
expectLog("testLocal",
"Overriding previous definition of reference to local");
expectLog("testLocal", "");
Object ref = project.getReferences().get("local");
assertNotNull("ref is not null", ref);
assertEquals("org.example.types.TypedefTestType",


Loading…
Cancel
Save