diff --git a/WHATSNEW b/WHATSNEW index 56043496a..a9114062e 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -46,6 +46,8 @@ Other changes: nested FileNameMapper implementations directly, allowing a usage comparable to those of , , and . +* New attribute "negate" on to invert selection criteria. + Changes from Ant 1.6.1 to current Ant 1.6 CVS version ============================================= diff --git a/docs/manual/CoreTypes/propertyset.html b/docs/manual/CoreTypes/propertyset.html index 0ff6f1fd2..3353579d9 100644 --- a/docs/manual/CoreTypes/propertyset.html +++ b/docs/manual/CoreTypes/propertyset.html @@ -25,6 +25,14 @@ supports this.

is used. Default is "true". No + + negate + Whether to negate results. If + "true", all properties not + selected by nested elements will be returned. + Default is "false". + No +

Parameters specified as nested elements

@@ -107,6 +115,9 @@ keys, for example:

collects all properties whose name starts with "foo", but changes the names to start with "bar" instead.

+

If supplied, the nested mapper will be applied +subsequent to any negation of matched properties.

+

Copyright © 2003-2004 The Apache Software Foundation. All rights Reserved.

diff --git a/src/etc/testcases/taskdefs/optional/echoproperties.xml b/src/etc/testcases/taskdefs/optional/echoproperties.xml index 265c4f5d9..3466642cf 100644 --- a/src/etc/testcases/taskdefs/optional/echoproperties.xml +++ b/src/etc/testcases/taskdefs/optional/echoproperties.xml @@ -72,6 +72,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/main/org/apache/tools/ant/types/PropertySet.java b/src/main/org/apache/tools/ant/types/PropertySet.java index 835bda21a..17426b131 100644 --- a/src/main/org/apache/tools/ant/types/PropertySet.java +++ b/src/main/org/apache/tools/ant/types/PropertySet.java @@ -18,6 +18,9 @@ package org.apache.tools.ant.types; import java.util.Enumeration; +import java.util.Iterator; +import java.util.HashSet; +import java.util.Set; import java.util.Hashtable; import java.util.Properties; import java.util.Stack; @@ -25,6 +28,7 @@ import java.util.Vector; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; +import org.apache.tools.ant.PropertyHelper; import org.apache.tools.ant.util.FileNameMapper; import org.apache.tools.ant.util.regexp.RegexpMatcher; import org.apache.tools.ant.util.regexp.RegexpMatcherFactory; @@ -37,7 +41,8 @@ import org.apache.tools.ant.util.regexp.RegexpMatcherFactory; public class PropertySet extends DataType { private boolean dynamic = true; - private Vector cachedNames; + private boolean negate = false; + private Set cachedNames; private Vector ptyRefs = new Vector(); private Vector setRefs = new Vector(); private Mapper _mapper; @@ -145,6 +150,11 @@ public class PropertySet extends DataType { this.dynamic = dynamic; } + public void setNegate(boolean negate) { + assertNotReference(); + this.negate = negate; + } + public boolean getDynamic() { return isReference() ? getRef().dynamic : dynamic; } @@ -154,19 +164,29 @@ public class PropertySet extends DataType { } public Properties getProperties() { - Vector names = null; + Set names = null; Project prj = getProject(); Hashtable props = prj == null ? System.getProperties() : prj.getProperties(); if (getDynamic() || cachedNames == null) { - names = new Vector(); // :TODO: should be a Set! + names = new HashSet(); if (isReference()) { getRef().addPropertyNames(names, props); } else { addPropertyNames(names, props); } - + // Add this PropertySet's nested PropertySets' property names. + for (Enumeration e = setRefs.elements(); e.hasMoreElements();) { + PropertySet set = (PropertySet) e.nextElement(); + names.addAll(set.getProperties().keySet()); + } + if (negate) { + //make a copy... + HashSet complement = new HashSet(props.keySet()); + complement.removeAll(names); + names = complement; + } if (!getDynamic()) { cachedNames = names; } @@ -180,8 +200,8 @@ public class PropertySet extends DataType { mapper = myMapper.getImplementation(); } Properties properties = new Properties(); - for (Enumeration e = names.elements(); e.hasMoreElements();) { - String name = (String) e.nextElement(); + for (Iterator iter = names.iterator(); iter.hasNext();) { + String name = (String) iter.next(); String value = (String) props.get(name); if (mapper != null) { String[] newname = mapper.mapFileName(name); @@ -195,12 +215,12 @@ public class PropertySet extends DataType { } /** - * @param names the output vector to fill with the property names + * @param names the output Set to fill with the property names * matching this PropertySet selection criteria. * @param properties the current Project properties, passed in to * avoid needless duplication of the Hashtable during recursion. */ - private void addPropertyNames(Vector names, Hashtable properties) { + private void addPropertyNames(Set names, Hashtable properties) { Project prj = getProject(); // Add this PropertySet's property names. @@ -208,13 +228,13 @@ public class PropertySet extends DataType { PropertyRef ref = (PropertyRef) e.nextElement(); if (ref.name != null) { if (prj != null && prj.getProperty(ref.name) != null) { - names.addElement(ref.name); + names.add(ref.name); } } else if (ref.prefix != null) { for (Enumeration p = properties.keys(); p.hasMoreElements();) { String name = (String) p.nextElement(); if (name.startsWith(ref.prefix)) { - names.addElement(name); + names.add(name); } } } else if (ref.regex != null) { @@ -224,38 +244,26 @@ public class PropertySet extends DataType { for (Enumeration p = properties.keys(); p.hasMoreElements();) { String name = (String) p.nextElement(); if (matcher.matches(name)) { - names.addElement(name); + names.add(name); } } } else if (ref.builtin != null) { - Enumeration e2 = null; if (ref.builtin.equals(BuiltinPropertySetName.ALL)) { - e2 = properties.keys(); + names.addAll(properties.keySet()); } else if (ref.builtin.equals(BuiltinPropertySetName.SYSTEM)) { - e2 = System.getProperties().keys(); + names.addAll(System.getProperties().keySet()); } else if (ref.builtin.equals(BuiltinPropertySetName .COMMANDLINE)) { - e2 = getProject().getUserProperties().keys(); + names.addAll(getProject().getUserProperties().keySet()); } else { throw new BuildException("Impossible: Invalid builtin " + "attribute!"); } - - while (e2.hasMoreElements()) { - names.addElement(e2.nextElement()); - } - } else { throw new BuildException("Impossible: Invalid PropertyRef!"); } } - - // Add this PropertySet's nested PropertySets' property names. - for (Enumeration e = setRefs.elements(); e.hasMoreElements();) { - PropertySet set = (PropertySet) e.nextElement(); - set.addPropertyNames(names, properties); - } } /** diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/EchoPropertiesTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/EchoPropertiesTest.java index eba3d9a26..1ccdaff7d 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/optional/EchoPropertiesTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/EchoPropertiesTest.java @@ -141,20 +141,28 @@ public class EchoPropertiesTest extends BuildFileTest { public void testEchoPrefix() throws Exception { - executeTarget( "testEchoPrefix" ); - Properties props=loadPropFile(PREFIX_OUTFILE); -// props.list(System.out); - assertEquals("prefix didn't include 'a.set' property","true",props.getProperty("a.set")); - assertNull("prefix failed to filter out property 'b.set'", - props.getProperty("b.set")); + testEchoPrefixVarious("testEchoPrefix"); } public void testEchoPrefixAsPropertyset() throws Exception { - executeTarget( "testEchoPrefixAsPropertyset" ); - Properties props=loadPropFile(PREFIX_OUTFILE); - assertEquals("prefix didn't include 'a.set' property","true",props.getProperty("a.set")); + testEchoPrefixVarious("testEchoPrefixAsPropertyset"); + } + + public void testEchoPrefixAsNegatedPropertyset() throws Exception { + testEchoPrefixVarious("testEchoPrefixAsNegatedPropertyset"); + } + + public void testEchoPrefixAsDoublyNegatedPropertyset() throws Exception { + testEchoPrefixVarious("testEchoPrefixAsDoublyNegatedPropertyset"); + } + + private void testEchoPrefixVarious(String target) throws Exception { + executeTarget(target); + Properties props = loadPropFile(PREFIX_OUTFILE); + assertEquals("prefix didn't include 'a.set' property", + "true", props.getProperty("a.set")); assertNull("prefix failed to filter out property 'b.set'", - props.getProperty("b.set")); + props.getProperty("b.set")); } protected Properties loadPropFile(String relativeFilename)