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