diff --git a/src/main/org/apache/tools/ant/property/ParseNextProperty.java b/src/main/org/apache/tools/ant/property/ParseNextProperty.java index c39118daa..5e5dfc07d 100644 --- a/src/main/org/apache/tools/ant/property/ParseNextProperty.java +++ b/src/main/org/apache/tools/ant/property/ParseNextProperty.java @@ -22,7 +22,8 @@ import java.text.ParsePosition; import org.apache.tools.ant.Project; /** - * Interface to parse a property. + * Helper for {@link PropertyExpander PropertyExpander} that can be + * used to expand property references to values. * @since Ant 1.8.0 */ public interface ParseNextProperty { diff --git a/src/main/org/apache/tools/ant/property/ParseProperties.java b/src/main/org/apache/tools/ant/property/ParseProperties.java index 7f54bd2fc..b955f6347 100644 --- a/src/main/org/apache/tools/ant/property/ParseProperties.java +++ b/src/main/org/apache/tools/ant/property/ParseProperties.java @@ -24,6 +24,7 @@ import org.apache.tools.ant.Project; /** * Parse properties using a collection of expanders. + * * @since Ant 1.8.0 */ public class ParseProperties implements ParseNextProperty { @@ -53,9 +54,33 @@ public class ParseProperties implements ParseNextProperty { } /** - * Decode properties from a String representation. If the entire - * contents of the String resolve to a single property, that value - * is returned. Otherwise a String is returned. + * Decode properties from a String representation. + * + *
value
+ * parameter (unsurprisingly) at the beginning and asks each
+ * {@link org.apache.tools.ant.PropertyHelper.PropertyExpander
+ * PropertyExpander} whether there is a property reference at
+ * that point. PropertyExpanders return the name of a property
+ * they may find and may advance the parse position.null
the
+ * method continues with the next PropertyExpander, otherwise it
+ * tries to look up the property's value using the configured
+ * {@link GetProperty GetProperty} instance.value
is exhausted.If the entire contents of value
resolves to a
+ * single property, the looked up property value is returned.
+ * Otherwise a String is returned that concatenates the
+ * non-property parts of value
and the expanded
+ * values of the properties that have been found.
null
, in which case this
@@ -68,19 +93,20 @@ public class ParseProperties implements ParseNextProperty {
if (value == null || "".equals(value)) {
return value;
}
+ final int len = value.length();
ParsePosition pos = new ParsePosition(0);
Object o = parseNextProperty(value, pos);
- if (o != null && pos.getIndex() == value.length()) {
+ if (o != null && pos.getIndex() >= len) {
return o;
}
- StringBuffer sb = new StringBuffer(value.length() * 2);
+ StringBuffer sb = new StringBuffer(len * 2);
if (o == null) {
sb.append(value.charAt(pos.getIndex()));
pos.setIndex(pos.getIndex() + 1);
} else {
sb.append(o);
}
- while (pos.getIndex() < value.length()) {
+ while (pos.getIndex() < len) {
o = parseNextProperty(value, pos);
if (o == null) {
sb.append(value.charAt(pos.getIndex()));
@@ -94,6 +120,12 @@ public class ParseProperties implements ParseNextProperty {
/**
* Learn whether a String contains replaceable properties.
+ *
+ * Uses the configured {@link + * org.apache.tools.ant.PropertyHelper.PropertyExpander + * PropertyExpanders} and scans through the string. Returns true + * as soon as any expander finds a property.
+ * * @param value the String to check. * @returntrue
if value
contains property notation.
*/
@@ -101,7 +133,8 @@ public class ParseProperties implements ParseNextProperty {
if (value == null) {
return false;
}
- for (ParsePosition pos = new ParsePosition(0); pos.getIndex() < value.length();) {
+ final int len = value.length();
+ for (ParsePosition pos = new ParsePosition(0); pos.getIndex() < len;) {
if (parsePropertyName(value, pos) != null) {
return true;
}
@@ -113,12 +146,28 @@ public class ParseProperties implements ParseNextProperty {
/**
* Return any property that can be parsed from the specified position
* in the specified String.
+ *
+ * Uses the configured {@link + * org.apache.tools.ant.PropertyHelper.PropertyExpander + * PropertyExpanders} and {@link GetProperty GetProperty} + * instance .
+ * * @param value String to parse * @param pos ParsePosition - * @return Object or null if no property is at the current location. + * @return Object or null if no property is at the current + * location. If a property reference has been found but the + * property doesn't expand to a value, the property's name is + * returned. */ public Object parseNextProperty(String value, ParsePosition pos) { - int start = pos.getIndex(); + final int start = pos.getIndex(); + + if (start > value.length()) { + // early exit, can't find any property here, no need to + // consult all the delegates. + return null; + } + String propertyName = parsePropertyName(value, pos); if (propertyName != null) { Object result = getProperty(propertyName); diff --git a/src/main/org/apache/tools/ant/property/PropertyExpander.java b/src/main/org/apache/tools/ant/property/PropertyExpander.java index 48d256a5b..9df8f31b0 100644 --- a/src/main/org/apache/tools/ant/property/PropertyExpander.java +++ b/src/main/org/apache/tools/ant/property/PropertyExpander.java @@ -22,17 +22,30 @@ import org.apache.tools.ant.PropertyHelper; import java.text.ParsePosition; /** - * Interface to a class (normally PropertyHelper) to get a property. + * Responsible for locating a property reference inside a String. * @since Ant 1.8.0 */ public interface PropertyExpander extends PropertyHelper.Delegate { + /** - * Parse the next property name. + * Determine whether there is a property reference at the current + * ParsePosition and return its name (or null if there is none). + * + *Implementations should advance the ParsePosition to the last
+ * character that makes up the property reference. E.g. the
+ * default implementation would return "foo"
for
+ * ${foo}
and advance the ParsePosition to the
+ * }
character.
null
.
+ * @param pos the ParsePosition in use, the location is expected
+ * to be modified if a property reference has been found (and may
+ * even be modified if no reference has been found).
+ * @param parseNextProperty provides access to the Project and may
+ * be used to look up property values.
+ * @return property name if any, else null
.
*/
- String parsePropertyName(String s, ParsePosition pos, ParseNextProperty parseNextProperty);
+ String parsePropertyName(String s, ParsePosition pos,
+ ParseNextProperty parseNextProperty);
}