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)