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). | |||
| 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: | |||
| ----------- | |||
| @@ -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 | |||
| 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> | |||
| 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 PropertyHelper next; | |||
| private Hashtable delegates = new Hashtable(); | |||
| @@ -245,6 +259,7 @@ public class PropertyHelper implements GetProperty { | |||
| * Default constructor. | |||
| */ | |||
| protected PropertyHelper() { | |||
| add(FROM_REF); | |||
| add(TO_STRING); | |||
| add(SKIP_DOUBLE_DOLLAR); | |||
| 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> | |||