diff --git a/WHATSNEW b/WHATSNEW
index 16bfdf1d2..1e184fa23 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -337,6 +337,8 @@ Other changes:
* new resourcesmatch condition.
+* added the onmissingfiltersfile attribute to filterset. Bugzilla report 19845.
+
Changes from Ant 1.6.4 to Ant 1.6.5
===================================
diff --git a/docs/manual/CoreTypes/filterset.html b/docs/manual/CoreTypes/filterset.html
index 4ffe817ea..579ca0595 100644
--- a/docs/manual/CoreTypes/filterset.html
+++ b/docs/manual/CoreTypes/filterset.html
@@ -62,7 +62,7 @@ you should ensure that the set of files being filtered are all text files.
filtersfile |
Specify a single filtersfile. |
- n/a |
+ none |
No |
@@ -72,6 +72,13 @@ you should ensure that the set of files being filtered are all text files.
true |
No |
+
+ onmissingfiltersfile |
+ Indicate behavior when a nonexistent filtersfile
+ is specified. One of "fail", "warn", "ignore". Since Ant 1.7 |
+ "fail" |
+ No |
+
Filter
diff --git a/src/etc/testcases/types/filterset.xml b/src/etc/testcases/types/filterset.xml
index 4fa780af4..210bfe22d 100644
--- a/src/etc/testcases/types/filterset.xml
+++ b/src/etc/testcases/types/filterset.xml
@@ -48,10 +48,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
diff --git a/src/etc/testcases/types/filtersetd.txt b/src/etc/testcases/types/filtersetd.txt
new file mode 100644
index 000000000..45c4849ee
--- /dev/null
+++ b/src/etc/testcases/types/filtersetd.txt
@@ -0,0 +1 @@
+@foo@ @bar@ @baz@ @blah@
diff --git a/src/etc/testcases/types/filtersfile1 b/src/etc/testcases/types/filtersfile1
new file mode 100644
index 000000000..20fe058f2
--- /dev/null
+++ b/src/etc/testcases/types/filtersfile1
@@ -0,0 +1,2 @@
+foo=FOO
+bar=BAR
diff --git a/src/etc/testcases/types/filtersfile2 b/src/etc/testcases/types/filtersfile2
new file mode 100644
index 000000000..43c97f27d
--- /dev/null
+++ b/src/etc/testcases/types/filtersfile2
@@ -0,0 +1 @@
+baz=BAZ
diff --git a/src/main/org/apache/tools/ant/types/FilterSet.java b/src/main/org/apache/tools/ant/types/FilterSet.java
index 1ae90c63f..9251c7020 100644
--- a/src/main/org/apache/tools/ant/types/FilterSet.java
+++ b/src/main/org/apache/tools/ant/types/FilterSet.java
@@ -118,7 +118,44 @@ public class FilterSet extends DataType implements Cloneable {
* @param file the file from which filters will be read.
*/
public void setFile(File file) {
- readFiltersFromFile(file);
+ filtersFiles.add(file);
+ }
+ }
+
+ /**
+ * EnumeratedAttribute to set behavior WRT missing filtersfiles:
+ * "fail" (default), "warn", "ignore".
+ * @since Ant 1.7
+ */
+ public static class OnMissing extends EnumeratedAttribute {
+ private static final String[] VALUES
+ = new String[] {"fail", "warn", "ignore"};
+
+ public static final OnMissing FAIL = new OnMissing("fail");
+ public static final OnMissing WARN = new OnMissing("warn");
+ public static final OnMissing IGNORE = new OnMissing("ignore");
+
+ private static final int FAIL_INDEX = 0;
+ private static final int WARN_INDEX = 1;
+ private static final int IGNORE_INDEX = 2;
+
+ /**
+ * Default constructor.
+ */
+ public OnMissing() {
+ }
+
+ /**
+ * Convenience constructor.
+ * @param value the value to set.
+ */
+ public OnMissing(String value) {
+ setValue(value);
+ }
+
+ //inherit doc
+ public String[] getValues() {
+ return VALUES;
}
}
@@ -138,6 +175,9 @@ public class FilterSet extends DataType implements Cloneable {
private boolean recurse = true;
private Hashtable filterHash = null;
+ private Vector filtersFiles = new Vector();
+ private OnMissing onMissingFiltersFile = OnMissing.FAIL;
+ private boolean readingFiles = false;
/**
* List of ordered filters and filter files.
@@ -169,6 +209,15 @@ public class FilterSet extends DataType implements Cloneable {
if (isReference()) {
return getRef().getFilters();
}
+ //silly hack to avoid stack overflow...
+ if (!readingFiles) {
+ readingFiles = true;
+ for (int i = 0, sz = filtersFiles.size(); i < sz; i++) {
+ readFiltersFromFile((File) filtersFiles.get(i));
+ }
+ filtersFiles.clear();
+ readingFiles = false;
+ }
return filters;
}
@@ -202,13 +251,12 @@ public class FilterSet extends DataType implements Cloneable {
*
* @param filtersFile sets the filter file from which to read filters
* for this filter set.
- * @exception BuildException if there is a problem reading the filters.
*/
public void setFiltersfile(File filtersFile) throws BuildException {
if (isReference()) {
throw tooManyAttributes();
}
- readFiltersFromFile(filtersFile);
+ filtersFiles.add(filtersFile);
}
/**
@@ -292,7 +340,7 @@ public class FilterSet extends DataType implements Cloneable {
throw tooManyAttributes();
}
if (!filtersFile.exists()) {
- throw new BuildException("Could not read filters from file "
+ handleMissingFile("Could not read filters from file "
+ filtersFile + " as it doesn't exist.");
}
if (filtersFile.isFile()) {
@@ -312,13 +360,14 @@ public class FilterSet extends DataType implements Cloneable {
}
} catch (Exception ex) {
throw new BuildException("Could not read filters from file: "
- + filtersFile);
+ + filtersFile);
} finally {
FileUtils.close(in);
}
} else {
- throw new BuildException("Must specify a file not a directory in "
- + "the filtersfile attribute:" + filtersFile);
+ handleMissingFile(
+ "Must specify a file rather than a directory in "
+ + "the filtersfile attribute:" + filtersFile);
}
filterHash = null;
}
@@ -338,6 +387,104 @@ public class FilterSet extends DataType implements Cloneable {
return iReplaceTokens(line);
}
+ /**
+ * Add a new filter.
+ *
+ * @param filter the filter to be added.
+ */
+ public synchronized void addFilter(Filter filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ filters.addElement(filter);
+ filterHash = null;
+ }
+
+ /**
+ * Create a new FiltersFile.
+ *
+ * @return The filtersfile that was created.
+ */
+ public FiltersFile createFiltersfile() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ return new FiltersFile();
+ }
+
+ /**
+ * Add a new filter made from the given token and value.
+ *
+ * @param token The token for the new filter.
+ * @param value The value for the new filter.
+ */
+ public synchronized void addFilter(String token, String value) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ addFilter(new Filter(token, value));
+ }
+
+ /**
+ * Add a Filterset to this filter set.
+ *
+ * @param filterSet the filterset to be added to this filterset
+ */
+ public synchronized void addConfiguredFilterSet(FilterSet filterSet) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ for (Enumeration e = filterSet.getFilters().elements(); e.hasMoreElements();) {
+ addFilter((Filter) e.nextElement());
+ }
+ }
+
+ /**
+ * Test to see if this filter set has filters.
+ *
+ * @return Return true if there are filters in this set.
+ */
+ public synchronized boolean hasFilters() {
+ return getFilters().size() > 0;
+ }
+
+ /**
+ * Clone the filterset.
+ *
+ * @return a deep clone of this filterset.
+ *
+ * @throws BuildException if the clone cannot be performed.
+ */
+ public synchronized Object clone() throws BuildException {
+ if (isReference()) {
+ return ((FilterSet) getRef()).clone();
+ }
+ try {
+ FilterSet fs = (FilterSet) super.clone();
+ fs.filters = (Vector) getFilters().clone();
+ fs.setProject(getProject());
+ return fs;
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Set the behavior WRT missing filtersfiles.
+ * @param onMissingFiltersFile the OnMissing describing the behavior.
+ */
+ public void setOnMissingFiltersFile(OnMissing onMissingFiltersFile) {
+ this.onMissingFiltersFile = onMissingFiltersFile;
+ }
+
+ /**
+ * Get the onMissingFiltersFile setting.
+ * @return the OnMissing instance.
+ */
+ public OnMissing getOnMissingFiltersFile() {
+ return onMissingFiltersFile;
+ }
+
/**
* Does replacement on the given string with token matching.
* This uses the defined begintoken and endtoken values which default
@@ -438,87 +585,21 @@ public class FilterSet extends DataType implements Cloneable {
return value;
}
- /**
- * Add a new filter.
- *
- * @param filter the filter to be added.
- */
- public synchronized void addFilter(Filter filter) {
- if (isReference()) {
- throw noChildrenAllowed();
- }
- filters.addElement(filter);
- filterHash = null;
- }
-
- /**
- * Create a new FiltersFile.
- *
- * @return The filtersfile that was created.
- */
- public FiltersFile createFiltersfile() {
- if (isReference()) {
- throw noChildrenAllowed();
- }
- return new FiltersFile();
- }
-
- /**
- * Add a new filter made from the given token and value.
- *
- * @param token The token for the new filter.
- * @param value The value for the new filter.
- */
- public synchronized void addFilter(String token, String value) {
- if (isReference()) {
- throw noChildrenAllowed();
+ private void addFiltersFile(File f) {
+ if (!filtersFiles.contains(f)) {
+ filtersFiles.add(f);
}
- addFilter(new Filter(token, value));
}
- /**
- * Add a Filterset to this filter set.
- *
- * @param filterSet the filterset to be added to this filterset
- */
- public synchronized void addConfiguredFilterSet(FilterSet filterSet) {
- if (isReference()) {
- throw noChildrenAllowed();
- }
- for (Enumeration e = filterSet.getFilters().elements(); e.hasMoreElements();) {
- addFilter((Filter) e.nextElement());
+ private void handleMissingFile(String message) {
+ switch (onMissingFiltersFile.getIndex()) {
+ case OnMissing.IGNORE_INDEX:
+ return;
+ case OnMissing.FAIL_INDEX:
+ throw new BuildException(message);
+ case OnMissing.WARN_INDEX:
+ log(message, Project.MSG_WARN);
}
}
- /**
- * Test to see if this filter set has filters.
- *
- * @return Return true if there are filters in this set.
- */
- public synchronized boolean hasFilters() {
- return getFilters().size() > 0;
- }
-
- /**
- * Clone the filterset.
- *
- * @return a deep clone of this filterset.
- *
- * @throws BuildException if the clone cannot be performed.
- */
- public synchronized Object clone() throws BuildException {
- if (isReference()) {
- return ((FilterSet) getRef()).clone();
- } else {
- try {
- FilterSet fs = (FilterSet) super.clone();
- fs.filters = (Vector) getFilters().clone();
- fs.setProject(getProject());
- return fs;
- } catch (CloneNotSupportedException e) {
- throw new BuildException(e);
- }
- }
- }
}
-
diff --git a/src/testcases/org/apache/tools/ant/types/FilterSetTest.java b/src/testcases/org/apache/tools/ant/types/FilterSetTest.java
index fe23a7671..108420f7a 100644
--- a/src/testcases/org/apache/tools/ant/types/FilterSetTest.java
+++ b/src/testcases/org/apache/tools/ant/types/FilterSetTest.java
@@ -141,6 +141,27 @@ public class FilterSetTest extends BuildFileTest {
assertEquals("value1", filters.get("token1"));
}
+ public void testFiltersFileElement() {
+ executeTarget("testFiltersFileElement");
+ }
+
+ public void testFiltersFileAttribute() {
+ executeTarget("testFiltersFileAttribute");
+ }
+
+ public void testMultipleFiltersFiles() {
+ executeTarget("testMultipleFiltersFiles");
+ }
+
+ public void testMissingFiltersFile() {
+ expectBuildException("testMissingFiltersFile",
+ "should fail due to missing filtersfile");
+ }
+
+ public void testAllowMissingFiltersFile() {
+ executeTarget("testAllowMissingFiltersFile");
+ }
+
private boolean compareFiles(String name1, String name2) {
File file1 = new File(System.getProperty("root"), name1);
File file2 = new File(System.getProperty("root"), name2);