Index: src/main/org/apache/tools/ant/PropertyHelper.java =================================================================== --- src/main/org/apache/tools/ant/PropertyHelper.java (revision 428601) +++ src/main/org/apache/tools/ant/PropertyHelper.java (working copy) @@ -18,6 +18,8 @@ package org.apache.tools.ant; import java.util.Hashtable; +import java.util.Properties; +import java.util.Stack; import java.util.Vector; import java.util.Enumeration; @@ -411,6 +413,145 @@ properties.put(name, value); } + /** + * Set a new inherited user property, which cannot be overwritten + * by set/unset property calls. If a user property with the + * same name is already present the value is not overridden. + * Also marks this property as a property that has not come + * from the command line. + * + * @param ns The namespace for the property (currently not used). + * @param n Name of property + * @param v Value to set + */ + public synchronized void setNewInheritedProperty(String ns, + String n, String v) { + if (getUserProperty(null, n) == null) { + setInheritedProperty(null, n, v); + } else { + project.log("Override ignored for " + n, Project.MSG_VERBOSE); + } + } + + /** + * Adds a set of unexpanded properties. + *

The properties are resolved, prefixed, expanded and added with + * {@link #setNewProperty(String, String, Object)}.

+ * @param props The unexpanded properties. + * @param prefix The prefix to add to each property name + * after properties resolved. + * null if no prefix. + */ + public synchronized void addNewProperties(String ns + , Properties props, String prefix) { + addUnexpandedProperties(ns, props, prefix, false); + } + + /** + * Adds a set of unexpanded inherited user properties. + *

The properties are resolved, prefixed, expanded and added with + * {@link #setNewInheritedProperty(String, String, String)}.

+ * @param props The unexpanded inherited user properties. + * @param prefix The prefix to add to each property name + * after properties resolved. + * null if no prefix. + */ + public synchronized void addNewInheritedProperties(String ns + , Properties props, String prefix) { + addUnexpandedProperties(ns, props, prefix, true); + } + + /** + * Iterate through a set of properties, + * resolve them then assign them + * @param props The properties to iterate over. + * @param prefix The prefix to add to each name. + * @param userProperties Whether to be added as user properties. + */ + private void addUnexpandedProperties(String ns + , Properties props, String prefix, boolean userProperties) { + resolveAllProperties(props); + Enumeration e = props.keys(); + while (e.hasMoreElements()) { + String propertyName = (String) e.nextElement(); + String propertyValue = props.getProperty(propertyName); + + String v = replaceProperties(null, propertyValue, null); + + if (prefix != null) { + propertyName = prefix + propertyName; + } + + if (userProperties) { + setNewInheritedProperty(null, propertyName, v); + } else { + setNewProperty(null, propertyName, v); + } + } + } + + /** + * 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 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(); + 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(); + Object o = getProperty(null, propertyName); + fragment = (o == null) ? null : o.toString(); + if (fragment == null) { + if (props.containsKey(propertyName)) { + resolve(props, propertyName, referencesSeen); + fragment = props.getProperty(propertyName); + } else { + fragment = "${" + propertyName + "}"; + } + } + } + sb.append(fragment); + } + propertyValue = sb.toString(); + props.put(name, propertyValue); + referencesSeen.pop(); + } + } + // -------------------- Getting properties -------------------- /** Index: src/main/org/apache/tools/ant/taskdefs/Property.java =================================================================== --- src/main/org/apache/tools/ant/taskdefs/Property.java (revision 428601) +++ src/main/org/apache/tools/ant/taskdefs/Property.java (working copy) @@ -24,7 +24,6 @@ import java.net.URL; import java.util.Enumeration; import java.util.Properties; -import java.util.Stack; import java.util.Vector; import org.apache.tools.ant.BuildException; @@ -535,103 +534,31 @@ } /** - * iterate through a set of properties, - * resolve them then assign them - * @param props the properties to iterate over + * Add the properties to the property helper + * @param props the properties to add */ 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; - } - - addProperty(propertyName, v); + PropertyHelper ph = PropertyHelper.getPropertyHelper(getProject()); + if (userProperty) { + ph.addNewInheritedProperties(null, props, prefix); + } else { + ph.addNewProperties(null, props, prefix); } } /** - * add a name value pair to the project property set + * Add a name value pair to the property helper + * * @param n name of property * @param v value to set */ protected void addProperty(String n, String v) { + PropertyHelper ph = PropertyHelper.getPropertyHelper(getProject()); if (userProperty) { - if (getProject().getUserProperty(n) == null) { - getProject().setInheritedProperty(n, v); - } else { - log("Override ignored for " + n, Project.MSG_VERBOSE); - } + ph.setNewInheritedProperty(null, n, v); } else { - getProject().setNewProperty(n, v); + ph.setNewProperty(null, n, v); } } - /** - * 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); - } - propertyValue = sb.toString(); - props.put(name, propertyValue); - referencesSeen.pop(); - } - } }