diff --git a/WHATSNEW b/WHATSNEW index a58f3c462..8f1b8f184 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -92,7 +92,7 @@ Fixed bugs: Bugzilla Report 49041. * The 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 from a mirror list). @@ -142,6 +142,13 @@ Other changes: timestamps in various tasks. Bugzilla Report 49485. + * ProjectHelpers can now be installed dynamically via the + Ant task. + + * 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 =================================== diff --git a/docs/manual/Tasks/import.html b/docs/manual/Tasks/import.html index 9742990dc..7400198b5 100644 --- a/docs/manual/Tasks/import.html +++ b/docs/manual/Tasks/import.html @@ -29,20 +29,28 @@

- Note 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 + startup. The selected ProjectHelper + instance will then be responsible to actually parse the imported file. +

+ +

+ Note as seen above, this task heavily relies on the ProjectHelper implementation and doesn't really perform any work of its own. If you have configured Ant to use a ProjectHelper other than Ant's default, this task may or may not work.

- 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 Entity Includes as explained in the Ant FAQ, as if the imported file was contained in the importing file, minus the top <project> tag.

+

The import task may only be used as a top-level task. This means that it may not be used in a target. diff --git a/docs/manual/Tasks/projecthelper.html b/docs/manual/Tasks/projecthelper.html new file mode 100644 index 000000000..4564d3e7a --- /dev/null +++ b/docs/manual/Tasks/projecthelper.html @@ -0,0 +1,59 @@ + + + + + + +ProjectHelper Task + + + + +

ProjectHelper

+

Description

+

This task is provided for the purpose of allowing the user to install a different +ProjectHelper at runtime. +

+

The helpers will be added after all the already registered helpers, but before +the default one (ProjectHelper2) +

+

See the description of Ant's +Project Helper for more information. +

+

Since Ant 1.8.2

+ +

Parameters specified as nested elements

+ +You may specify many configured org.apache.tools.ant.ProjectHelper instances. + +

Example

+ +

Install a custom ProjectHelper implementation + (assuming MyProjectHelper extends ProjectHelper):

+ +
+<typedef classname="org.example.MyProjectHelper"
+              name="myprojecthelper"/>
+<projecthelper>
+  <myprojecthelper/>
+</projecthelper>
+
+ + + + diff --git a/docs/manual/projecthelper.html b/docs/manual/projecthelper.html index 4e0c9dccb..be838c843 100644 --- a/docs/manual/projecthelper.html +++ b/docs/manual/projecthelper.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).

+

Since Ant 1.8.2, the import 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. +

+

How is Ant is selecting the proper ProjectHelper

@@ -122,7 +128,7 @@ capable of and what is is expecting:

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

  • use the system property org.apache.tools.ant.ProjectHelper @@ -132,6 +138,10 @@ solutions here: META-INF/services/org.apache.tools.ant.ProjectHelper. And then in this file just put the fully qualified name of your implementation
  • +
  • use the projecthelper 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 + import task.

