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