git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@816153 13f79535-47bb-0310-9956-ffa450edef68master
@@ -156,6 +156,23 @@ Changes that could break older environments: | |||||
adapt (by overriding the new two-arg processFile method). | adapt (by overriding the new two-arg processFile method). | ||||
Bugzilla Report 23243. | Bugzilla Report 23243. | ||||
* A new property syntax can be used to set attributes from | |||||
references: ${ant.ref:some-reference} | |||||
In most cases this will yield the exact same result as | |||||
${toString:some-reference} - only when an attribute setter method | |||||
accepts an object type other than string and the project's | |||||
reference is an Object of matching type the new syntax will pass in | |||||
that object. | |||||
If your build file already contains properties whose name starts | |||||
with "ant.ref:" there is a potential for collision. If your | |||||
property has been set, normal property expansion will take | |||||
precedence over the new syntax. If the property has not been set | |||||
and a reference with the postfix of your property name exists | |||||
(i.e. in a very unlikely event) then the new syntax would yield a | |||||
different result (an expanded property) than Ant 1.7.1 did. | |||||
Fixed bugs: | Fixed bugs: | ||||
----------- | ----------- | ||||
@@ -804,6 +804,31 @@ For example, here is how to get a listing of the files in a fileset, | |||||
There is no guarantee that external types provide meaningful information in such | There is no guarantee that external types provide meaningful information in such | ||||
a situation</p> | a situation</p> | ||||
<h3><a name="ant.refid">Getting the value of a Reference with | |||||
${ant.refid:}</a></h3> | |||||
<p>Any Ant type which has been declared with a reference can also be | |||||
used as a property by using the <code>${ant.refid:}</code> | |||||
operation, with the name of the reference listed after | |||||
the <code>ant.refid:</code> text. The difference between this | |||||
operation and <a href="#toString"><code>${toString:}</code></a> is | |||||
that <code>${ant.refid:}</code> will expand to the referenced object | |||||
itself. In most circumstances the toString method will be invoked | |||||
anyway, for example if the <code>${ant.refid:}</code> is surrounded | |||||
by other text.</p> | |||||
<p>This syntax is most useful when using a task with attribute setters | |||||
that accept objects other than String. For example if the setter | |||||
accepts a Resource object as in</p> | |||||
<pre> | |||||
public void setAttr(Resource r) { ... } | |||||
</pre> | |||||
<p>then the syntax can be used to pass in resource subclasses | |||||
preciously defined as references like</p> | |||||
<pre> | |||||
<url url="http://ant.apache.org/" id="anturl"/> | |||||
<my:task attr="${ant.refid:anturl}"/> | |||||
</pre> | |||||
<h3><a name="external-tasks">Use of external tasks</a></h3> | <h3><a name="external-tasks">Use of external tasks</a></h3> | ||||
Ant supports a plugin mechanism for using third party tasks. For using them you | Ant supports a plugin mechanism for using third party tasks. For using them you | ||||
@@ -220,6 +220,20 @@ public class PropertyHelper implements GetProperty { | |||||
} | } | ||||
}; | }; | ||||
/** | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
private static final PropertyEvaluator FROM_REF = new PropertyEvaluator() { | |||||
private final String PREFIX = "ant.refid:"; | |||||
private final int PREFIX_LEN = PREFIX.length(); | |||||
public Object evaluate(String prop, PropertyHelper helper) { | |||||
return prop.startsWith(PREFIX) && helper.getProject() != null | |||||
? helper.getProject().getReference(prop.substring(PREFIX_LEN)) | |||||
: null; | |||||
} | |||||
}; | |||||
private Project project; | private Project project; | ||||
private PropertyHelper next; | private PropertyHelper next; | ||||
private Hashtable delegates = new Hashtable(); | private Hashtable delegates = new Hashtable(); | ||||
@@ -245,6 +259,7 @@ public class PropertyHelper implements GetProperty { | |||||
* Default constructor. | * Default constructor. | ||||
*/ | */ | ||||
protected PropertyHelper() { | protected PropertyHelper() { | ||||
add(FROM_REF); | |||||
add(TO_STRING); | add(TO_STRING); | ||||
add(SKIP_DOUBLE_DOLLAR); | add(SKIP_DOUBLE_DOLLAR); | ||||
add(DEFAULT_EXPANDER); | add(DEFAULT_EXPANDER); | ||||
@@ -0,0 +1,104 @@ | |||||
<?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"/> | |||||
<path id="foo" location="x.y"/> | |||||
<target name="testToString"> | |||||
<echo message="${toString:foo}"/> | |||||
<au:assertLogContains | |||||
text="antunit${file.separator}core${file.separator}x.y"/> | |||||
</target> | |||||
<target name="testImplicitToString"> | |||||
<echo message="${ant.refid:foo}"/> | |||||
<au:assertLogContains | |||||
text="antunit${file.separator}core${file.separator}x.y"/> | |||||
</target> | |||||
<target name="testPathObject"> | |||||
<mkdir dir="${input}/org/example"/> | |||||
<mkdir dir="${output}"/> | |||||
<echo file="${input}/org/example/Task.java"><![CDATA[ | |||||
package org.example; | |||||
import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.Project; | |||||
import org.apache.tools.ant.types.Path; | |||||
public class Task { | |||||
private Project project; | |||||
public void setProject(Project p) { | |||||
project = p; | |||||
} | |||||
private boolean set = false; | |||||
public void setPath(Path p) { | |||||
if (p != project.getReference("foo")) { | |||||
throw new BuildException("this is not my path"); | |||||
} | |||||
set = true; | |||||
} | |||||
public void execute() { | |||||
if (!set) { | |||||
throw new BuildException("expected my path attribute to be set"); | |||||
} | |||||
} | |||||
} | |||||
]]></echo> | |||||
<javac srcdir="${input}" destdir="${output}"/> | |||||
<taskdef name="x" classname="org.example.Task" | |||||
classpath="${output}"/> | |||||
<x path="${ant.refid:foo}"/> | |||||
</target> | |||||
<target name="testManualExample"> | |||||
<mkdir dir="${input}/org/example"/> | |||||
<mkdir dir="${output}"/> | |||||
<echo file="${input}/org/example/Task.java"><![CDATA[ | |||||
package org.example; | |||||
import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.types.Resource; | |||||
import org.apache.tools.ant.types.resources.URLResource; | |||||
public class Task { | |||||
private Resource r; | |||||
private boolean set = false; | |||||
public void setAttr(Resource r) { | |||||
this.r = r; | |||||
} | |||||
public void execute() { | |||||
if (r instanceof URLResource) { | |||||
System.out.println("URL is: " + ((URLResource) r).getURL()); | |||||
} else { | |||||
throw new BuildException("Expected an URLResource but got: " | |||||
+ (r != null ? r.getClass().getName() | |||||
: "nothing")); | |||||
} | |||||
} | |||||
} | |||||
]]></echo> | |||||
<javac srcdir="${input}" destdir="${output}"/> | |||||
<taskdef name="x" classname="org.example.Task" | |||||
classpath="${output}"/> | |||||
<url url="http://ant.apache.org/" id="anturl"/> | |||||
<x attr="${ant.refid:anturl}"/> | |||||
<au:assertLogContains text="URL is: http://ant.apache.org/"/> | |||||
</target> | |||||
</project> |