Browse Source

implement a new ${ant.refid:} syntax to expand project references as properties

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@816153 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 15 years ago
parent
commit
e25dc381ca
4 changed files with 161 additions and 0 deletions
  1. +17
    -0
      WHATSNEW
  2. +25
    -0
      docs/manual/using.html
  3. +15
    -0
      src/main/org/apache/tools/ant/PropertyHelper.java
  4. +104
    -0
      src/tests/antunit/core/ref-propertyhelper-test.xml

+ 17
- 0
WHATSNEW View File

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



+ 25
- 0
docs/manual/using.html View File

@@ -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>
&lt;url url="http://ant.apache.org/" id="anturl"/&gt;
&lt;my:task attr="${ant.refid:anturl}"/&gt;
</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


+ 15
- 0
src/main/org/apache/tools/ant/PropertyHelper.java View File

@@ -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);


+ 104
- 0
src/tests/antunit/core/ref-propertyhelper-test.xml View File

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

Loading…
Cancel
Save