From 12d618105703b0a76f3d6f2efbc48e7f2bf48a8b Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 4 Sep 2009 08:41:56 +0000 Subject: [PATCH] Improve PropertyHelper documentation git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@811283 13f79535-47bb-0310-9956-ffa450edef68 --- docs/manual/CoreTasks/propertyhelper.html | 44 ++++++++- docs/manual/using.html | 91 +++++++++++++------ .../org/apache/tools/ant/PropertyHelper.java | 80 ++++++++++++---- 3 files changed, 165 insertions(+), 50 deletions(-) diff --git a/docs/manual/CoreTasks/propertyhelper.html b/docs/manual/CoreTasks/propertyhelper.html index f6c1800fa..141b34c6f 100644 --- a/docs/manual/CoreTasks/propertyhelper.html +++ b/docs/manual/CoreTasks/propertyhelper.html @@ -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 Property Helper for more information. -Since Ant 1.8

+Since Ant 1.8.0

Parameters specified as nested elements

@@ -47,7 +47,8 @@ is a marker interface only: the nested arguments must implement a Delegate subinterface in order to do anything meaningful.

delegate

-A generic <delegate> element is also provided: +

A generic <delegate> element which can use project references +is also provided:

Parameters
@@ -63,6 +64,45 @@ A generic <delegate> element is also provided:
+

Examples

+ +

Install a completely different PropertyHelper implementation + (assuming MyPropertyHelper extends PropertyHelper):

+ +
+<componentdef classname="org.example.MyPropertyHelper"
+              name="mypropertyhelper"/>
+<propertyhelper>
+  <mypropertyhelper/>
+</propertyhelper>
+
+ +

Add a new PropertyEvaluator delegate + (assuming MyPropertyEvaluator implements + PropertyHelper.PropertyEvaluator). 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.

+ +
+<componentdef classname="org.example.MyPropertyEvaluator"
+              name="mypropertyevaluator"/>
+<propertyhelper>
+  <mypropertyevaluator/>
+</propertyhelper>
+
+ +

Add a new PropertyEvaluator delegate using the refid syntax:

+ +
+<typedef classname="org.example.MyPropertyEvaluator"
+         name="mypropertyevaluator"/>
+<mypropertyevaluator id="evaluator"/>
+<propertyhelper>
+  <delegate refid="evaluator"/>
+</propertyhelper>
+
+ diff --git a/docs/manual/using.html b/docs/manual/using.html index 32b790b66..c58832cc5 100644 --- a/docs/manual/using.html +++ b/docs/manual/using.html @@ -346,39 +346,52 @@ new propertyhelper task used to mani PropertyHelper and its delegates from the context of the Ant buildfile.

There are three sub-interfaces of Delegate that may be - useful to - implement. org.apache.tools.ant.PropertyHelper$PropertyEvaluator - is used to expand ${some-string} into - an Object - while org.apache.tools.ant.PropertyHelper$PropertySetter - is responsible for setting properties. - Finally org.apache.tools.ant.property.PropertyExpander - is responsible for finding the property name inside a string in the - first place (the default extracts foo - from ${foo}).

+ useful to implement.

-

The logic that replaces ${toString:some-id} with the - stringified representation of the object with - id some-id inside the current build is contained in a - PropertyEvaluator similar to the following code:

+

The default PropertyExpander looks similar to:

@@ -401,6 +414,24 @@ public class DefaultExpander implements PropertyExpander { } +

The logic that replaces ${toString:some-id} with the + stringified representation of the object with + id some-id inside the current build is contained in a + PropertyEvaluator similar to the following code:

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

Example Buildfile

 <project name="MyProject" default="dist" basedir=".">
diff --git a/src/main/org/apache/tools/ant/PropertyHelper.java b/src/main/org/apache/tools/ant/PropertyHelper.java
index 102f1759b..bbf7a4924 100644
--- a/src/main/org/apache/tools/ant/PropertyHelper.java
+++ b/src/main/org/apache/tools/ant/PropertyHelper.java
@@ -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.
+ * 

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.

+ * + *

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.

+ * + *

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.

+ * + *

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.

* * @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. + * + *

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 + * ${toString:refid} syntax.

+ * + * @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 null 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. + * + *

Can be used to store properties in a different storage than + * the project instance (like local properties for example).

+ * + * @since Ant 1.8.0 */ public interface PropertySetter extends Delegate { /** * Set a *new" property. + * + *

Should not replace the value of an existing property.

+ * * @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. + * + *

May replace the value of an existing property.

+ * * @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 null. * @param value The new value of the property. * Must not be null. - * @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 - * @since Ant 1.8 + * @since Ant 1.8.0 */ protected static Set getDelegateInterfaces(Delegate d) { HashSet result = new HashSet();