Refactor and simplify new boolean APIs.
MODIFY
src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java
src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
/**
* A {@link java.io.FileFilter} providing conditional AND logic across a list of
private final List<IOFileFilter> fileFilters;
/**
- * Constructs a new instance of <code>AndFileFilter</code>.
+ * Constructs a new empty instance.
*
* @since 1.1
*/
public AndFileFilter() {
- this.fileFilters = new ArrayList<>();
+ this(0);
+ }
+
+ /**
+ * Constructs a new instance with the given initial list.
+ *
+ * @param initialList the initial list.
+ */
+ private AndFileFilter(final ArrayList<IOFileFilter> initialList) {
+ this.fileFilters = Objects.requireNonNull(initialList);
+ }
+
+ /**
+ * Constructs a new instance with the given initial capacity.
+ *
+ * @param initialCapacity the initial capacity.
+ */
+ private AndFileFilter(int initialCapacity) {
+ this(new ArrayList<>(initialCapacity));
}
/**
@@ -62,43 +80,31 @@ public AndFileFilter() {
* @throws IllegalArgumentException if either filter is null
*/
public AndFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) {
- if (filter1 == null || filter2 == null) {
- throw new IllegalArgumentException("The filters must not be null");
- }
- this.fileFilters = new ArrayList<>(2);
- this.fileFilters.add(filter1);
- this.fileFilters.add(filter2);
+ this(2);
+ addFileFilter(filter1);
+ addFileFilter(filter2);
}
/**
- * Constructs a new file filter that ANDs the result of other filters.
+ * Constructs a new instance for the give filters.
+ * @param fileFilters filters to OR.
*
- * @param filter1 the first filter, must not be null
- * @param filters more filters, must not be null
- * @throws IllegalArgumentException if either filter is null
+ * @since 2.9.0
*/
- public AndFileFilter(final IOFileFilter filter1, final IOFileFilter... filters) {
- if (filter1 == null || filters == null) {
- throw new IllegalArgumentException("The filters must not be null");
- }
- this.fileFilters = new ArrayList<>(filters.length + 1);
- this.fileFilters.add(filter1);
- this.fileFilters.addAll(Arrays.asList(filters));
+ public AndFileFilter(final IOFileFilter... fileFilters) {
+ this(Objects.requireNonNull(fileFilters, "fileFilters").length);
+ addFileFilter(fileFilters);
}
/**
* Constructs a new instance of <code>AndFileFilter</code>
* with the specified list of filters.
*
- * @param fileFilters a List of IOFileFilter instances, copied, null ignored
+ * @param fileFilters a List of IOFileFilter instances, copied.
* @since 1.1
*/
public AndFileFilter(final List<IOFileFilter> fileFilters) {
- if (fileFilters == null) {
- this.fileFilters = new ArrayList<>();
- } else {
- this.fileFilters = new ArrayList<>(fileFilters);
- }
+ this(new ArrayList<>(Objects.requireNonNull(fileFilters)));
}
/**
@@ -154,8 +160,20 @@ public FileVisitResult accept(final Path file, final BasicFileAttributes attribu
* {@inheritDoc}
*/
@Override
- public void addFileFilter(final IOFileFilter ioFileFilter) {
- this.fileFilters.add(ioFileFilter);
+ public void addFileFilter(final IOFileFilter fileFilter) {
+ this.fileFilters.add(Objects.requireNonNull(fileFilter, "fileFilter"));
+ }
+
+ /**
+ * Adds the given file filters.
+ *
+ * @param fileFilters the filters to add.
+ * @since 2.9.0
+ */
+ public void addFileFilter(final IOFileFilter... fileFilters) {
+ for (final IOFileFilter fileFilter : Objects.requireNonNull(fileFilters, "fileFilters")) {
+ addFileFilter(fileFilter);
+ }
}
/**
@@ -201,8 +219,7 @@ public String toString() {
if (i > 0) {
buffer.append(",");
}
- final Object filter = fileFilters.get(i);
- buffer.append(filter == null ? "null" : filter.toString());
+ buffer.append(Objects.toString(fileFilters.get(i)));
}
buffer.append(")");
return buffer.toString();

MODIFY
src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java
src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java
*/
public class FalseFileFilter implements IOFileFilter, Serializable {
+ private static final String TO_STRING = Boolean.FALSE.toString();
+
/**
* Singleton instance of false filter.
*
@@ -76,6 +78,7 @@ public boolean accept(final File dir, final String name) {
/**
* Returns false.
+ *
* @param file the file to check (ignored)
*
* @return false
@@ -91,4 +94,20 @@ public IOFileFilter negate() {
return TrueFileFilter.INSTANCE;
}
+ @Override
+ public String toString() {
+ return TO_STRING;
+ }
+
+ @Override
+ public IOFileFilter and(IOFileFilter fileFilter) {
+ // FALSE AND expression <=> FALSE
+ return INSTANCE;
+ }
+
+ @Override
+ public IOFileFilter or(IOFileFilter fileFilter) {
+ // FALSE OR expression <=> expression
+ return fileFilter;
+ }
}

MODIFY
src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java
src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java
@@ -75,13 +75,13 @@ default FileVisitResult accept(final Path path, final BasicFileAttributes attrib
}
/**
- * Creates a new "and" filter with this filter and the given filters.
+ * Creates a new "and" filter with this filter.
*
- * @param fileFilter the filters to "and".
+ * @param fileFilter the filter to "and".
* @return a new filter
* @since 2.9.0
*/
- default AndFileFilter and(final IOFileFilter... fileFilter) {
+ default IOFileFilter and(final IOFileFilter fileFilter) {
return new AndFileFilter(this, fileFilter);
}
@@ -96,13 +96,13 @@ default IOFileFilter negate() {
}
/**
- * Creates a new "or" filter with this filter and the given filters.
+ * Creates a new "or" filter with this filter.
*
- * @param fileFilter the filters to "or".
+ * @param fileFilter the filter to "or".
* @return a new filter
* @since 2.9.0
*/
- default OrFileFilter or(final IOFileFilter... fileFilter) {
+ default IOFileFilter or(final IOFileFilter fileFilter) {
return new OrFileFilter(this, fileFilter);
}

MODIFY
src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java
src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java
@@ -95,7 +95,7 @@ private FileVisitResult not(final FileVisitResult accept) {
*/
@Override
public String toString() {
- return super.toString() + "(" + filter.toString() + ")";
+ return "NOT (" + filter.toString() + ")";
}
}

MODIFY
src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java
src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
/**
* A {@link java.io.FileFilter} providing conditional OR logic across a list of file filters. This filter returns
* @since 1.1
*/
public OrFileFilter() {
- this.fileFilters = new ArrayList<>();
+ this(0);
}
/**
- * Constructs a new file filter that ORs the result of other filters.
+ * Constructs a new instance with the given initial list.
*
- * @param filter1 the first filter, must not be null
- * @param filter2 the second filter, must not be null
- * @throws IllegalArgumentException if either filter is null
+ * @param initialList the initial list.
*/
- public OrFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) {
- if (filter1 == null || filter2 == null) {
- throw new IllegalArgumentException("The filters must not be null");
+ private OrFileFilter(final ArrayList<IOFileFilter> initialList) {
+ this.fileFilters = Objects.requireNonNull(initialList);
+ }
+
+ /**
+ * Constructs a new instance with the given initial capacity.
+ *
+ * @param initialCapacity the initial capacity.
+ */
+ private OrFileFilter(final int initialCapacity) {
+ this(new ArrayList<>(initialCapacity));
}
- this.fileFilters = new ArrayList<>(2);
- this.fileFilters.add(filter1);
- this.fileFilters.add(filter2);
+
+ /**
+ * Constructs a new instance for the give filters.
+ * @param fileFilters filters to OR.
+ *
+ * @since 2.9.0
+ */
+ public OrFileFilter(final IOFileFilter... fileFilters) {
+ this(Objects.requireNonNull(fileFilters, "fileFilters").length);
+ addFileFilter(fileFilters);
}
/**
* Constructs a new file filter that ORs the result of other filters.
*
* @param filter1 the first filter, must not be null
- * @param filters more filter, must not be null
+ * @param filter2 the second filter, must not be null
* @throws IllegalArgumentException if either filter is null
*/
- public OrFileFilter(final IOFileFilter filter1, final IOFileFilter... filters) {
- if (filter1 == null || filters == null) {
- throw new IllegalArgumentException("The filters must not be null");
- }
- this.fileFilters = new ArrayList<>(filters.length + 1);
- this.fileFilters.add(filter1);
- this.fileFilters.addAll(Arrays.asList(filters));
+ public OrFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) {
+ this(2);
+ addFileFilter(filter1);
+ addFileFilter(filter2);
}
/**
* Constructs a new instance of <code>OrFileFilter</code> with the specified filters.
*
- * @param fileFilters the file filters for this filter, copied, null ignored
+ * @param fileFilters the file filters for this filter, copied.
* @since 1.1
*/
public OrFileFilter(final List<IOFileFilter> fileFilters) {
- if (fileFilters == null) {
- this.fileFilters = new ArrayList<>();
- } else {
- this.fileFilters = new ArrayList<>(fileFilters);
- }
+ this(new ArrayList<>(Objects.requireNonNull(fileFilters)));
}
/**
@@ -139,8 +145,20 @@ public FileVisitResult accept(final Path file, final BasicFileAttributes attribu
* {@inheritDoc}
*/
@Override
- public void addFileFilter(final IOFileFilter ioFileFilter) {
- this.fileFilters.add(ioFileFilter);
+ public void addFileFilter(final IOFileFilter fileFilter) {
+ this.fileFilters.add(Objects.requireNonNull(fileFilter, "fileFilter"));
+ }
+
+ /**
+ * Adds the given file filters.
+ *
+ * @param fileFilters the filters to add.
+ * @since 2.9.0
+ */
+ public void addFileFilter(final IOFileFilter... fileFilters) {
+ for (final IOFileFilter fileFilter : Objects.requireNonNull(fileFilters, "fileFilters")) {
+ addFileFilter(fileFilter);
+ }
}
/**
@@ -155,8 +173,8 @@ public void addFileFilter(final IOFileFilter ioFileFilter) {
* {@inheritDoc}
*/
@Override
- public boolean removeFileFilter(final IOFileFilter ioFileFilter) {
- return this.fileFilters.remove(ioFileFilter);
+ public boolean removeFileFilter(final IOFileFilter fileFilter) {
+ return this.fileFilters.remove(fileFilter);
}
/**
@@ -165,7 +183,7 @@ public boolean removeFileFilter(final IOFileFilter ioFileFilter) {
@Override
public void setFileFilters(final List<IOFileFilter> fileFilters) {
this.fileFilters.clear();
- this.fileFilters.addAll(fileFilters);
+ this.fileFilters.addAll(Objects.requireNonNull(fileFilters, "fileFilters"));
}
/**
@@ -183,8 +201,7 @@ public String toString() {
if (i > 0) {
buffer.append(",");
}
- final Object filter = fileFilters.get(i);
- buffer.append(filter == null ? "null" : filter.toString());
+ buffer.append(Objects.toString(fileFilters.get(i)));
}
}
buffer.append(")");

MODIFY
src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java
src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java
*/
public class TrueFileFilter implements IOFileFilter, Serializable {
+ private static final String TO_STRING = Boolean.TRUE.toString();
+
private static final long serialVersionUID = 8782512160909720199L;
/**
@@ -91,4 +93,20 @@ public IOFileFilter negate() {
return FalseFileFilter.INSTANCE;
}
+ @Override
+ public IOFileFilter or(final IOFileFilter fileFilter) {
+ // TRUE OR expression <=> true
+ return INSTANCE;
+ }
+
+ @Override
+ public IOFileFilter and(final IOFileFilter fileFilter) {
+ // TRUE AND expression <=> expression
+ return fileFilter;
+ }
+
+ @Override
+ public String toString() {
+ return TO_STRING;
+ }
}

MODIFY
src/test/java/org/apache/commons/io/filefilter/FileFilterTestCase.java
src/test/java/org/apache/commons/io/filefilter/FileFilterTestCase.java
@@ -205,8 +205,6 @@ public void testAnd() {
assertFiltering(trueFilter.and(falseFilter), new File("foo.test"), false);
assertFiltering(falseFilter.and(trueFilter), new File("foo.test"), false);
assertFiltering(falseFilter.and(trueFilter), new File("foo.test"), false);
- assertFiltering(falseFilter.and(trueFilter, trueFilter), new File("foo.test"), false);
- assertFiltering(falseFilter.and(trueFilter, trueFilter, trueFilter), new File("foo.test"), false);
}
@Test
@@ -222,13 +220,9 @@ public void testAnd2() {
assertFiltering(new AndFileFilter(filters), new File("test"), false);
assertFiltering(new AndFileFilter(), new File("test"), false);
- assertThrows(IllegalArgumentException.class, () -> new AndFileFilter(falseFilter, (IOFileFilter) null));
- assertThrows(IllegalArgumentException.class, () -> new AndFileFilter(null, falseFilter));
-
- final AndFileFilter f = new AndFileFilter((List<IOFileFilter>) null);
- assertTrue(f.getFileFilters().isEmpty());
-
- assertNotNull(f.toString()); // TODO better tests
+ assertThrows(NullPointerException.class, () -> new AndFileFilter(falseFilter, (IOFileFilter) null));
+ assertThrows(NullPointerException.class, () -> new AndFileFilter(null, falseFilter));
+ assertThrows(NullPointerException.class, () -> new AndFileFilter((List<IOFileFilter>) null));
}
@Test
@@ -519,6 +513,7 @@ public void testFalse() {
assertSame(FalseFileFilter.FALSE, FalseFileFilter.INSTANCE);
assertSame(TrueFileFilter.TRUE, FalseFileFilter.INSTANCE.negate());
assertSame(TrueFileFilter.INSTANCE, FalseFileFilter.INSTANCE.negate());
+ assertNotNull(FalseFileFilter.INSTANCE.toString());
}
@Test
@@ -1339,8 +1334,6 @@ public void testOr() {
assertFiltering(new OrFileFilter(), testPath, false);
//
assertFiltering(falseFilter.or(trueFilter), testPath, true);
- assertFiltering(falseFilter.or(falseFilter, trueFilter), testPath, true);
- assertFiltering(falseFilter.or(falseFilter, falseFilter, trueFilter), testPath, true);
final List<IOFileFilter> filters = new ArrayList<>();
filters.add(trueFilter);
@@ -1364,14 +1357,7 @@ public void testOr() {
assertTrue(!orFilter.accept(testFile.getParentFile(), testFile.getName()));
assertEquals(FileVisitResult.TERMINATE, orFilter.accept(testPath, null));
- try {
- new OrFileFilter(falseFilter, (IOFileFilter) null);
- fail();
- } catch (final IllegalArgumentException ex) {
- }
-
- final OrFileFilter f = new OrFileFilter((List<IOFileFilter>) null);
- assertTrue(f.getFileFilters().isEmpty());
+ assertThrows(NullPointerException.class, () -> new OrFileFilter(falseFilter, (IOFileFilter) null));
}
@Test
@@ -1738,6 +1724,7 @@ public void testTrue() {
assertSame(TrueFileFilter.TRUE, TrueFileFilter.INSTANCE);
assertSame(FalseFileFilter.FALSE, TrueFileFilter.INSTANCE.negate());
assertSame(FalseFileFilter.INSTANCE, TrueFileFilter.INSTANCE.negate());
+ assertNotNull(TrueFileFilter.INSTANCE.toString());
}
@Test

Refactor and simplify new boolean APIs.