git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@811283 13f79535-47bb-0310-9956-ffa450edef68master
@@ -32,7 +32,7 @@ | |||
PropertyHelper active on the current Project. This is somewhat advanced Ant usage and | |||
assumes a working familiarity with the modern Ant APIs. See the description of Ant's | |||
<a href="../using.html#propertyHelper">Property Helper</a> for more information. | |||
<b>Since Ant 1.8</b></p> | |||
<b>Since Ant 1.8.0</b></p> | |||
<h3>Parameters specified as nested elements</h3> | |||
@@ -47,7 +47,8 @@ is a marker interface only: the nested arguments must implement a <code>Delegate | |||
subinterface in order to do anything meaningful. | |||
<h4>delegate</h4> | |||
A generic <delegate> element is also provided: | |||
<p>A generic <delegate> element which can use project references | |||
is also provided:</p> | |||
<h5>Parameters</h5> | |||
<table border="1" cellpadding="2" cellspacing="0"> | |||
@@ -63,6 +64,45 @@ A generic <delegate> element is also provided: | |||
</tr> | |||
</table> | |||
<h3>Examples</h3> | |||
<p>Install a completely different PropertyHelper implementation | |||
(assuming <code>MyPropertyHelper extends PropertyHelper</code>):</p> | |||
<pre> | |||
<componentdef classname="org.example.MyPropertyHelper" | |||
name="mypropertyhelper"/> | |||
<propertyhelper> | |||
<mypropertyhelper/> | |||
</propertyhelper> | |||
</pre> | |||
<p>Add a new PropertyEvaluator delegate | |||
(assuming <code>MyPropertyEvaluator implements | |||
PropertyHelper.PropertyEvaluator</code>). Note that PropertyHelper | |||
uses the configured delegates in LIFO order. I.e. the delegate | |||
added by this task will be consulted before any previously defined | |||
delegate and in particular before the built-in ones.</p> | |||
<pre> | |||
<componentdef classname="org.example.MyPropertyEvaluator" | |||
name="mypropertyevaluator"/> | |||
<propertyhelper> | |||
<mypropertyevaluator/> | |||
</propertyhelper> | |||
</pre> | |||
<p>Add a new PropertyEvaluator delegate using the refid syntax:</p> | |||
<pre> | |||
<typedef classname="org.example.MyPropertyEvaluator" | |||
name="mypropertyevaluator"/> | |||
<mypropertyevaluator id="evaluator"/> | |||
<propertyhelper> | |||
<delegate refid="evaluator"/> | |||
</propertyhelper> | |||
</pre> | |||
</body> | |||
</html> | |||
@@ -346,39 +346,52 @@ new <a href="CoreTasks/propertyhelper.html">propertyhelper</a> task used to mani | |||
PropertyHelper and its delegates from the context of the Ant buildfile. | |||
<p>There are three sub-interfaces of <code>Delegate</code> that may be | |||
useful to | |||
implement. <code>org.apache.tools.ant.PropertyHelper$PropertyEvaluator</code> | |||
is used to expand <code>${some-string}</code> into | |||
an <code>Object</code> | |||
while <code>org.apache.tools.ant.PropertyHelper$PropertySetter</code> | |||
is responsible for setting properties. | |||
Finally <code>org.apache.tools.ant.property.PropertyExpander</code> | |||
is responsible for finding the property name inside a string in the | |||
first place (the default extracts <code>foo</code> | |||
from <code>${foo}</code>).</p> | |||
useful to implement.</p> | |||
<p>The logic that replaces <code>${toString:some-id}</code> with the | |||
stringified representation of the object with | |||
id <code>some-id</code> inside the current build is contained in a | |||
PropertyEvaluator similar to the following code:</p> | |||
<ul> | |||
<li><code>org.apache.tools.ant.property.PropertyExpander</code> is | |||
responsible for finding the property name inside a string in the | |||
first place (the default extracts <code>foo</code> | |||
from <code>${foo}</code>). | |||
<p>This is the interface you'd implement if you wanted to invent | |||
your own property syntax - or allow nested property expansions | |||
since the default implementation doesn't balance braces | |||
(see <a href="http://svn.apache.org/viewvc/ant/sandbox/antlibs/props/trunk/src/main/org/apache/ant/props/NestedPropertyExpander.java?view=log"><code>NestedPropertyExpander</code> | |||
in the "props" Antlib in Ant's sandbox</a> for an | |||
example).</p> | |||
</li> | |||
<pre> | |||
public class ToStringEvaluator implements PropertyHelper.PropertyEvaluator { | |||
private static final String prefix = "toString:"; | |||
public Object evaluate(String property, PropertyHelper propertyHelper) { | |||
Object o = null; | |||
if (property.startsWith(prefix) && propertyHelper.getProject() != null) { | |||
o = propertyHelper.getProject().getReference(property.substring(prefix.length())); | |||
} | |||
return o == null ? null : o.toString(); | |||
} | |||
} | |||
</pre> | |||
<li><code>org.apache.tools.ant.PropertyHelper$PropertyEvaluator</code> | |||
is used to expand <code>${some-string}</code> into | |||
an <code>Object</code>. | |||
<p>This is the interface you'd implement if you want to provide | |||
your own storage independent of Ant's project instance - the | |||
interface represents the reading end. An example for this would | |||
be <code>org.apache.tools.ant.property.LocalProperties</code> | |||
which implements storage | |||
for <a href="CoreTasks/local.html">local properties</a>.</p> | |||
<p>Another reason to implement this interface is if you wanted to | |||
provide your own "property protocol" like | |||
expanding <code>toString:foo</code> by looking up the project | |||
reference foo and invoking <code>toString()</code> on it (which | |||
is already implemented in Ant, see below).</p> | |||
</li> | |||
<p>An example of a <code>PropertySetter</code> can be found | |||
in <code>org.apache.tools.ant.property.LocalProperties</code> which | |||
implements storage for <a href="CoreTasks/local.html">local | |||
properties</a>.</p> | |||
<li><code>org.apache.tools.ant.PropertyHelper$PropertySetter</code> | |||
is responsible for setting properties. | |||
<p>This is the interface you'd implement if you want to provide | |||
your own storage independent of Ant's project instance - the | |||
interface represents the reading end. An example for this would | |||
be <code>org.apache.tools.ant.property.LocalProperties</code> | |||
which implements storage | |||
for <a href="CoreTasks/local.html">local properties</a>.</p> | |||
</li> | |||
</ul> | |||
<p>The default <code>PropertyExpander</code> looks similar to:</p> | |||
@@ -401,6 +414,24 @@ public class DefaultExpander implements PropertyExpander { | |||
} | |||
</pre> | |||
<p>The logic that replaces <code>${toString:some-id}</code> with the | |||
stringified representation of the object with | |||
id <code>some-id</code> inside the current build is contained in a | |||
PropertyEvaluator similar to the following code:</p> | |||
<pre> | |||
public class ToStringEvaluator implements PropertyHelper.PropertyEvaluator { | |||
private static final String prefix = "toString:"; | |||
public Object evaluate(String property, PropertyHelper propertyHelper) { | |||
Object o = null; | |||
if (property.startsWith(prefix) && propertyHelper.getProject() != null) { | |||
o = propertyHelper.getProject().getReference(property.substring(prefix.length())); | |||
} | |||
return o == null ? null : o.toString(); | |||
} | |||
} | |||
</pre> | |||
<a name="example"><h3>Example Buildfile</h3></a> | |||
<pre> | |||
<project name="MyProject" default="dist" basedir="."> | |||
@@ -48,7 +48,7 @@ import org.apache.tools.ant.property.ParseProperties; | |||
Need to discuss this and find if we need more. | |||
*/ | |||
/* update for impending Ant 1.8: | |||
/* update for impending Ant 1.8.0: | |||
- I can't see any reason for ns and would like to deprecate it. | |||
- Replacing chaining with delegates for certain behavioral aspects. | |||
@@ -56,12 +56,35 @@ import org.apache.tools.ant.property.ParseProperties; | |||
*/ | |||
/** NOT FINAL. API MAY CHANGE | |||
* | |||
/** | |||
* Deals with properties - substitution, dynamic properties, etc. | |||
* | |||
* This is the same code as in Ant1.5. The main addition is the ability | |||
* to chain multiple PropertyHelpers and to replace the default. | |||
* <p>This code has been heavily restructured for Ant 1.8.0. It is | |||
* expected that custom PropertyHelper implementation that used the | |||
* older chaining mechanism of Ant 1.6 won't work in all cases, and | |||
* its usage is deprecated. The preferred way to customize Ant's | |||
* property handling is by {@link #add adding} {@link | |||
* PropertyHelper.Delegate delegates} of the appropriate subinterface | |||
* and have this implementation use them.</p> | |||
* | |||
* <p>When {@link #parseProperties expanding a string that may contain | |||
* properties} this class will delegate the actual parsing to {@link | |||
* org.apache.tools.ant.property.ParseProperties#parseProperties | |||
* parseProperties} inside the ParseProperties class which in turn | |||
* uses the {@link org.apache.tools.ant.property.PropertyExpander | |||
* PropertyExpander delegates} to find properties inside the string | |||
* and this class to expand the propertiy names found into the | |||
* corresponding values.</p> | |||
* | |||
* <p>When {@link #getProperty looking up a property value} this class | |||
* will first consult all {@link PropertyHelper.PropertyEvaluator | |||
* PropertyEvaluator} delegates and fall back to an internal map of | |||
* "project properties" if no evaluator matched the property name.</p> | |||
* | |||
* <p>When {@link #setProperty setting a property value} this class | |||
* will first consult all {@link PropertyHelper.PropertySetter | |||
* PropertySetter} delegates and fall back to an internal map of | |||
* "project properties" if no setter matched the property name.</p> | |||
* | |||
* @since Ant 1.6 | |||
*/ | |||
@@ -75,32 +98,50 @@ public class PropertyHelper implements GetProperty { | |||
/** | |||
* Marker interface for a PropertyHelper delegate. | |||
* @since Ant 1.8 | |||
* @since Ant 1.8.0 | |||
*/ | |||
public interface Delegate { | |||
} | |||
/** | |||
* Describes an entity capable of evaluating a property name for value. | |||
* @since Ant 1.8 | |||
* Looks up a property's value based on its name. | |||
* | |||
* <p>Can be used to look up properties in a different storage | |||
* than the project instance (like local properties for example) | |||
* or to implement custom "protocols" like Ant's | |||
* <code>${toString:refid}</code> syntax.</p> | |||
* | |||
* @since Ant 1.8.0 | |||
*/ | |||
public interface PropertyEvaluator extends Delegate { | |||
/** | |||
* Evaluate a property. | |||
* | |||
* @param property the property's String "identifier". | |||
* @param propertyHelper the invoking PropertyHelper. | |||
* @return Object value. | |||
* @return null if the property name could not be found, an | |||
* instance of {@link org.apache.tools.ant.property.NullReturn | |||
* NullReturn} to indicate a property with a name that can be | |||
* matched but a value of <code>null</code> and the property's | |||
* value otherwise. | |||
*/ | |||
Object evaluate(String property, PropertyHelper propertyHelper); | |||
} | |||
/** | |||
* Describes an entity capable of setting a property to a value. | |||
* @since Ant 1.8 | |||
* Sets or overrides a property. | |||
* | |||
* <p>Can be used to store properties in a different storage than | |||
* the project instance (like local properties for example).</p> | |||
* | |||
* @since Ant 1.8.0 | |||
*/ | |||
public interface PropertySetter extends Delegate { | |||
/** | |||
* Set a *new" property. | |||
* | |||
* <p>Should not replace the value of an existing property.</p> | |||
* | |||
* @param property the property's String "identifier". | |||
* @param value the value to set. | |||
* @param propertyHelper the invoking PropertyHelper. | |||
@@ -111,6 +152,9 @@ public class PropertyHelper implements GetProperty { | |||
/** | |||
* Set a property. | |||
* | |||
* <p>May replace the value of an existing property.</p> | |||
* | |||
* @param property the property's String "identifier". | |||
* @param value the value to set. | |||
* @param propertyHelper the invoking PropertyHelper. | |||
@@ -217,7 +261,7 @@ public class PropertyHelper implements GetProperty { | |||
* @param project the project in question. | |||
* @param name the property name | |||
* @return the value of the property if present, null otherwise. | |||
* @since Ant 1.8 | |||
* @since Ant 1.8.0 | |||
*/ | |||
public static Object getProperty(Project project, String name) { | |||
return PropertyHelper.getPropertyHelper(project) | |||
@@ -230,7 +274,7 @@ public class PropertyHelper implements GetProperty { | |||
* @param project the project in question. | |||
* @param name the property name | |||
* @param value the value to use. | |||
* @since Ant 1.8 | |||
* @since Ant 1.8.0 | |||
*/ | |||
public static void setProperty(Project project, String name, Object value) { | |||
PropertyHelper.getPropertyHelper(project) | |||
@@ -243,7 +287,7 @@ public class PropertyHelper implements GetProperty { | |||
* @param project the project in question. | |||
* @param name the property name | |||
* @param value the value to use. | |||
* @since Ant 1.8 | |||
* @since Ant 1.8.0 | |||
*/ | |||
public static void setNewProperty( | |||
Project project, String name, Object value) { | |||
@@ -580,7 +624,7 @@ public class PropertyHelper implements GetProperty { | |||
* Must not be <code>null</code>. | |||
* @param value The new value of the property. | |||
* Must not be <code>null</code>. | |||
* @since Ant 1.8 | |||
* @since Ant 1.8.0 | |||
*/ | |||
public void setNewProperty(String name, Object value) { | |||
for (Iterator iter = getDelegates(PropertySetter.class).iterator(); | |||
@@ -932,7 +976,7 @@ public class PropertyHelper implements GetProperty { | |||
* Add the specified delegate object to this PropertyHelper. | |||
* Delegates are processed in LIFO order. | |||
* @param delegate the delegate to add. | |||
* @since Ant 1.8 | |||
* @since Ant 1.8.0 | |||
*/ | |||
public void add(Delegate delegate) { | |||
synchronized (delegates) { | |||
@@ -957,7 +1001,7 @@ public class PropertyHelper implements GetProperty { | |||
* @param type | |||
* delegate type. | |||
* @return Collection. | |||
* @since Ant 1.8 | |||
* @since Ant 1.8.0 | |||
*/ | |||
protected List getDelegates(Class type) { | |||
List r = (List) delegates.get(type); | |||
@@ -968,7 +1012,7 @@ public class PropertyHelper implements GetProperty { | |||
* Get all Delegate interfaces (excluding Delegate itself) from the specified Delegate. | |||
* @param d the Delegate to inspect. | |||
* @return Set<Class> | |||
* @since Ant 1.8 | |||
* @since Ant 1.8.0 | |||
*/ | |||
protected static Set getDelegateInterfaces(Delegate d) { | |||
HashSet result = new HashSet(); | |||