- introduce a <projecthelper> task to install project helpers dynamically, especially usefull for unit testing git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@980536 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -92,7 +92,7 @@ Fixed bugs: | |||||
| Bugzilla Report 49041. | Bugzilla Report 49041. | ||||
| * The <restrict> resource collection was checking every resource even if | * The <restrict> resource collection was checking every resource even if | ||||
| we actually just want the first one, like in the exemple of use of | |||||
| we actually just want the first one, like in the example of use of | |||||
| resourcelist in the documentation (getting the first available resource | resourcelist in the documentation (getting the first available resource | ||||
| from a mirror list). | from a mirror list). | ||||
| @@ -142,6 +142,13 @@ Other changes: | |||||
| timestamps in various tasks. | timestamps in various tasks. | ||||
| Bugzilla Report 49485. | Bugzilla Report 49485. | ||||
| * ProjectHelpers can now be installed dynamically via the <projecthelper> | |||||
| Ant task. | |||||
| * <import> is now able to switch to the proper ProjectHelper to parse | |||||
| the imported resource. This means that several kinds of different build | |||||
| files can import each other. | |||||
| Changes from Ant 1.8.0 TO Ant 1.8.1 | Changes from Ant 1.8.0 TO Ant 1.8.1 | ||||
| =================================== | =================================== | ||||
| @@ -29,20 +29,28 @@ | |||||
| </p> | </p> | ||||
| <p> | <p> | ||||
| <b>Note</b> this task heavily relies on the ProjectHelper | |||||
| On execution it will select the proper ProjectHelper to parse the imported | |||||
| file, using the same algorithm as the one executed at | |||||
| <a href="../projecthelper.html">startup</a>. The selected ProjectHelper | |||||
| instance will then be responsible to actually parse the imported file. | |||||
| </p> | |||||
| <p> | |||||
| <b>Note</b> as seen above, this task heavily relies on the ProjectHelper | |||||
| implementation and doesn't really perform any work of its own. If | implementation and doesn't really perform any work of its own. If | ||||
| you have configured Ant to use a ProjectHelper other than Ant's | you have configured Ant to use a ProjectHelper other than Ant's | ||||
| default, this task may or may not work. | default, this task may or may not work. | ||||
| </p> | </p> | ||||
| <p> | <p> | ||||
| On execution it will read another Ant file into | |||||
| the same Project. This means that it basically works like the | |||||
| In the common use case where only Ant's default project helper is | |||||
| used, it basically works like the | |||||
| <a href="http://ant.apache.org/faq.html#xml-entity-include">Entity | <a href="http://ant.apache.org/faq.html#xml-entity-include">Entity | ||||
| Includes as explained in the Ant FAQ</a>, as if the imported file was | Includes as explained in the Ant FAQ</a>, as if the imported file was | ||||
| contained in the importing file, minus the top <code><project></code> | contained in the importing file, minus the top <code><project></code> | ||||
| tag. | tag. | ||||
| </p> | </p> | ||||
| <p> | <p> | ||||
| The import task may only be used as a top-level task. This means that | The import task may only be used as a top-level task. This means that | ||||
| it may not be used in a target. | it may not be used in a target. | ||||
| @@ -0,0 +1,59 @@ | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <html> | |||||
| <head> | |||||
| <meta http-equiv="Content-Language" content="en-us"> | |||||
| <link rel="stylesheet" type="text/css" href="../stylesheets/style.css"> | |||||
| <title>ProjectHelper Task</title> | |||||
| </head> | |||||
| <body> | |||||
| <h2>ProjectHelper</h2> | |||||
| <h3>Description</h3> | |||||
| <p>This task is provided for the purpose of allowing the user to install a different | |||||
| ProjectHelper at runtime. | |||||
| </p> | |||||
| <p>The helpers will be added after all the already registered helpers, but before | |||||
| the default one (ProjectHelper2) | |||||
| </p> | |||||
| <p>See the description of Ant's | |||||
| <a href="../projecthelper.html">Project Helper</a> for more information. | |||||
| </p> | |||||
| <p><b>Since Ant 1.8.2</b></p> | |||||
| <h3>Parameters specified as nested elements</h3> | |||||
| You may specify many configured <code>org.apache.tools.ant.ProjectHelper</code> instances. | |||||
| <h3>Example</h3> | |||||
| <p>Install a custom ProjectHelper implementation | |||||
| (assuming <code>MyProjectHelper extends ProjectHelper</code>):</p> | |||||
| <pre> | |||||
| <typedef classname="org.example.MyProjectHelper" | |||||
| name="myprojecthelper"/> | |||||
| <projecthelper> | |||||
| <myprojecthelper/> | |||||
| </projecthelper> | |||||
| </pre> | |||||
| </body> | |||||
| </html> | |||||
| @@ -47,6 +47,12 @@ been done around a pure java frontend, and a groovy one too (ask the dev mailing | |||||
| list for further info about these). | list for further info about these). | ||||
| </p> | </p> | ||||
| <p>Since Ant 1.8.2, the <a href="Tasks/import.html">import</a> task will also | |||||
| try to use the proper helper to parse the imported file. So it is possible to | |||||
| write different build files in different languages and have them import each | |||||
| other. | |||||
| </p> | |||||
| <h2><a name="repository">How is Ant is selecting the proper ProjectHelper</a></h2> | <h2><a name="repository">How is Ant is selecting the proper ProjectHelper</a></h2> | ||||
| <p> | <p> | ||||
| @@ -122,7 +128,7 @@ capable of and what is is expecting: | |||||
| </p> | </p> | ||||
| <p> | <p> | ||||
| Now that you have your implementation ready, you have to declare it to Ant. Two | |||||
| Now that you have your implementation ready, you have to declare it to Ant. Three | |||||
| solutions here: | solutions here: | ||||
| <ul> | <ul> | ||||
| <li>use the system property <code>org.apache.tools.ant.ProjectHelper</code> | <li>use the system property <code>org.apache.tools.ant.ProjectHelper</code> | ||||
| @@ -132,6 +138,10 @@ solutions here: | |||||
| <code>META-INF/services/org.apache.tools.ant.ProjectHelper</code>. | <code>META-INF/services/org.apache.tools.ant.ProjectHelper</code>. | ||||
| And then in this file just put the fully qualified name of your | And then in this file just put the fully qualified name of your | ||||
| implementation</li> | implementation</li> | ||||
| <li>use the <a href="Tasks/projecthelper.html">projecthelper</a> task (since | |||||
| Ant 1.8.2) which will install dynamically an helper in the internal helper | |||||
| 'repository'. Then your helper can be used on the next call to the | |||||
| <a href="Tasks/import.html">import</a> task.</li> | |||||
| </ul> | </ul> | ||||
| </p> | </p> | ||||
| @@ -133,6 +133,7 @@ | |||||
| <li><a href="Tasks/pathconvert.html">PathConvert</a></li> | <li><a href="Tasks/pathconvert.html">PathConvert</a></li> | ||||
| <li><a href="Tasks/perforce.html">Perforce Tasks</a></li> | <li><a href="Tasks/perforce.html">Perforce Tasks</a></li> | ||||
| <li><a href="Tasks/presetdef.html">PreSetDef</a></li> | <li><a href="Tasks/presetdef.html">PreSetDef</a></li> | ||||
| <li><a href="Tasks/projecthelper.html">ProjectHelper</a></li> | |||||
| <li><a href="Tasks/property.html">Property</a></li> | <li><a href="Tasks/property.html">Property</a></li> | ||||
| <li><a href="Tasks/propertyfile.html">PropertyFile</a></li> | <li><a href="Tasks/propertyfile.html">PropertyFile</a></li> | ||||
| <li><a href="Tasks/propertyhelper.html">PropertyHelper</a></li> | <li><a href="Tasks/propertyhelper.html">PropertyHelper</a></li> | ||||
| @@ -34,7 +34,7 @@ import org.apache.tools.ant.util.LoaderUtils; | |||||
| /** | /** | ||||
| * Repository of {@link ProjectHelper} found in the classpath or via | * Repository of {@link ProjectHelper} found in the classpath or via | ||||
| * some System properties. | * some System properties. | ||||
| * | |||||
| * <p>See the ProjectHelper documentation in the manual.</p> | * <p>See the ProjectHelper documentation in the manual.</p> | ||||
| * | * | ||||
| * @since Ant 1.8.0 | * @since Ant 1.8.0 | ||||
| @@ -57,6 +57,18 @@ public class ProjectHelperRepository { | |||||
| private static final Class[] NO_CLASS = new Class[0]; | private static final Class[] NO_CLASS = new Class[0]; | ||||
| private static final Object[] NO_OBJECT = new Object[0]; | private static final Object[] NO_OBJECT = new Object[0]; | ||||
| private static Constructor PROJECTHELPER2_CONSTRUCTOR; | |||||
| static { | |||||
| try { | |||||
| PROJECTHELPER2_CONSTRUCTOR = ProjectHelper2.class | |||||
| .getConstructor(NO_CLASS); | |||||
| } catch (Exception e) { | |||||
| // ProjectHelper2 must be available | |||||
| throw new RuntimeException(e); | |||||
| } | |||||
| } | |||||
| public static ProjectHelperRepository getInstance() { | public static ProjectHelperRepository getInstance() { | ||||
| return instance; | return instance; | ||||
| } | } | ||||
| @@ -67,7 +79,7 @@ public class ProjectHelperRepository { | |||||
| private void collectProjectHelpers() { | private void collectProjectHelpers() { | ||||
| // First, try the system property | // First, try the system property | ||||
| ProjectHelper projectHelper = getProjectHelperBySystemProperty(); | |||||
| Constructor projectHelper = getProjectHelperBySystemProperty(); | |||||
| registerProjectHelper(projectHelper); | registerProjectHelper(projectHelper); | ||||
| // A JDK1.3 'service' ( like in JAXP ). That will plug a helper | // A JDK1.3 'service' ( like in JAXP ). That will plug a helper | ||||
| @@ -100,35 +112,63 @@ public class ProjectHelperRepository { | |||||
| e.printStackTrace(System.err); | e.printStackTrace(System.err); | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| // last but not least, ant default project helper | |||||
| projectHelper = new ProjectHelper2(); | |||||
| registerProjectHelper(projectHelper); | |||||
| /** | |||||
| * Register the specified project helper into the repository. | |||||
| * <p> | |||||
| * The helper will be added after all the already registered helpers, but | |||||
| * before the default one (ProjectHelper2) | |||||
| * | |||||
| * @param helperClassName | |||||
| * the fully qualified name of the helper | |||||
| * @throws BuildException | |||||
| * if the class cannot be loaded or if there is no constructor | |||||
| * with no argument | |||||
| * @since Ant 1.8.2 | |||||
| */ | |||||
| public void registerProjectHelper(String helperClassName) | |||||
| throws BuildException { | |||||
| registerProjectHelper(getHelperConstructor(helperClassName)); | |||||
| } | } | ||||
| private void registerProjectHelper(ProjectHelper projectHelper) { | |||||
| if (projectHelper == null) { | |||||
| /** | |||||
| * Register the specified project helper into the repository. | |||||
| * <p> | |||||
| * The helper will be added after all the already registered helpers, but | |||||
| * before the default one (ProjectHelper2) | |||||
| * | |||||
| * @param helperClass | |||||
| * the class of the helper | |||||
| * @throws BuildException | |||||
| * if there is no constructor with no argument | |||||
| * @since Ant 1.8.2 | |||||
| */ | |||||
| public void registerProjectHelper(Class helperClass) throws BuildException { | |||||
| try { | |||||
| registerProjectHelper(helperClass.getConstructor(NO_CLASS)); | |||||
| } catch (NoSuchMethodException e) { | |||||
| throw new BuildException("Couldn't find no-arg constructor in " | |||||
| + helperClass.getName()); | |||||
| } | |||||
| } | |||||
| private void registerProjectHelper(Constructor helperConstructor) { | |||||
| if (helperConstructor == null) { | |||||
| return; | return; | ||||
| } | } | ||||
| if (DEBUG) { | if (DEBUG) { | ||||
| System.out.println("ProjectHelper " + | |||||
| projectHelper.getClass().getName() | |||||
| + " registered."); | |||||
| } | |||||
| try { | |||||
| helpers.add(projectHelper.getClass().getConstructor(NO_CLASS)); | |||||
| } catch (NoSuchMethodException nse) { | |||||
| // impossible to get here | |||||
| throw new BuildException("Couldn't find no-arg constructor in " | |||||
| + projectHelper.getClass().getName()); | |||||
| System.out.println("ProjectHelper " | |||||
| + helperConstructor.getClass().getName() + " registered."); | |||||
| } | } | ||||
| helpers.add(helperConstructor); | |||||
| } | } | ||||
| private ProjectHelper getProjectHelperBySystemProperty() { | |||||
| private Constructor getProjectHelperBySystemProperty() { | |||||
| String helperClass = System.getProperty(ProjectHelper.HELPER_PROPERTY); | String helperClass = System.getProperty(ProjectHelper.HELPER_PROPERTY); | ||||
| try { | try { | ||||
| if (helperClass != null) { | if (helperClass != null) { | ||||
| return newHelper(helperClass); | |||||
| return getHelperConstructor(helperClass); | |||||
| } | } | ||||
| } catch (SecurityException e) { | } catch (SecurityException e) { | ||||
| System.err.println("Unable to load ProjectHelper class \"" | System.err.println("Unable to load ProjectHelper class \"" | ||||
| @@ -142,7 +182,7 @@ public class ProjectHelperRepository { | |||||
| return null; | return null; | ||||
| } | } | ||||
| private ProjectHelper getProjectHelperByService(InputStream is) { | |||||
| private Constructor getProjectHelperByService(InputStream is) { | |||||
| try { | try { | ||||
| // This code is needed by EBCDIC and other strange systems. | // This code is needed by EBCDIC and other strange systems. | ||||
| // It's a fix for bugs reported in xerces | // It's a fix for bugs reported in xerces | ||||
| @@ -158,7 +198,7 @@ public class ProjectHelperRepository { | |||||
| rd.close(); | rd.close(); | ||||
| if (helperClassName != null && !"".equals(helperClassName)) { | if (helperClassName != null && !"".equals(helperClassName)) { | ||||
| return newHelper(helperClassName); | |||||
| return getHelperConstructor(helperClassName); | |||||
| } | } | ||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| System.out.println("Unable to load ProjectHelper from service " | System.out.println("Unable to load ProjectHelper from service " | ||||
| @@ -171,21 +211,21 @@ public class ProjectHelperRepository { | |||||
| } | } | ||||
| /** | /** | ||||
| * Creates a new helper instance from the name of the class. It'll | |||||
| * first try the thread class loader, then Class.forName() will | |||||
| * load from the same loader that loaded this class. | |||||
| * Get the constructor with not argument of an helper from its class name. | |||||
| * It'll first try the thread class loader, then Class.forName() will load | |||||
| * from the same loader that loaded this class. | |||||
| * | * | ||||
| * @param helperClass | * @param helperClass | ||||
| * The name of the class to create an instance of. Must not be | * The name of the class to create an instance of. Must not be | ||||
| * <code>null</code>. | * <code>null</code>. | ||||
| * | * | ||||
| * @return a new instance of the specified class. | |||||
| * @return the constructor of the specified class. | |||||
| * | * | ||||
| * @exception BuildException | * @exception BuildException | ||||
| * if the class cannot be found or cannot be appropriate | |||||
| * instantiated. | |||||
| * if the class cannot be found or if a constructor with no | |||||
| * argument cannot be found. | |||||
| */ | */ | ||||
| private ProjectHelper newHelper(String helperClass) throws BuildException { | |||||
| private Constructor getHelperConstructor(String helperClass) throws BuildException { | |||||
| ClassLoader classLoader = LoaderUtils.getContextClassLoader(); | ClassLoader classLoader = LoaderUtils.getContextClassLoader(); | ||||
| try { | try { | ||||
| Class clazz = null; | Class clazz = null; | ||||
| @@ -199,7 +239,7 @@ public class ProjectHelperRepository { | |||||
| if (clazz == null) { | if (clazz == null) { | ||||
| clazz = Class.forName(helperClass); | clazz = Class.forName(helperClass); | ||||
| } | } | ||||
| return ((ProjectHelper) clazz.newInstance()); | |||||
| return clazz.getConstructor(NO_CLASS); | |||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| throw new BuildException(e); | throw new BuildException(e); | ||||
| } | } | ||||
| @@ -266,17 +306,25 @@ public class ProjectHelperRepository { | |||||
| private static class ConstructingIterator implements Iterator { | private static class ConstructingIterator implements Iterator { | ||||
| private final Iterator nested; | private final Iterator nested; | ||||
| private boolean empty = false; | |||||
| ConstructingIterator(Iterator nested) { | ConstructingIterator(Iterator nested) { | ||||
| this.nested = nested; | this.nested = nested; | ||||
| } | } | ||||
| public boolean hasNext() { | public boolean hasNext() { | ||||
| return nested.hasNext(); | |||||
| return nested.hasNext() || !empty; | |||||
| } | } | ||||
| public Object next() { | public Object next() { | ||||
| Constructor c = (Constructor) nested.next(); | |||||
| Constructor c; | |||||
| if (nested.hasNext()) { | |||||
| c = (Constructor) nested.next(); | |||||
| } else { | |||||
| // last but not least, ant default project helper | |||||
| empty = true; | |||||
| c = PROJECTHELPER2_CONSTRUCTOR; | |||||
| } | |||||
| try { | try { | ||||
| return c.newInstance(NO_OBJECT); | return c.newInstance(NO_OBJECT); | ||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| @@ -21,6 +21,7 @@ package org.apache.tools.ant.taskdefs; | |||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.ProjectHelper; | import org.apache.tools.ant.ProjectHelper; | ||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| import org.apache.tools.ant.ProjectHelperRepository; | |||||
| import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
| import org.apache.tools.ant.types.Resource; | import org.apache.tools.ant.types.Resource; | ||||
| import org.apache.tools.ant.types.ResourceCollection; | import org.apache.tools.ant.types.ResourceCollection; | ||||
| @@ -213,7 +214,22 @@ public class ImportTask extends Task { | |||||
| setProjectHelperProps(prefix, prefixSeparator, | setProjectHelperProps(prefix, prefixSeparator, | ||||
| isInIncludeMode()); | isInIncludeMode()); | ||||
| helper.parse(getProject(), importedResource); | |||||
| ProjectHelper subHelper = ProjectHelperRepository.getInstance().getProjectHelperForBuildFile( | |||||
| importedResource); | |||||
| // push current stacks into the sub helper | |||||
| subHelper.getImportStack().addAll(helper.getImportStack()); | |||||
| subHelper.getExtensionStack().addAll(helper.getExtensionStack()); | |||||
| getProject().addReference(ProjectHelper.PROJECTHELPER_REFERENCE, subHelper); | |||||
| subHelper.parse(getProject(), importedResource); | |||||
| // push back the stack from the sub helper to the main one | |||||
| getProject().addReference(ProjectHelper.PROJECTHELPER_REFERENCE, helper); | |||||
| helper.getImportStack().clear(); | |||||
| helper.getImportStack().addAll(subHelper.getImportStack()); | |||||
| helper.getExtensionStack().clear(); | |||||
| helper.getExtensionStack().addAll(subHelper.getExtensionStack()); | |||||
| } catch (BuildException ex) { | } catch (BuildException ex) { | ||||
| throw ProjectHelper.addLocationToBuildException( | throw ProjectHelper.addLocationToBuildException( | ||||
| ex, getLocation()); | ex, getLocation()); | ||||
| @@ -0,0 +1,49 @@ | |||||
| /* | |||||
| * Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| * contributor license agreements. See the NOTICE file distributed with | |||||
| * this work for additional information regarding copyright ownership. | |||||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| * (the "License"); you may not use this file except in compliance with | |||||
| * the License. You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| * | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs; | |||||
| import java.util.ArrayList; | |||||
| import java.util.Iterator; | |||||
| import java.util.List; | |||||
| import org.apache.tools.ant.BuildException; | |||||
| import org.apache.tools.ant.ProjectHelper; | |||||
| import org.apache.tools.ant.ProjectHelperRepository; | |||||
| import org.apache.tools.ant.Task; | |||||
| /** | |||||
| * Task to install project helper into Ant's runtime | |||||
| * | |||||
| * @since Ant 1.8.2 | |||||
| */ | |||||
| public class ProjectHelperTask extends Task { | |||||
| private List projectHelpers = new ArrayList(); | |||||
| public synchronized void addConfigured(ProjectHelper projectHelper) { | |||||
| this.projectHelpers.add(projectHelper); | |||||
| } | |||||
| public void execute() throws BuildException { | |||||
| ProjectHelperRepository repo = ProjectHelperRepository.getInstance(); | |||||
| for (Iterator it = projectHelpers.iterator(); it.hasNext();) { | |||||
| ProjectHelper helper = (ProjectHelper) it.next(); | |||||
| repo.registerProjectHelper(helper.getClass()); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -81,6 +81,7 @@ parallel=org.apache.tools.ant.taskdefs.Parallel | |||||
| patch=org.apache.tools.ant.taskdefs.Patch | patch=org.apache.tools.ant.taskdefs.Patch | ||||
| pathconvert=org.apache.tools.ant.taskdefs.PathConvert | pathconvert=org.apache.tools.ant.taskdefs.PathConvert | ||||
| presetdef=org.apache.tools.ant.taskdefs.PreSetDef | presetdef=org.apache.tools.ant.taskdefs.PreSetDef | ||||
| projecthelper=org.apache.tools.ant.taskdefs.ProjectHelperTask | |||||
| property=org.apache.tools.ant.taskdefs.Property | property=org.apache.tools.ant.taskdefs.Property | ||||
| propertyhelper=org.apache.tools.ant.taskdefs.PropertyHelperTask | propertyhelper=org.apache.tools.ant.taskdefs.PropertyHelperTask | ||||
| record=org.apache.tools.ant.taskdefs.Recorder | record=org.apache.tools.ant.taskdefs.Recorder | ||||
| @@ -0,0 +1,90 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project xmlns:au="antlib:org.apache.ant.antunit" default="antunit"> | |||||
| <import file="../antunit-base.xml"/> | |||||
| <property name="projecthelperin" location="${java.io.tmpdir}/projecthelperinput"/> | |||||
| <property name="projecthelperout" location="${java.io.tmpdir}/projecthelperoutput"/> | |||||
| <target name="compileHelpers"> | |||||
| <mkdir dir="${projecthelperin}/org/apache/tools/ant"/> | |||||
| <mkdir dir="${projecthelperout}/org/apache/tools/ant"/> | |||||
| <echo file="${projecthelperin}/org/apache/tools/ant/ReferencerProjectHelper.java"> | |||||
| <!-- helper that just delegate the parsing to the xml build with the proper name --> | |||||
| <![CDATA[ | |||||
| package org.apache.tools.ant; | |||||
| import org.apache.tools.ant.helper.ProjectHelper2; | |||||
| import org.apache.tools.ant.types.Resource; | |||||
| import org.apache.tools.ant.types.resources.FileResource; | |||||
| public class ReferencerProjectHelper extends ProjectHelper2 { | |||||
| public boolean canParseBuildFile(Resource buildFile) { | |||||
| return buildFile instanceof FileResource && buildFile.getName().endsWith(".xmlref"); | |||||
| } | |||||
| public String getDefaultBuildFile() { | |||||
| return "build.xmlref"; | |||||
| } | |||||
| public boolean canParseAntlibDescriptor(Resource resource) { | |||||
| return resource instanceof FileResource && resource.getName().endsWith(".xmlref"); | |||||
| } | |||||
| public void parse(Project project, Object source, RootHandler handler) | |||||
| throws BuildException { | |||||
| FileResource file = (FileResource) source; | |||||
| String name = file.getName(); | |||||
| Resource actual = new FileResource(file.getFile().getParentFile(), name.substring(0, name.length() - 3)); | |||||
| // switch to the parsing of the xml build file | |||||
| super.parse(project, actual, handler); | |||||
| } | |||||
| } | |||||
| ]]></echo> | |||||
| <javac srcdir="${projecthelperin}" destdir="${projecthelperout}"/> | |||||
| </target> | |||||
| <target name="defineHelpers" depends="compileHelpers"> | |||||
| <typedef name="referencerhelper" classname="org.apache.tools.ant.ReferencerProjectHelper"> | |||||
| <classpath location="${projecthelperout}"/> | |||||
| </typedef> | |||||
| <projecthelper> | |||||
| <referencerhelper/> | |||||
| </projecthelper> | |||||
| </target> | |||||
| <target name="testCrossTargets" depends="defineHelpers"> | |||||
| <ant antfile="projecthelpers/build-cross-targets.xml" /> | |||||
| </target> | |||||
| <target name="testManyImport" depends="defineHelpers"> | |||||
| <ant antfile="projecthelpers/build-many-import.xml" /> | |||||
| </target> | |||||
| <target name="testCrossExtension" depends="defineHelpers"> | |||||
| <ant antfile="projecthelpers/build-cross-extension.xml" /> | |||||
| </target> | |||||
| <target name="tearDown" depends="antunit-base.tearDown"> | |||||
| <delete dir="${projecthelperin}"/> | |||||
| <delete dir="${projecthelperout}"/> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,26 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project> | |||||
| <extension-point name="extension-ref" /> | |||||
| <target name="setbar" extensionOf="extension"> | |||||
| <property name="bar" value="hello" /> | |||||
| </target> | |||||
| <target name="setfoo" depends="init,extension-ref"> | |||||
| <property name="foo" value="hello" /> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,14 @@ | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| @@ -0,0 +1,36 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project default="end" xmlns:au="antlib:org.apache.ant.antunit"> | |||||
| <import file="build-cross-extension-ref.xmlref" /> | |||||
| <target name="init"> | |||||
| <property name="start" value="true" /> | |||||
| </target> | |||||
| <target name="setprop" extensionOf="extension-ref"> | |||||
| <property name="prop" value="ok" /> | |||||
| </target> | |||||
| <extension-point name="extension" /> | |||||
| <target name="end" depends="setfoo,extension"> | |||||
| <au:assertPropertyEquals name="start" value="true" /> | |||||
| <au:assertPropertyEquals name="foo" value="hello" /> | |||||
| <au:assertPropertyEquals name="bar" value="hello" /> | |||||
| <au:assertPropertyEquals name="prop" value="ok" /> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,22 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project> | |||||
| <target name="setfoo" depends="init"> | |||||
| <property name="foo" value="hello" /> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,14 @@ | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| @@ -0,0 +1,27 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project default="end" xmlns:au="antlib:org.apache.ant.antunit"> | |||||
| <import file="build-cross-targets-ref.xmlref" /> | |||||
| <target name="init"> | |||||
| <property name="start" value="true" /> | |||||
| </target> | |||||
| <target name="end" depends="setfoo"> | |||||
| <au:assertPropertyEquals name="start" value="true" /> | |||||
| <au:assertPropertyEquals name="foo" value="hello" /> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,23 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project> | |||||
| <!-- build file imported by every other build --> | |||||
| <target name="common" depends="init"> | |||||
| <property name="common" value="ok" /> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,23 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project> | |||||
| <!-- build file imported by bot referenced build --> | |||||
| <target name="commonref" depends="init"> | |||||
| <property name="commonref" value="ok" /> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,24 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project> | |||||
| <import file="build-many-import-common.xml" /> | |||||
| <import file="build-many-import-commonref.xml" /> | |||||
| <target name="setfoo" depends="init"> | |||||
| <property name="foo" value="hello" /> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,14 @@ | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| @@ -0,0 +1,32 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project default="end" xmlns:au="antlib:org.apache.ant.antunit"> | |||||
| <import file="build-many-import-ref.xmlref" /> | |||||
| <import file="build-many-import2-ref.xmlref" /> | |||||
| <import file="build-many-import-common.xml" /> | |||||
| <target name="init"> | |||||
| <property name="start" value="true" /> | |||||
| </target> | |||||
| <target name="end" depends="setfoo,setbar,common,commonref"> | |||||
| <au:assertPropertyEquals name="start" value="true" /> | |||||
| <au:assertPropertyEquals name="foo" value="hello" /> | |||||
| <au:assertPropertyEquals name="bar" value="hello" /> | |||||
| <au:assertPropertyEquals name="common" value="ok" /> | |||||
| <au:assertPropertyEquals name="commonref" value="ok" /> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,25 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project> | |||||
| <import file="build-many-import-ref.xmlref" /> | |||||
| <import file="build-many-import-common.xml" /> | |||||
| <import file="build-many-import-commonref.xml" /> | |||||
| <target name="setbar" depends="init,common"> | |||||
| <property name="bar" value="hello" /> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,14 @@ | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| @@ -0,0 +1,97 @@ | |||||
| /* | |||||
| * Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| * contributor license agreements. See the NOTICE file distributed with | |||||
| * this work for additional information regarding copyright ownership. | |||||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| * (the "License"); you may not use this file except in compliance with | |||||
| * the License. You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| * | |||||
| */ | |||||
| package org.apache.tools.ant; | |||||
| import java.io.File; | |||||
| import junit.framework.TestCase; | |||||
| import org.apache.tools.ant.helper.ProjectHelper2; | |||||
| import org.apache.tools.ant.types.Resource; | |||||
| import org.apache.tools.ant.types.resources.FileResource; | |||||
| import org.apache.tools.ant.types.resources.StringResource; | |||||
| /** | |||||
| * Testing around the management of the project helpers | |||||
| */ | |||||
| public class ProjectHelperRepositoryTest extends TestCase { | |||||
| public static class SomeHelper extends ProjectHelper { | |||||
| public boolean canParseBuildFile(Resource buildFile) { | |||||
| return buildFile instanceof FileResource | |||||
| && buildFile.getName().endsWith(".myext"); | |||||
| } | |||||
| public boolean canParseAntlibDescriptor(Resource r) { | |||||
| return r instanceof FileResource && r.getName().endsWith(".myext"); | |||||
| } | |||||
| } | |||||
| public void testFind() throws Exception { | |||||
| ProjectHelperRepository repo = ProjectHelperRepository.getInstance(); | |||||
| repo.registerProjectHelper(SomeHelper.class); | |||||
| Resource r = new FileResource(new File("test.xml")); | |||||
| ProjectHelper helper = repo.getProjectHelperForBuildFile(r); | |||||
| assertTrue(helper instanceof ProjectHelper2); | |||||
| helper = repo.getProjectHelperForAntlib(r); | |||||
| assertTrue(helper instanceof ProjectHelper2); | |||||
| r = new FileResource(new File("test.myext")); | |||||
| helper = repo.getProjectHelperForBuildFile(r); | |||||
| assertTrue(helper instanceof SomeHelper); | |||||
| helper = repo.getProjectHelperForAntlib(r); | |||||
| assertTrue(helper instanceof SomeHelper); | |||||
| r = new StringResource("test.myext"); | |||||
| helper = repo.getProjectHelperForBuildFile(r); | |||||
| assertTrue(helper instanceof ProjectHelper2); | |||||
| helper = repo.getProjectHelperForAntlib(r); | |||||
| assertTrue(helper instanceof ProjectHelper2); | |||||
| r = new StringResource("test.other"); | |||||
| helper = repo.getProjectHelperForBuildFile(r); | |||||
| assertTrue(helper instanceof ProjectHelper2); | |||||
| helper = repo.getProjectHelperForAntlib(r); | |||||
| assertTrue(helper instanceof ProjectHelper2); | |||||
| } | |||||
| public void testNoDefaultContructor() throws Exception { | |||||
| class IncrrectHelper extends ProjectHelper { | |||||
| // the default constructor is not visible to ant here | |||||
| } | |||||
| ProjectHelperRepository repo = ProjectHelperRepository.getInstance(); | |||||
| try { | |||||
| repo.registerProjectHelper(IncrrectHelper.class); | |||||
| fail("Registring an helper with no default constructor should fail"); | |||||
| } catch (BuildException e) { | |||||
| // ok | |||||
| } | |||||
| } | |||||
| public void testUnkwnowHelper() throws Exception { | |||||
| ProjectHelperRepository repo = ProjectHelperRepository.getInstance(); | |||||
| try { | |||||
| repo.registerProjectHelper("xxx.yyy.zzz.UnknownHelper"); | |||||
| fail("Registring an unknwon helper should fail"); | |||||
| } catch (BuildException e) { | |||||
| // ok | |||||
| } | |||||
| } | |||||
| } | |||||