Allows deferred execution to work - for example ant script in macro def. Bugzilla report : 23029 from Yannick Menager git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275209 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -0,0 +1,10 @@ | |||
| <?xml version="1.0"?> | |||
| <antlib xmlns:c="ant:current"> | |||
| <typedef name="echo2" classname="org.apache.tools.ant.taskdefs.Echo"/> | |||
| <c:echo2>Echo2 called</c:echo2> | |||
| <macrodef name="useecho2"> | |||
| <sequential> | |||
| <c:echo2>Echo2 inside a macro</c:echo2> | |||
| </sequential> | |||
| </macrodef> | |||
| </antlib> | |||
| @@ -14,4 +14,8 @@ | |||
| <mytask/> | |||
| </target> | |||
| <target name="ns.current"> | |||
| <typedef file="antlib.current-test.xml" uri="abc"/> | |||
| <x:useecho2 xmlns:x="abc"/> | |||
| </target> | |||
| </project> | |||
| @@ -111,8 +111,8 @@ public class ComponentHelper { | |||
| * processing antlib | |||
| */ | |||
| private Stack antLibStack = new Stack(); | |||
| /** current antlib context */ | |||
| private AntTypeTable antLibCurrentTypeTable = null; | |||
| /** current antlib uri */ | |||
| private String antLibCurrentUri = null; | |||
| /** | |||
| * Map from task names to vectors of created tasks | |||
| @@ -268,14 +268,7 @@ public class ComponentHelper { | |||
| public AntTypeDefinition getDefinition(String componentName) { | |||
| checkNamespace(componentName); | |||
| AntTypeDefinition ret = null; | |||
| if (antLibCurrentTypeTable != null | |||
| && ProjectHelper.ANT_CURRENT_URI.equals( | |||
| ProjectHelper.extractUriFromComponentName(componentName))) { | |||
| ret = antLibCurrentTypeTable.getDefinition(componentName); | |||
| } | |||
| if (ret == null) { | |||
| ret = antTypeTable.getDefinition(componentName); | |||
| } | |||
| ret = antTypeTable.getDefinition(componentName); | |||
| return ret; | |||
| } | |||
| @@ -690,22 +683,23 @@ public class ComponentHelper { | |||
| project.log(" +Datatype " + name + " " + def.getClassName(), | |||
| Project.MSG_DEBUG); | |||
| antTypeTable.put(name, def); | |||
| if (antLibCurrentTypeTable != null && name.lastIndexOf(':') != -1) { | |||
| String baseName = name.substring(name.lastIndexOf(':') + 1); | |||
| antLibCurrentTypeTable.put( | |||
| ProjectHelper.genComponentName( | |||
| ProjectHelper.ANT_CURRENT_URI, baseName), def); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Called at the start of processing an antlib | |||
| * @param uri the uri that is associated with this antlib | |||
| */ | |||
| public void enterAntLib(String uri) { | |||
| antLibCurrentUri = uri; | |||
| antLibStack.push(uri); | |||
| } | |||
| /** | |||
| * @return the current antlib uri | |||
| */ | |||
| public void enterAntLib() { | |||
| antLibCurrentTypeTable = new AntTypeTable(project); | |||
| antLibStack.push(antLibCurrentTypeTable); | |||
| public String getCurrentAntlibUri() { | |||
| return antLibCurrentUri; | |||
| } | |||
| /** | |||
| @@ -714,9 +708,9 @@ public class ComponentHelper { | |||
| public void exitAntLib() { | |||
| antLibStack.pop(); | |||
| if (antLibStack.size() != 0) { | |||
| antLibCurrentTypeTable = (AntTypeTable) antLibStack.peek(); | |||
| antLibCurrentUri = (String) antLibStack.peek(); | |||
| } else { | |||
| antLibCurrentTypeTable = null; | |||
| antLibCurrentUri = null; | |||
| } | |||
| } | |||
| @@ -125,12 +125,20 @@ public class UnknownElement extends Task { | |||
| return namespace; | |||
| } | |||
| /** Set the namespace of the XML element associated with this component. | |||
| /** | |||
| * Set the namespace of the XML element associated with this component. | |||
| * This method is typically called by the XML processor. | |||
| * If the namespace is "ant:current", the component helper | |||
| * is used to get the current antlib uri. | |||
| * | |||
| * @param namespace URI used in the xmlns declaration. | |||
| */ | |||
| public void setNamespace(String namespace) { | |||
| if (namespace.equals(ProjectHelper.ANT_CURRENT_URI)) { | |||
| ComponentHelper helper = ComponentHelper.getComponentHelper( | |||
| getProject()); | |||
| namespace = helper.getCurrentAntlibUri(); | |||
| } | |||
| this.namespace = namespace; | |||
| } | |||
| @@ -926,8 +926,8 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| /* UnknownElement is used for tasks and data types - with | |||
| delayed eval */ | |||
| UnknownElement task = new UnknownElement(tag); | |||
| task.setNamespace(uri); | |||
| task.setProject(context.getProject()); | |||
| task.setNamespace(uri); | |||
| //XXX task.setTaskType(qname); | |||
| task.setQName(qname); | |||
| task.setTaskName(qname); | |||
| @@ -90,9 +90,11 @@ public class Antlib extends Task implements TaskContainer { | |||
| * | |||
| * @param project the current project | |||
| * @param antlibUrl the url to read the definitions from | |||
| * @param uri the uri that the antlib is to be placed in | |||
| * @return the ant lib task | |||
| */ | |||
| public static Antlib createAntlib(Project project, URL antlibUrl) { | |||
| public static Antlib createAntlib(Project project, URL antlibUrl, | |||
| String uri) { | |||
| // Check if we can contact the URL | |||
| try { | |||
| antlibUrl.openConnection().connect(); | |||
| @@ -100,22 +102,29 @@ public class Antlib extends Task implements TaskContainer { | |||
| throw new BuildException( | |||
| "Unable to find " + antlibUrl, ex); | |||
| } | |||
| // Should be safe to parse | |||
| ProjectHelper2 parser = new ProjectHelper2(); | |||
| UnknownElement ue = | |||
| parser.parseUnknownElement(project, antlibUrl); | |||
| // Check name is "antlib" | |||
| if (!(ue.getTag().equals(TAG))) { | |||
| throw new BuildException( | |||
| "Unexpected tag " + ue.getTag() + " expecting " | |||
| + TAG, ue.getLocation()); | |||
| ComponentHelper helper = | |||
| ComponentHelper.getComponentHelper(project); | |||
| helper.enterAntLib(uri); | |||
| try { | |||
| // Should be safe to parse | |||
| ProjectHelper2 parser = new ProjectHelper2(); | |||
| UnknownElement ue = | |||
| parser.parseUnknownElement(project, antlibUrl); | |||
| // Check name is "antlib" | |||
| if (!(ue.getTag().equals(TAG))) { | |||
| throw new BuildException( | |||
| "Unexpected tag " + ue.getTag() + " expecting " | |||
| + TAG, ue.getLocation()); | |||
| } | |||
| Antlib antlib = new Antlib(); | |||
| antlib.setProject(project); | |||
| antlib.setLocation(ue.getLocation()); | |||
| antlib.init(); | |||
| ue.configure(antlib); | |||
| return antlib; | |||
| } finally { | |||
| helper.exitAntLib(); | |||
| } | |||
| Antlib antlib = new Antlib(); | |||
| antlib.setProject(project); | |||
| antlib.setLocation(ue.getLocation()); | |||
| antlib.init(); | |||
| ue.configure(antlib); | |||
| return antlib; | |||
| } | |||
| @@ -166,28 +175,21 @@ public class Antlib extends Task implements TaskContainer { | |||
| * any tasks that derive from Definer. | |||
| */ | |||
| public void execute() { | |||
| ComponentHelper helper = | |||
| ComponentHelper.getComponentHelper(getProject()); | |||
| helper.enterAntLib(); | |||
| try { | |||
| for (Iterator i = tasks.iterator(); i.hasNext();) { | |||
| UnknownElement ue = (UnknownElement) i.next(); | |||
| ue.maybeConfigure(); | |||
| setLocation(ue.getLocation()); | |||
| Task t = ue.getTask(); | |||
| if (t == null) { | |||
| continue; | |||
| } | |||
| if (t instanceof AntlibInterface) { | |||
| AntlibInterface d = (AntlibInterface) t; | |||
| d.setURI(uri); | |||
| d.setAntlibClassLoader(getClassLoader()); | |||
| } | |||
| t.init(); | |||
| t.execute(); | |||
| for (Iterator i = tasks.iterator(); i.hasNext();) { | |||
| UnknownElement ue = (UnknownElement) i.next(); | |||
| ue.maybeConfigure(); | |||
| setLocation(ue.getLocation()); | |||
| Task t = ue.getTask(); | |||
| if (t == null) { | |||
| continue; | |||
| } | |||
| } finally { | |||
| helper.exitAntLib(); | |||
| if (t instanceof AntlibInterface) { | |||
| AntlibInterface d = (AntlibInterface) t; | |||
| d.setURI(uri); | |||
| d.setAntlibClassLoader(getClassLoader()); | |||
| } | |||
| t.init(); | |||
| t.execute(); | |||
| } | |||
| } | |||
| @@ -315,7 +315,7 @@ public abstract class Definer extends DefBase { | |||
| */ | |||
| private void loadAntlib(ClassLoader classLoader, URL url) { | |||
| try { | |||
| Antlib antlib = Antlib.createAntlib(getProject(), url); | |||
| Antlib antlib = Antlib.createAntlib(getProject(), url, getUri()); | |||
| antlib.setClassLoader(classLoader); | |||
| antlib.setURI(getUri()); | |||
| antlib.perform(); | |||
| @@ -74,6 +74,10 @@ public class AntlibTest extends BuildFileTest { | |||
| expectLog("antlib.file", "MyTask called"); | |||
| } | |||
| public void testNsCurrent() { | |||
| expectLog("ns.current", "Echo2 calledEcho2 inside a macro"); | |||
| } | |||
| public static class MyTask extends Task { | |||
| public void execute() { | |||
| log("MyTask called"); | |||