Author: mbenson Date: Tue Jul 17 14:37:53 2007 New Revision: 557063 URL: http://svn.apache.org/viewvc?view=rev&rev=557063 Log: refactor Properties to use current PH API; allow non-String values
Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Property.java Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Property.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Property.java?view=diff&rev=557063&r1=557062&r2=557063 ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Property.java (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Property.java Tue Jul 17 14:37:53 2007 @@ -15,7 +15,6 @@ * limitations under the License. * */ - package org.apache.tools.ant.taskdefs; import java.io.File; @@ -24,6 +23,9 @@ import java.io.InputStream; import java.net.URL; import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import java.util.Properties; import java.util.Stack; import java.util.Vector; @@ -69,6 +71,59 @@ * @ant.task category="property" */ public class Property extends Task { + private class PropertyResolver implements PropertyHelper.PropertyEvaluator { + private ThreadLocal getStack = new ThreadLocal() { + protected Object initialValue() { + return new Stack(); + } + }; + private ThreadLocal replaceStack = new ThreadLocal() { + protected Object initialValue() { + return new Stack(); + } + }; + private Map map; + + /** + * Construct a new Property.PropertyResolver instance. + */ + public PropertyResolver(Map map) { + this.map = map; + } + + /* (non-Javadoc) + * @see org.apache.tools.ant.PropertyHelper.PropertyEvaluator#evaluate(java.lang.String, org.apache.tools.ant.PropertyHelper) + */ + public Object evaluate(String property, PropertyHelper propertyHelper) { + //our feeble properties don't matter if the PropertyHelper can resolve the property without us: + Stack stk = (Stack) getStack.get(); + if (stk.contains(property)) { + return null; + } + stk.push(property); + try { + if (propertyHelper.getProperty(property) != null) { + return null; + } + } finally { + stk.pop(); + } + Object value = map.get(property); + if (!(value instanceof String)) { + return null; + } + stk = (Stack) replaceStack.get(); + if (stk.contains(property)) { + throw new BuildException("Property " + name + " was circularly defined."); + } + stk.push(property); + try { + return propertyHelper.replaceProperties((String) value); + } finally { + stk.pop(); + } + } + } // CheckStyle:VisibilityModifier OFF - bc protected String name; @@ -81,6 +136,7 @@ protected Reference ref; protected String prefix; private Project fallback; + private Object untypedValue; protected boolean userProperty; // set read-only properties // CheckStyle:VisibilityModifier ON @@ -143,14 +199,28 @@ setValue(location.getAbsolutePath()); } + /* the following method is first in source so IH will pick it up first: + * Hopefully we'll never get any classes compiled by wise-guy compilers that behave otherwise... + */ + + /** + * Set the value of the property. + * @param value + */ + public void setValue(Object value) { + this.untypedValue = value; + //preserve protected string value for subclasses :( + this.value = value == null ? null : value.toString(); + } + /** - * The value of the property. + * Set the value of the property as a String. * @param value value to assign * * @ant.attribute group="name" */ public void setValue(String value) { - this.value = value; + setValue((Object) value); } /** @@ -365,7 +435,7 @@ } if (name != null) { - if (value == null && ref == null) { + if (untypedValue == null && ref == null) { throw new BuildException("You must specify value, location or " + "refid with the name attribute", getLocation()); @@ -383,8 +453,8 @@ + "a url, file or resource", getLocation()); } - if ((name != null) && (value != null)) { - addProperty(name, value); + if (name != null && untypedValue != null) { + addProperty(name, untypedValue); } if (file != null) { @@ -544,19 +614,17 @@ * @param props the properties to iterate over */ protected void addProperties(Properties props) { - resolveAllProperties(props); - Enumeration e = props.keys(); - while (e.hasMoreElements()) { - String propertyName = (String) e.nextElement(); - String propertyValue = props.getProperty(propertyName); - - String v = getProject().replaceProperties(propertyValue); - - if (prefix != null) { - propertyName = prefix + propertyName; + HashMap m = new HashMap(props); + resolveAllProperties(m); + for (Iterator it = m.keySet().iterator(); it.hasNext();) { + Object k = it.next(); + if (k instanceof String) { + String propertyName = (String) k; + if (prefix != null) { + propertyName = prefix + propertyName; + } + addProperty(propertyName, m.get(k)); } - - addProperty(propertyName, v); } } @@ -566,14 +634,25 @@ * @param v value to set */ protected void addProperty(String n, String v) { + addProperty(n, (Object) v); + } + + /** + * add a name value pair to the project property set + * @param n name of property + * @param v value to set + * @since Ant 1.8 + */ + protected void addProperty(String n, Object v) { + PropertyHelper ph = PropertyHelper.getPropertyHelper(getProject()); if (userProperty) { - if (getProject().getUserProperty(n) == null) { - getProject().setInheritedProperty(n, v); + if (ph.getUserProperty(n) == null) { + ph.setInheritedProperty(n, v); } else { log("Override ignored for " + n, Project.MSG_VERBOSE); } } else { - getProject().setNewProperty(n, v); + ph.setNewProperty(n, v); } } @@ -581,62 +660,17 @@ * resolve properties inside a properties hashtable * @param props properties object to resolve */ - private void resolveAllProperties(Properties props) throws BuildException { - for (Enumeration e = props.keys(); e.hasMoreElements();) { - String propertyName = (String) e.nextElement(); - Stack referencesSeen = new Stack(); - resolve(props, propertyName, referencesSeen); - } - } - - /** - * Recursively expand the named property using the project's - * reference table and the given set of properties - fail if a - * circular definition is detected. - * - * @param props properties object to resolve - * @param name of the property to resolve - * @param referencesSeen stack of all property names that have - * been tried to expand before coming here. - */ - private void resolve(Properties props, String name, Stack referencesSeen) - throws BuildException { - if (referencesSeen.contains(name)) { - throw new BuildException("Property " + name + " was circularly " - + "defined."); - } - - String propertyValue = props.getProperty(name); - Vector fragments = new Vector(); - Vector propertyRefs = new Vector(); - PropertyHelper.getPropertyHelper( - this.getProject()).parsePropertyString( - propertyValue, fragments, propertyRefs); - - if (propertyRefs.size() != 0) { - referencesSeen.push(name); - StringBuffer sb = new StringBuffer(); - Enumeration i = fragments.elements(); - Enumeration j = propertyRefs.elements(); - while (i.hasMoreElements()) { - String fragment = (String) i.nextElement(); - if (fragment == null) { - String propertyName = (String) j.nextElement(); - fragment = getProject().getProperty(propertyName); - if (fragment == null) { - if (props.containsKey(propertyName)) { - resolve(props, propertyName, referencesSeen); - fragment = props.getProperty(propertyName); - } else { - fragment = "${" + propertyName + "}"; - } - } - } - sb.append(fragment); + private void resolveAllProperties(Map props) throws BuildException { + PropertyHelper propertyHelper = (PropertyHelper) PropertyHelper.getPropertyHelper( + getProject()).clone(); + propertyHelper.add(new PropertyResolver(props)); + for (Iterator it = props.keySet().iterator(); it.hasNext();) { + Object k = it.next(); + if (k instanceof String) { + Object value = propertyHelper.getProperty((String) k); + props.put(k, value); } - propertyValue = sb.toString(); - props.put(name, propertyValue); - referencesSeen.pop(); } } + } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]