Browse Source

Improve PropertyHelper documentation

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@811283 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 16 years ago
parent
commit
12d6181057
3 changed files with 165 additions and 50 deletions
  1. +42
    -2
      docs/manual/CoreTasks/propertyhelper.html
  2. +61
    -30
      docs/manual/using.html
  3. +62
    -18
      src/main/org/apache/tools/ant/PropertyHelper.java

+ 42
- 2
docs/manual/CoreTasks/propertyhelper.html View File

@@ -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 &lt;delegate&gt; element is also provided:
<p>A generic &lt;delegate&gt; 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 &lt;delegate&gt; element is also provided:
</tr>
</table>

<h3>Examples</h3>

<p>Install a completely different PropertyHelper implementation
(assuming <code>MyPropertyHelper extends PropertyHelper</code>):</p>

<pre>
&lt;componentdef classname="org.example.MyPropertyHelper"
name="mypropertyhelper"/>
&lt;propertyhelper>
&lt;mypropertyhelper/>
&lt;/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>
&lt;componentdef classname="org.example.MyPropertyEvaluator"
name="mypropertyevaluator"/>
&lt;propertyhelper>
&lt;mypropertyevaluator/>
&lt;/propertyhelper>
</pre>

<p>Add a new PropertyEvaluator delegate using the refid syntax:</p>

<pre>
&lt;typedef classname="org.example.MyPropertyEvaluator"
name="mypropertyevaluator"/>
&lt;mypropertyevaluator id="evaluator"/>
&lt;propertyhelper>
&lt;delegate refid="evaluator"/>
&lt;/propertyhelper>
</pre>

</body>
</html>


+ 61
- 30
docs/manual/using.html View File

@@ -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>
&lt;project name=&quot;MyProject&quot; default=&quot;dist&quot; basedir=&quot;.&quot;&gt;


+ 62
- 18
src/main/org/apache/tools/ant/PropertyHelper.java View File

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


Loading…
Cancel
Save