diff --git a/docs/manual/tasklist.html b/docs/manual/tasklist.html index 83d0f8e1c..1a598df95 100644 --- a/docs/manual/tasklist.html +++ b/docs/manual/tasklist.html @@ -133,6 +133,7 @@
  • PathConvert
  • Perforce Tasks
  • PreSetDef
  • +
  • ProjectHelper
  • Property
  • PropertyFile
  • PropertyHelper
  • diff --git a/src/main/org/apache/tools/ant/ProjectHelperRepository.java b/src/main/org/apache/tools/ant/ProjectHelperRepository.java index ecb4eba6e..c13cf44b2 100644 --- a/src/main/org/apache/tools/ant/ProjectHelperRepository.java +++ b/src/main/org/apache/tools/ant/ProjectHelperRepository.java @@ -34,7 +34,7 @@ import org.apache.tools.ant.util.LoaderUtils; /** * Repository of {@link ProjectHelper} found in the classpath or via * some System properties. - + * *

    See the ProjectHelper documentation in the manual.

    * * @since Ant 1.8.0 @@ -57,6 +57,18 @@ public class ProjectHelperRepository { private static final Class[] NO_CLASS = new Class[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() { return instance; } @@ -67,7 +79,7 @@ public class ProjectHelperRepository { private void collectProjectHelpers() { // First, try the system property - ProjectHelper projectHelper = getProjectHelperBySystemProperty(); + Constructor projectHelper = getProjectHelperBySystemProperty(); registerProjectHelper(projectHelper); // A JDK1.3 'service' ( like in JAXP ). That will plug a helper @@ -100,35 +112,63 @@ public class ProjectHelperRepository { 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. + *

    + * 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. + *

    + * 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; } 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); try { if (helperClass != null) { - return newHelper(helperClass); + return getHelperConstructor(helperClass); } } catch (SecurityException e) { System.err.println("Unable to load ProjectHelper class \"" @@ -142,7 +182,7 @@ public class ProjectHelperRepository { return null; } - private ProjectHelper getProjectHelperByService(InputStream is) { + private Constructor getProjectHelperByService(InputStream is) { try { // This code is needed by EBCDIC and other strange systems. // It's a fix for bugs reported in xerces @@ -158,7 +198,7 @@ public class ProjectHelperRepository { rd.close(); if (helperClassName != null && !"".equals(helperClassName)) { - return newHelper(helperClassName); + return getHelperConstructor(helperClassName); } } catch (Exception e) { 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 * The name of the class to create an instance of. Must not be * null. * - * @return a new instance of the specified class. + * @return the constructor of the specified class. * * @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(); try { Class clazz = null; @@ -199,7 +239,7 @@ public class ProjectHelperRepository { if (clazz == null) { clazz = Class.forName(helperClass); } - return ((ProjectHelper) clazz.newInstance()); + return clazz.getConstructor(NO_CLASS); } catch (Exception e) { throw new BuildException(e); } @@ -266,17 +306,25 @@ public class ProjectHelperRepository { private static class ConstructingIterator implements Iterator { private final Iterator nested; + private boolean empty = false; ConstructingIterator(Iterator nested) { this.nested = nested; } public boolean hasNext() { - return nested.hasNext(); + return nested.hasNext() || !empty; } 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 { return c.newInstance(NO_OBJECT); } catch (Exception e) { diff --git a/src/main/org/apache/tools/ant/taskdefs/ImportTask.java b/src/main/org/apache/tools/ant/taskdefs/ImportTask.java index a3abc2a36..26d7a43ac 100644 --- a/src/main/org/apache/tools/ant/taskdefs/ImportTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/ImportTask.java @@ -21,6 +21,7 @@ package org.apache.tools.ant.taskdefs; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.ProjectHelper; import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectHelperRepository; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.ResourceCollection; @@ -213,7 +214,22 @@ public class ImportTask extends Task { setProjectHelperProps(prefix, prefixSeparator, 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) { throw ProjectHelper.addLocationToBuildException( ex, getLocation()); diff --git a/src/main/org/apache/tools/ant/taskdefs/ProjectHelperTask.java b/src/main/org/apache/tools/ant/taskdefs/ProjectHelperTask.java new file mode 100644 index 000000000..6d222efd3 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/ProjectHelperTask.java @@ -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()); + } + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties index b99d44cf7..533f6c23c 100644 --- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties +++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties @@ -81,6 +81,7 @@ parallel=org.apache.tools.ant.taskdefs.Parallel patch=org.apache.tools.ant.taskdefs.Patch pathconvert=org.apache.tools.ant.taskdefs.PathConvert presetdef=org.apache.tools.ant.taskdefs.PreSetDef +projecthelper=org.apache.tools.ant.taskdefs.ProjectHelperTask property=org.apache.tools.ant.taskdefs.Property propertyhelper=org.apache.tools.ant.taskdefs.PropertyHelperTask record=org.apache.tools.ant.taskdefs.Recorder diff --git a/src/tests/antunit/core/projecthelpers-test.xml b/src/tests/antunit/core/projecthelpers-test.xml new file mode 100644 index 000000000..cc293765c --- /dev/null +++ b/src/tests/antunit/core/projecthelpers-test.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xml b/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xml new file mode 100644 index 000000000..67837a045 --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xmlref b/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xmlref new file mode 100644 index 000000000..f81d3dbd0 --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xmlref @@ -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. diff --git a/src/tests/antunit/core/projecthelpers/build-cross-extension.xml b/src/tests/antunit/core/projecthelpers/build-cross-extension.xml new file mode 100644 index 000000000..f8f1220be --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-cross-extension.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xml b/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xml new file mode 100644 index 000000000..c16d989d2 --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xmlref b/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xmlref new file mode 100644 index 000000000..f81d3dbd0 --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xmlref @@ -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. diff --git a/src/tests/antunit/core/projecthelpers/build-cross-targets.xml b/src/tests/antunit/core/projecthelpers/build-cross-targets.xml new file mode 100644 index 000000000..c4c7ca76e --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-cross-targets.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + diff --git a/src/tests/antunit/core/projecthelpers/build-many-import-common.xml b/src/tests/antunit/core/projecthelpers/build-many-import-common.xml new file mode 100644 index 000000000..243de8cce --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-many-import-common.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/src/tests/antunit/core/projecthelpers/build-many-import-commonref.xml b/src/tests/antunit/core/projecthelpers/build-many-import-commonref.xml new file mode 100644 index 000000000..38b50ada9 --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-many-import-commonref.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/src/tests/antunit/core/projecthelpers/build-many-import-ref.xml b/src/tests/antunit/core/projecthelpers/build-many-import-ref.xml new file mode 100644 index 000000000..c9c02fe8f --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-many-import-ref.xml @@ -0,0 +1,24 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/tests/antunit/core/projecthelpers/build-many-import-ref.xmlref b/src/tests/antunit/core/projecthelpers/build-many-import-ref.xmlref new file mode 100644 index 000000000..f81d3dbd0 --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-many-import-ref.xmlref @@ -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. diff --git a/src/tests/antunit/core/projecthelpers/build-many-import.xml b/src/tests/antunit/core/projecthelpers/build-many-import.xml new file mode 100644 index 000000000..792fb56ea --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-many-import.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + diff --git a/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xml b/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xml new file mode 100644 index 000000000..d32cf17ab --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xml @@ -0,0 +1,25 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xmlref b/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xmlref new file mode 100644 index 000000000..f81d3dbd0 --- /dev/null +++ b/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xmlref @@ -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. diff --git a/src/tests/junit/org/apache/tools/ant/ProjectHelperRepositoryTest.java b/src/tests/junit/org/apache/tools/ant/ProjectHelperRepositoryTest.java new file mode 100644 index 000000000..ab3c1bb80 --- /dev/null +++ b/src/tests/junit/org/apache/tools/ant/ProjectHelperRepositoryTest.java @@ -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 + } + } +}