You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2023/06/30 04:02:29 UTC
[commons-io] branch master updated: Add PathMatcherFileFilter to adapt java.nio.file.PathMatcher
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git
The following commit(s) were added to refs/heads/master by this push:
new 4d1ded4b Add PathMatcherFileFilter to adapt java.nio.file.PathMatcher
new c3471687 Merge branch 'master' of https://gitbox.apache.org/repos/asf/commons-io.git
4d1ded4b is described below
commit 4d1ded4b111e25ffea2fbe3c02b4c705cd06d2d0
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Fri Jun 30 00:02:07 2023 -0400
Add PathMatcherFileFilter to adapt java.nio.file.PathMatcher
- MagicNumberFileFilter.accept(Path, BasicFileAttributes) doesn't its
byteOffset before reading.
- Move fixes into first changes section
---
src/changes/changes.xml | 24 +++++++----
.../io/filefilter/MagicNumberFileFilter.java | 1 +
.../io/filefilter/PathMatcherFileFilter.java | 50 ++++++++++++++++++++++
.../commons/io/filefilter/AbstractFilterTest.java | 22 +++++++---
.../commons/io/filefilter/FileFilterTest.java | 45 ++++++++++---------
.../io/filefilter/PathMatcherFileFilterTest.java | 50 ++++++++++++++++++++++
.../io/filefilter/WildcardFileFilterTest.java | 3 +-
7 files changed, 155 insertions(+), 40 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 1ce68660..81a4f784 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -48,6 +48,19 @@ The <action> type attribute can be add,update,fix,remove.
<body>
<release version="2.14.0" date="2023-MM-DD" description="Java 8 required.">
+ <!-- FIX -->
+ <action dev="ggregory" type="fix" issue="IO-799" due-to="Jeroen van der Vegt, Gary Gregory">
+ ReaderInputStream.read() throws an exception instead of returning -1 when called again after returning -1.
+ </action>
+ <action dev="ggregory" type="fix" issue="IO-804" due-to="Elliotte Rusty Harold, Gary Gregory">
+ FileUtils.forceMkdirParent() Javadoc is likely incorrect.
+ </action>
+ <action dev="ggregory" type="fix" due-to="step-security-bot, Gary Gregory">
+ [StepSecurity] ci: Harden GitHub Actions #461.
+ </action>
+ <action dev="ggregory" type="fix" due-to="Gary Gregory">
+ MagicNumberFileFilter.accept(Path, BasicFileAttributes) doesn't its byteOffset before reading.
+ </action>
<!-- ADD -->
<action dev="ggregory" type="add" due-to="Gary Gregory">
Add DeferredFileOutputStream.getPath().
@@ -82,15 +95,8 @@ The <action> type attribute can be add,update,fix,remove.
<action dev="ggregory" type="add" due-to="Gary Gregory">
IOFileFilter now also extends java.nio.file.PathMatcher.
</action>
- <!-- FIX -->
- <action dev="ggregory" type="fix" issue="IO-799" due-to="Jeroen van der Vegt, Gary Gregory">
- ReaderInputStream.read() throws an exception instead of returning -1 when called again after returning -1.
- </action>
- <action dev="ggregory" type="fix" issue="IO-804" due-to="Elliotte Rusty Harold, Gary Gregory">
- FileUtils.forceMkdirParent() Javadoc is likely incorrect.
- </action>
- <action dev="ggregory" type="fix" due-to="step-security-bot, Gary Gregory">
- [StepSecurity] ci: Harden GitHub Actions #461.
+ <action dev="ggregory" type="add" due-to="Gary Gregory">
+ Add PathMatcherFileFilter to adapt java.nio.file.PathMatcher.
</action>
<!-- UPDATE -->
</release>
diff --git a/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java
index e7743408..1793ef2a 100644
--- a/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java
+++ b/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java
@@ -293,6 +293,7 @@ public class MagicNumberFileFilter extends AbstractFileFilter implements Seriali
try {
try (FileChannel fileChannel = FileChannel.open(file)) {
final ByteBuffer byteBuffer = ByteBuffer.allocate(this.magicNumbers.length);
+ fileChannel.position(byteOffset);
final int read = fileChannel.read(byteBuffer);
if (read != magicNumbers.length) {
return FileVisitResult.TERMINATE;
diff --git a/src/main/java/org/apache/commons/io/filefilter/PathMatcherFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/PathMatcherFileFilter.java
new file mode 100644
index 00000000..a36c6879
--- /dev/null
+++ b/src/main/java/org/apache/commons/io/filefilter/PathMatcherFileFilter.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.io.filefilter;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+
+/**
+ * Delegates matching to a {@link PathMatcher}.
+ *
+ * @since 2.14.0
+ */
+public class PathMatcherFileFilter extends AbstractFileFilter {
+
+ private final PathMatcher pathMatcher;
+
+ /**
+ * Constructs a new instance to perform matching with a PathMatcher.
+ *
+ * @param pathMatcher The PathMatcher delegate.
+ */
+ public PathMatcherFileFilter(final PathMatcher pathMatcher) {
+ this.pathMatcher = pathMatcher;
+ }
+
+ @Override
+ public boolean accept(File file) {
+ return file != null && matches(file.toPath());
+ }
+ @Override
+ public boolean matches(final Path path) {
+ return pathMatcher.matches(path);
+ }
+}
diff --git a/src/test/java/org/apache/commons/io/filefilter/AbstractFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/AbstractFilterTest.java
index 3014b315..ca6f8874 100644
--- a/src/test/java/org/apache/commons/io/filefilter/AbstractFilterTest.java
+++ b/src/test/java/org/apache/commons/io/filefilter/AbstractFilterTest.java
@@ -24,6 +24,7 @@ import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
import org.apache.commons.io.IOCase;
import org.junit.jupiter.api.io.TempDir;
@@ -43,7 +44,7 @@ public class AbstractFilterTest {
@TempDir
public File temporaryFolder;
- void assertFiltering(final IOFileFilter filter, final File file, final boolean expected) {
+ void assertFiltering(final IOFileFilter filter, final File file, final boolean expected) throws IOException {
// Note. This only tests the (File, String) version if the parent of
// the File passed in is not null
assertEquals(expected, filter.accept(file), "Filter(File) " + filter.getClass().getName() + " not " + expected + " for " + file);
@@ -51,6 +52,13 @@ public class AbstractFilterTest {
if (file != null && file.getParentFile() != null) {
assertEquals(expected, filter.accept(file.getParentFile(), file.getName()),
"Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for " + file);
+ final Path path = file.toPath();
+ assertEquals(expected, filter.accept(path, null) != FileVisitResult.TERMINATE, filter::toString);
+ if (Files.isRegularFile(path)) {
+ assertEquals(expected, filter.accept(path, Files.readAttributes(path, BasicFileAttributes.class)) != FileVisitResult.TERMINATE,
+ filter::toString);
+ }
+ assertEquals(expected, filter.matches(path), filter::toString);
} else if (file == null) {
assertEquals(expected, filter.accept(null), "Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for null");
assertEquals(expected, filter.matches(null), "Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for null");
@@ -63,7 +71,7 @@ public class AbstractFilterTest {
// the File passed in is not null
final FileVisitResult expectedFileVisitResult = AbstractFileFilter.toDefaultFileVisitResult(expected);
assertEquals(expectedFileVisitResult, filter.accept(path, null),
- "Filter(Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for " + path);
+ "Filter(Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for " + path);
if (path != null && path.getParent() != null) {
assertEquals(expectedFileVisitResult, filter.accept(path, null),
@@ -79,7 +87,7 @@ public class AbstractFilterTest {
assertNotNull(filter.toString());
}
- void assertFooBarFileFiltering(IOFileFilter filter) {
+ void assertFooBarFileFiltering(IOFileFilter filter) throws IOException {
assertFiltering(filter, new File("foo"), true);
assertFiltering(filter, new File("foo"), true);
assertFiltering(filter, new File("bar"), true);
@@ -89,7 +97,7 @@ public class AbstractFilterTest {
assertFiltering(filter, new File("bar").toPath(), true);
assertFiltering(filter, new File("fred").toPath(), false);
- filter = new NameFileFilter(new String[] {"foo", "bar"}, IOCase.SENSITIVE);
+ filter = new NameFileFilter(new String[] { "foo", "bar" }, IOCase.SENSITIVE);
assertFiltering(filter, new File("foo"), true);
assertFiltering(filter, new File("bar"), true);
assertFiltering(filter, new File("FOO"), false);
@@ -99,7 +107,7 @@ public class AbstractFilterTest {
assertFiltering(filter, new File("FOO").toPath(), false);
assertFiltering(filter, new File("BAR").toPath(), false);
- filter = new NameFileFilter(new String[] {"foo", "bar"}, IOCase.INSENSITIVE);
+ filter = new NameFileFilter(new String[] { "foo", "bar" }, IOCase.INSENSITIVE);
assertFiltering(filter, new File("foo"), true);
assertFiltering(filter, new File("bar"), true);
assertFiltering(filter, new File("FOO"), true);
@@ -109,7 +117,7 @@ public class AbstractFilterTest {
assertFiltering(filter, new File("FOO").toPath(), true);
assertFiltering(filter, new File("BAR").toPath(), true);
- filter = new NameFileFilter(new String[] {"foo", "bar"}, IOCase.SYSTEM);
+ filter = new NameFileFilter(new String[] { "foo", "bar" }, IOCase.SYSTEM);
assertFiltering(filter, new File("foo"), true);
assertFiltering(filter, new File("bar"), true);
assertFiltering(filter, new File("FOO"), WINDOWS);
@@ -119,7 +127,7 @@ public class AbstractFilterTest {
assertFiltering(filter, new File("FOO").toPath(), WINDOWS);
assertFiltering(filter, new File("BAR").toPath(), WINDOWS);
- filter = new NameFileFilter(new String[] {"foo", "bar"}, null);
+ filter = new NameFileFilter(new String[] { "foo", "bar" }, null);
assertFiltering(filter, new File("foo"), true);
assertFiltering(filter, new File("bar"), true);
assertFiltering(filter, new File("FOO"), false);
diff --git a/src/test/java/org/apache/commons/io/filefilter/FileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/FileFilterTest.java
index 9aa39b72..858c4a19 100644
--- a/src/test/java/org/apache/commons/io/filefilter/FileFilterTest.java
+++ b/src/test/java/org/apache/commons/io/filefilter/FileFilterTest.java
@@ -29,6 +29,7 @@ import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
+import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
@@ -153,7 +154,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testAnd() {
+ public void testAnd() throws IOException {
final IOFileFilter trueFilter = TrueFileFilter.INSTANCE;
final IOFileFilter falseFilter = FalseFileFilter.INSTANCE;
assertFiltering(trueFilter.and(trueFilter), new File("foo.test"), true);
@@ -163,7 +164,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testAnd2() {
+ public void testAnd2() throws IOException {
final IOFileFilter trueFilter = TrueFileFilter.INSTANCE;
final IOFileFilter falseFilter = FalseFileFilter.INSTANCE;
assertFiltering(new AndFileFilter(trueFilter, trueFilter), new File("foo.test"), true);
@@ -181,7 +182,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testAndArray() {
+ public void testAndArray() throws IOException {
final IOFileFilter trueFilter = TrueFileFilter.INSTANCE;
final IOFileFilter falseFilter = FalseFileFilter.INSTANCE;
assertFiltering(new AndFileFilter(trueFilter, trueFilter, trueFilter), new File("foo.test"), true);
@@ -252,7 +253,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testDelegateFileFilter() {
+ public void testDelegateFileFilter() throws IOException {
final OrFileFilter orFilter = new OrFileFilter();
final File testFile = new File("test.txt");
@@ -276,7 +277,7 @@ public class FileFilterTest extends AbstractFilterTest {
@SuppressWarnings("deprecation")
@Test
- public void testDeprecatedWildcard() {
+ public void testDeprecatedWildcard() throws IOException {
IOFileFilter filter = new WildcardFilter("*.txt");
final List<String> patternList = Arrays.asList("*.txt", "*.xml", "*.gif");
final IOFileFilter listFilter = new WildcardFilter(patternList);
@@ -355,7 +356,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testDirectory() {
+ public void testDirectory() throws IOException {
// XXX: This test presumes the current working dir is the base dir of the source checkout.
final IOFileFilter filter = new DirectoryFileFilter();
@@ -432,7 +433,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testFalse() {
+ public void testFalse() throws IOException {
final IOFileFilter filter = FileFilterUtils.falseFileFilter();
assertFiltering(filter, new File("foo.test"), false);
assertFiltering(filter, new File("foo.test").toPath(), false);
@@ -447,13 +448,13 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testFileEqualsFilter() {
+ public void testFileEqualsFilter() throws IOException {
assertFooBarFileFiltering(
new FileEqualsFileFilter(new File("foo")).or(new FileEqualsFileFilter(new File("bar"))));
}
@Test
- public void testFileFilterUtils_and() {
+ public void testFileFilterUtils_and() throws IOException {
final IOFileFilter trueFilter = TrueFileFilter.INSTANCE;
final IOFileFilter falseFilter = FalseFileFilter.INSTANCE;
assertFiltering(FileFilterUtils.and(trueFilter, trueFilter, trueFilter), new File("foo.test"), true);
@@ -463,7 +464,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testFileFilterUtils_or() {
+ public void testFileFilterUtils_or() throws IOException {
final IOFileFilter trueFilter = TrueFileFilter.INSTANCE;
final IOFileFilter falseFilter = FalseFileFilter.INSTANCE;
final File testFile = new File("foo.test");
@@ -474,7 +475,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testFiles() {
+ public void testFiles() throws IOException {
// XXX: This test presumes the current working dir is the base dir of the source checkout.
final IOFileFilter filter = FileFileFilter.INSTANCE;
@@ -700,7 +701,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testHidden() {
+ public void testHidden() throws IOException {
final File hiddenDirFile = new File(SVN_DIR_NAME);
final Path hiddenDirPath = hiddenDirFile.toPath();
if (hiddenDirFile.exists()) {
@@ -797,8 +798,6 @@ public class FileFilterTest extends AbstractFilterTest {
assertFiltering(filter, dir, false);
}
- // -----------------------------------------------------------------------
-
@Test
public void testMagicNumberFileFilterString() throws Exception {
final byte[] classFileMagicNumber = {(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE};
@@ -1037,7 +1036,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testNameFilter() {
+ public void testNameFilter() throws IOException {
assertFooBarFileFiltering(new NameFileFilter("foo", "bar"));
}
@@ -1061,7 +1060,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testNegate() {
+ public void testNegate() throws IOException {
final IOFileFilter filter = FileFilterUtils.notFileFilter(FileFilterUtils.trueFileFilter());
assertFiltering(filter, new File("foo.test"), false);
assertFiltering(filter, new File("foo"), false);
@@ -1077,7 +1076,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testOr() {
+ public void testOr() throws IOException {
final IOFileFilter trueFilter = TrueFileFilter.INSTANCE;
final IOFileFilter falseFilter = FalseFileFilter.INSTANCE;
final File testFile = new File("foo.test");
@@ -1124,13 +1123,13 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testPathEqualsFilter() {
+ public void testPathEqualsFilter() throws IOException {
assertFooBarFileFiltering(
new PathEqualsFileFilter(Paths.get("foo")).or(new PathEqualsFileFilter(Paths.get("bar"))));
}
@Test
- public void testPrefix() {
+ public void testPrefix() throws IOException {
IOFileFilter filter = new PrefixFileFilter("foo", "bar");
final File testFile = new File("test");
final Path testPath = testFile.toPath();
@@ -1194,7 +1193,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testPrefixCaseInsensitive() {
+ public void testPrefixCaseInsensitive() throws IOException {
IOFileFilter filter = new PrefixFileFilter(new String[] {"foo", "bar"}, IOCase.INSENSITIVE);
assertFiltering(filter, new File("foo.test1"), true);
@@ -1323,7 +1322,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testSuffix() {
+ public void testSuffix() throws IOException {
IOFileFilter filter = new SuffixFileFilter("tes", "est");
final File testFile = new File("test");
final Path testPath = testFile.toPath();
@@ -1380,7 +1379,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testSuffixCaseInsensitive() {
+ public void testSuffixCaseInsensitive() throws IOException {
IOFileFilter filter = new SuffixFileFilter(new String[] {"tes", "est"}, IOCase.INSENSITIVE);
assertFiltering(filter, new File("foo.tes"), true);
@@ -1414,7 +1413,7 @@ public class FileFilterTest extends AbstractFilterTest {
}
@Test
- public void testTrue() {
+ public void testTrue() throws IOException {
final IOFileFilter filter = FileFilterUtils.trueFileFilter();
assertFiltering(filter, new File("foo.test"), true);
assertFiltering(filter, new File("foo"), true);
diff --git a/src/test/java/org/apache/commons/io/filefilter/PathMatcherFileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/PathMatcherFileFilterTest.java
new file mode 100644
index 00000000..ce794115
--- /dev/null
+++ b/src/test/java/org/apache/commons/io/filefilter/PathMatcherFileFilterTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.io.filefilter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystems;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests {@link PathMatcherFileFilter}.
+ */
+public class PathMatcherFileFilterTest extends AbstractFilterTest {
+
+ @Test
+ public void testGlob() throws IOException {
+ @SuppressWarnings("resource")
+ final IOFileFilter filter = new PathMatcherFileFilter(FileSystems.getDefault().getPathMatcher("glob:*.txt"));
+ final File file1 = new File("log.txt");
+ final File file2 = new File("log.TXT");
+ //
+ assertTrue(filter.accept(file1));
+ assertTrue(filter.accept(file2));
+ assertTrue(filter.accept(file1.getParentFile(), file1.getName()));
+ assertTrue(filter.accept(file2.getParentFile(), file2.getName()));
+ assertFiltering(filter, file1, true);
+ assertFiltering(filter, file2, true);
+ assertFiltering(filter, file1.toPath(), true);
+ assertFiltering(filter, file2.toPath(), true);
+ }
+
+}
diff --git a/src/test/java/org/apache/commons/io/filefilter/WildcardFileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/WildcardFileFilterTest.java
index af3755ae..44ee1fa9 100644
--- a/src/test/java/org/apache/commons/io/filefilter/WildcardFileFilterTest.java
+++ b/src/test/java/org/apache/commons/io/filefilter/WildcardFileFilterTest.java
@@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
+import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.util.Arrays;
@@ -34,7 +35,7 @@ import org.junit.jupiter.api.Test;
public class WildcardFileFilterTest extends AbstractFilterTest {
@Test
- public void testWildcard() {
+ public void testWildcard() throws IOException {
IOFileFilter filter = new WildcardFileFilter("*.txt");
assertFiltering(filter, new File("log.txt"), true);
assertFiltering(filter, new File("log.TXT"), false);