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> |