git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@938315 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -38,6 +38,7 @@ Brant Langer Gurganus | |||
| Brian Curnow | |||
| Brian Deitte | |||
| Brian Felder | |||
| Brian Repko | |||
| Bruce Atherton | |||
| Cedomir Igaly | |||
| Charles Hudak | |||
| @@ -177,6 +177,10 @@ | |||
| <first>Brian</first> | |||
| <last>Felder</last> | |||
| </name> | |||
| <name> | |||
| <first>Brian</first> | |||
| <last>Repko</last> | |||
| </name> | |||
| <name> | |||
| <first>Bruce</first> | |||
| <last>Atherton</last> | |||
| @@ -431,6 +431,11 @@ | |||
| Ant runs into an infinite loop/throws an OutOfMemoryError | |||
| when I compile my project under Mac OS X. | |||
| </a></li> | |||
| <li><a href="#extension-point-and-import"> | |||
| <code>extension-point</code> doesn't work | |||
| with <code>import</code> like the documentation | |||
| states. | |||
| </a></li> | |||
| </ul> | |||
| @@ -2184,6 +2189,49 @@ mv /tmp/foo $ANT_HOME/bin/antRun | |||
| there is another symlink <code>bundle</code> that points to | |||
| the <code>Home</code> directory and will cause infite | |||
| recursions as well.</p> | |||
| <p class="faq"> | |||
| <a name="extension-point-and-import"></a> | |||
| <code>extension-point</code> doesn't work | |||
| with <code>import</code> like the documentation | |||
| states. | |||
| </p> | |||
| <p>Yes, there is | |||
| a <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=48804">bug | |||
| in Ant 1.8.0</a>.</p> | |||
| <p>When using two build files like</p> | |||
| <pre class="code"> | |||
| importing.xml: | |||
| <project> | |||
| ... | |||
| <import file="imported.xml"/> | |||
| <target name="bar" extensionOf="foo"/> | |||
| </project> | |||
| imported.xml: | |||
| <project> | |||
| <extension-point name="foo"/> | |||
| </project> | |||
| </pre> | |||
| <p>Ant 1.8.0 will fail, claiming there was no extension point | |||
| named "foo".</p> | |||
| <p>This bug has been fixed for Ant 1.8.1. For Ant 1.8.0 there | |||
| is | |||
| a <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=48804#c9">work-around</a>: | |||
| add an additional layer of importing like in</p> | |||
| <pre class="code"> | |||
| importing.xml: | |||
| <project> | |||
| <target name="bar" extensionOf="foo"/> | |||
| </project> | |||
| imported.xml: | |||
| <project> | |||
| <extension-point name="foo"/> | |||
| </project> | |||
| build.xml: | |||
| <project> | |||
| <import file="imported.xml"/> | |||
| <import file="importing.xml"/> | |||
| </project> | |||
| </pre> | |||
| </div> | |||
| </div> | |||
| @@ -19,6 +19,8 @@ package org.apache.tools.ant; | |||
| import java.io.File; | |||
| import java.util.Hashtable; | |||
| import java.util.LinkedList; | |||
| import java.util.List; | |||
| import java.util.Locale; | |||
| import java.util.Vector; | |||
| @@ -89,6 +91,7 @@ public class ProjectHelper { | |||
| // that read build files using ProjectHelper ). | |||
| private Vector importStack = new Vector(); | |||
| private List extensionStack = new LinkedList(); | |||
| /** | |||
| * Import stack. | |||
| @@ -101,6 +104,18 @@ public class ProjectHelper { | |||
| return importStack; | |||
| } | |||
| /** | |||
| * Extension stack. | |||
| * Used to keep track of targets that extend extension points. | |||
| * | |||
| * @return a list of two element string arrays where the first | |||
| * element is the name of the extensionpoint and the second the | |||
| * name of the target | |||
| */ | |||
| public List getExtensionStack() { | |||
| return extensionStack; | |||
| } | |||
| private final static ThreadLocal targetPrefix = new ThreadLocal() { | |||
| protected Object initialValue() { | |||
| return (String) null; | |||
| @@ -177,6 +177,28 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| parse(project, source, new RootHandler(context, mainHandler)); | |||
| // Execute the top-level target | |||
| context.getImplicitTarget().execute(); | |||
| // resolve extensionOf attributes | |||
| for (Iterator i = getExtensionStack().iterator(); i.hasNext(); ) { | |||
| String[] extensionInfo = (String[]) i.next(); | |||
| String tgName = extensionInfo[0]; | |||
| String name = extensionInfo[1]; | |||
| Hashtable projectTargets = project.getTargets(); | |||
| if (!projectTargets.containsKey(tgName)) { | |||
| throw new BuildException("can't add target " | |||
| + name + " to extension-point " | |||
| + tgName | |||
| + " because the extension-point" | |||
| + " is unknown."); | |||
| } | |||
| Target t = (Target) projectTargets.get(tgName); | |||
| if (!(t instanceof ExtensionPoint)) { | |||
| throw new BuildException("referenced target " | |||
| + tgName | |||
| + " is not an extension-point"); | |||
| } | |||
| t.addDependency(name); | |||
| } | |||
| } | |||
| } | |||
| @@ -987,6 +1009,9 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| project.addOrReplaceTarget(newName, newTarget); | |||
| } | |||
| if (extensionPoint != null) { | |||
| ProjectHelper helper = | |||
| (ProjectHelper) context.getProject(). | |||
| getReference(ProjectHelper.PROJECTHELPER_REFERENCE); | |||
| for (Iterator iter = | |||
| Target.parseDepends(extensionPoint, name, "extensionOf") | |||
| .iterator(); | |||
| @@ -995,20 +1020,12 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| if (isInIncludeMode()) { | |||
| tgName = prefix + sep + tgName; | |||
| } | |||
| if (!projectTargets.containsKey(tgName)) { | |||
| throw new BuildException("can't add target " | |||
| + name + " to extension-point " | |||
| + tgName | |||
| + " because the extension-point" | |||
| + " is unknown."); | |||
| } | |||
| Target t = (Target) projectTargets.get(tgName); | |||
| if (!(t instanceof ExtensionPoint)) { | |||
| throw new BuildException("referenced target " | |||
| + tgName | |||
| + " is not an extension-point"); | |||
| } | |||
| t.addDependency(name); | |||
| // defer extensionpoint resolution until the full | |||
| // import stack has been processed | |||
| helper.getExtensionStack().add(new String[] { | |||
| tgName, name | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -57,30 +57,35 @@ | |||
| <au:assertLogContains text="In target bar"/> | |||
| </target> | |||
| <target name="testExtensionPointMustBeKnown"> | |||
| <target name="testCantAddToPlainTarget"> | |||
| <mkdir dir="${output}"/> | |||
| <echo file="${output}/build.xml"><![CDATA[ | |||
| <project default="foo"> | |||
| <extension-point name="bar" extensionOf="foo"/> | |||
| <extension-point name="foo"/> | |||
| <target name="foo"/> | |||
| <target name="bar" extensionOf="foo"/> | |||
| </project>]]></echo> | |||
| <au:expectfailure | |||
| expectedMessage="can't add target bar to extension-point foo because the extension-point is unknown"> | |||
| expectedMessage="referenced target foo is not an extension-point"> | |||
| <ant dir="${output}"/> | |||
| </au:expectfailure> | |||
| </target> | |||
| <target name="testCantAddToPlainTarget"> | |||
| <target name="testExtensionPointInImportedBuildfile" description="Bug 48804"> | |||
| <mkdir dir="${output}"/> | |||
| <echo file="${output}/master.xml"><![CDATA[ | |||
| <project default="bar"> | |||
| <extension-point name="foo"/> | |||
| <target name="bar" depends="foo"/> | |||
| </project>]]></echo> | |||
| <echo file="${output}/build.xml"><![CDATA[ | |||
| <project default="foo"> | |||
| <target name="foo"/> | |||
| <target name="bar" extensionOf="foo"/> | |||
| <project> | |||
| <import file="master.xml"/> | |||
| <target name="prepare" extensionOf="foo"> | |||
| <echo>in target prepare</echo> | |||
| </target> | |||
| </project>]]></echo> | |||
| <au:expectfailure | |||
| expectedMessage="referenced target foo is not an extension-point"> | |||
| <ant dir="${output}"/> | |||
| </au:expectfailure> | |||
| <ant dir="${output}" target="bar"/> | |||
| <au:assertLogContains text="in target prepare"/> | |||
| </target> | |||
| </project> | |||
| @@ -1912,6 +1912,54 @@ mv /tmp/foo $ANT_HOME/bin/antRun | |||
| recursions as well.</p> | |||
| </answer> | |||
| </faq> | |||
| <faq id="extension-point-and-import"> | |||
| <question><code>extension-point</code> doesn't work | |||
| with <code>import</code> like the documentation | |||
| states.</question> | |||
| <answer> | |||
| <p>Yes, there is | |||
| a <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=48804">bug | |||
| in Ant 1.8.0</a>.</p> | |||
| <p>When using two build files like</p> | |||
| <source><![CDATA[ | |||
| importing.xml: | |||
| <project> | |||
| ... | |||
| <import file="imported.xml"/> | |||
| <target name="bar" extensionOf="foo"/> | |||
| </project> | |||
| imported.xml: | |||
| <project> | |||
| <extension-point name="foo"/> | |||
| </project> | |||
| ]]></source> | |||
| <p>Ant 1.8.0 will fail, claiming there was no extension point | |||
| named "foo".</p> | |||
| <p>This bug has been fixed for Ant 1.8.1. For Ant 1.8.0 there | |||
| is | |||
| a <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=48804#c9">work-around</a>: | |||
| add an additional layer of importing like in</p> | |||
| <source><![CDATA[ | |||
| importing.xml: | |||
| <project> | |||
| <target name="bar" extensionOf="foo"/> | |||
| </project> | |||
| imported.xml: | |||
| <project> | |||
| <extension-point name="foo"/> | |||
| </project> | |||
| build.xml: | |||
| <project> | |||
| <import file="imported.xml"/> | |||
| <import file="importing.xml"/> | |||
| </project> | |||
| ]]></source> | |||
| </answer> | |||
| </faq> | |||
| </faqsection> | |||
| </document> | |||