Skip to content

Commit 8b6d496

Browse files
author
Gary Gregory
committed
Let org.apache.commons.io.filefilter classes work with
java.nio.file.Files.walk* APIs. Also: AccumulatorPathVisitor does not track directories properly.
1 parent 947ff91 commit 8b6d496

48 files changed

Lines changed: 2947 additions & 604 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pom.xml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ file comparators, endian transformation classes, and much more.
308308
<spotbugs.plugin.version>4.1.3</spotbugs.plugin.version>
309309
<spotbugs.impl.version>4.1.3</spotbugs.impl.version>
310310
<japicmp.skip>false</japicmp.skip>
311+
<!-- generate report even if there are binary incompatible changes -->
312+
<commons.japicmp.breakBuildOnBinaryIncompatibleModifications>false</commons.japicmp.breakBuildOnBinaryIncompatibleModifications>
311313
<jacoco.skip>${env.JACOCO_SKIP}</jacoco.skip>
312314
<commons.release.isDistModule>true</commons.release.isDistModule>
313315
<commons.releaseManagerName>Gary Gregory</commons.releaseManagerName>
@@ -437,6 +439,22 @@ file comparators, endian transformation classes, and much more.
437439
<excludeFilterFile>${basedir}/spotbugs-exclude-filter.xml</excludeFilterFile>
438440
</configuration>
439441
</plugin>
442+
<plugin>
443+
<groupId>com.github.siom79.japicmp</groupId>
444+
<artifactId>japicmp-maven-plugin</artifactId>
445+
<configuration>
446+
<parameter>
447+
<overrideCompatibilityChangeParameters>
448+
<overrideCompatibilityChangeParameter>
449+
<compatibilityChange>METHOD_NEW_DEFAULT</compatibilityChange>
450+
<binaryCompatible>true</binaryCompatible>
451+
<sourceCompatible>true</sourceCompatible>
452+
<semanticVersionLevel>PATCH</semanticVersionLevel>
453+
</overrideCompatibilityChangeParameter>
454+
</overrideCompatibilityChangeParameters>
455+
</parameter>
456+
</configuration>
457+
</plugin>
440458
</plugins>
441459
</build>
442460

@@ -459,6 +477,22 @@ file comparators, endian transformation classes, and much more.
459477
<excludeFilterFile>${basedir}/spotbugs-exclude-filter.xml</excludeFilterFile>
460478
</configuration>
461479
</plugin>
480+
<plugin>
481+
<groupId>com.github.siom79.japicmp</groupId>
482+
<artifactId>japicmp-maven-plugin</artifactId>
483+
<configuration>
484+
<parameter>
485+
<overrideCompatibilityChangeParameters>
486+
<overrideCompatibilityChangeParameter>
487+
<compatibilityChange>METHOD_NEW_DEFAULT</compatibilityChange>
488+
<binaryCompatible>true</binaryCompatible>
489+
<sourceCompatible>true</sourceCompatible>
490+
<semanticVersionLevel>PATCH</semanticVersionLevel>
491+
</overrideCompatibilityChangeParameter>
492+
</overrideCompatibilityChangeParameters>
493+
</parameter>
494+
</configuration>
495+
</plugin>
462496
</plugins>
463497
</reporting>
464498
<profiles>

src/changes/changes.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,16 @@ The <action> type attribute can be add,update,fix,remove.
6363
<action dev="ggregory" type="fix" due-to="Michiel Kalkman">
6464
FileUtils#copyDirectory(File, File, FileFilter, preserveFileDate) clean up #163.
6565
</action>
66+
<action dev="ggregory" type="fix" due-to="Michiel Kalkman">
67+
AccumulatorPathVisitor does not track directories properly.
68+
</action>
6669
<!-- ADD -->
6770
<action dev="ggregory" type="add" due-to="Gary Gregory">
6871
Add FileSystemProviders class.
6972
</action>
73+
<action dev="ggregory" type="add" due-to="Gary Gregory">
74+
Let org.apache.commons.io.filefilter classes work with java.nio.file.Files.walk* APIs.
75+
</action>
7076
<!-- UPDATES -->
7177
<action dev="ggregory" type="update" due-to="Dependabot">
7278
Update junit-jupiter from 5.6.2 to 5.7.0 #153.

src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import java.io.IOException;
2121
import java.nio.file.FileVisitResult;
22-
import java.nio.file.Files;
2322
import java.nio.file.Path;
2423
import java.nio.file.attribute.BasicFileAttributes;
2524
import java.util.ArrayList;
@@ -28,12 +27,34 @@
2827
import java.util.Objects;
2928

3029
import org.apache.commons.io.file.Counters.PathCounters;
30+
import org.apache.commons.io.filefilter.PathFilter;
3131

3232
/**
3333
* Accumulates normalized paths during visitation.
3434
* <p>
3535
* Use with care on large file trees as each visited Path element is remembered.
3636
* </p>
37+
* <h2>Example</h2>
38+
*
39+
* <pre>
40+
* Path dir = Paths.get(".");
41+
* // We are interested in files older than one day
42+
* long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
43+
* AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new AgeFileFilter(cutoff));
44+
* //
45+
* // Walk one dir
46+
* Files.walkFileTree(dir, Collections.emptySet(), 1, visitor);
47+
* System.out.println(visitor.getPathCounters());
48+
* System.out.println(visitor.getFileList());
49+
* //
50+
* visitor.getPathCounters().reset();
51+
* //
52+
* // Walk dir tree
53+
* Files.walkFileTree(dir, visitor);
54+
* System.out.println(visitor.getPathCounters());
55+
* System.out.println(visitor.getDirList());
56+
* System.out.println(visitor.getFileList());
57+
* </pre>
3758
*
3859
* @since 2.7
3960
*/
@@ -57,19 +78,65 @@ public static AccumulatorPathVisitor withLongCounters() {
5778
return new AccumulatorPathVisitor(Counters.longPathCounters());
5879
}
5980

81+
/**
82+
* Creates a new instance configured with a long {@link PathCounters}.
83+
*
84+
* @param pathFilter Filters files to accumulate and count.
85+
* @return a new instance configured with a long {@link PathCounters}.
86+
* @since 2.9.0
87+
*/
88+
public static AccumulatorPathVisitor withLongCounters(final PathFilter pathFilter) {
89+
return new AccumulatorPathVisitor(Counters.longPathCounters(), pathFilter);
90+
}
91+
92+
/**
93+
* Creates a new instance configured with a BigInteger {@link PathCounters}.
94+
*
95+
* @param pathFilter Filters files to accumulate and count.
96+
* @return a new instance configured with a long {@link PathCounters}.
97+
* @since 2.9.0
98+
*/
99+
public static AccumulatorPathVisitor withBigIntegerCounters(final PathFilter pathFilter) {
100+
return new AccumulatorPathVisitor(Counters.bigIntegerPathCounters(), pathFilter);
101+
}
102+
60103
private final List<Path> dirList = new ArrayList<>();
61104

62105
private final List<Path> fileList = new ArrayList<>();
63106

64107
/**
65108
* Constructs a new instance.
66109
*
110+
* @since 2.9.0
111+
*/
112+
public AccumulatorPathVisitor() {
113+
super(Counters.noopPathCounters());
114+
}
115+
116+
/**
117+
* Constructs a new instance that counts file system elements.
118+
*
67119
* @param pathCounter How to count path visits.
68120
*/
69121
public AccumulatorPathVisitor(final PathCounters pathCounter) {
70122
super(pathCounter);
71123
}
72124

125+
/**
126+
* Constructs a new instance.
127+
*
128+
* @param pathCounter How to count path visits.
129+
* @param pathFilter Filters which paths to count.
130+
* @since 2.9.0
131+
*/
132+
public AccumulatorPathVisitor(final PathCounters pathCounter, final PathFilter pathFilter) {
133+
super(pathCounter, pathFilter);
134+
}
135+
136+
private void add(final List<Path> list, final Path dir) {
137+
list.add(dir.normalize());
138+
}
139+
73140
@Override
74141
public boolean equals(final Object obj) {
75142
if (this == obj) {
@@ -111,6 +178,12 @@ public int hashCode() {
111178
return result;
112179
}
113180

181+
@Override
182+
public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException {
183+
add(dirList, dir);
184+
return super.postVisitDirectory(dir, exc);
185+
}
186+
114187
/**
115188
* Relativizes each directory path with {@link Path#relativize(Path)} against the given {@code parent}, optionally
116189
* sorting the result.
@@ -120,7 +193,8 @@ public int hashCode() {
120193
* @param comparator How to sort, null uses default sorting.
121194
* @return A new list
122195
*/
123-
public List<Path> relativizeDirectories(final Path parent, final boolean sort, final Comparator<? super Path> comparator) {
196+
public List<Path> relativizeDirectories(final Path parent, final boolean sort,
197+
final Comparator<? super Path> comparator) {
124198
return PathUtils.relativize(getDirList(), parent, sort, comparator);
125199
}
126200

@@ -133,13 +207,14 @@ public List<Path> relativizeDirectories(final Path parent, final boolean sort, f
133207
* @param comparator How to sort, null uses default sorting.
134208
* @return A new list
135209
*/
136-
public List<Path> relativizeFiles(final Path parent, final boolean sort, final Comparator<? super Path> comparator) {
210+
public List<Path> relativizeFiles(final Path parent, final boolean sort,
211+
final Comparator<? super Path> comparator) {
137212
return PathUtils.relativize(getFileList(), parent, sort, comparator);
138213
}
139214

140215
@Override
141216
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attributes) throws IOException {
142-
((Files.isDirectory(file)) ? dirList : fileList).add(file.normalize());
217+
add(fileList, file);
143218
return super.visitFile(file, attributes);
144219
}
145220

src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.Objects;
2828

2929
import org.apache.commons.io.file.Counters.PathCounters;
30+
import org.apache.commons.io.filefilter.PathFilter;
3031

3132
/**
3233
* Copies a source directory to a target directory.
@@ -35,8 +36,6 @@
3536
*/
3637
public class CopyDirectoryVisitor extends CountingPathVisitor {
3738

38-
private static final CopyOption[] EMPTY_COPY_OPTIONS = new CopyOption[0];
39-
4039
private final CopyOption[] copyOptions;
4140
private final Path sourceDirectory;
4241
private final Path targetDirectory;
@@ -54,7 +53,25 @@ public CopyDirectoryVisitor(final PathCounters pathCounter, final Path sourceDir
5453
super(pathCounter);
5554
this.sourceDirectory = sourceDirectory;
5655
this.targetDirectory = targetDirectory;
57-
this.copyOptions = copyOptions == null ? EMPTY_COPY_OPTIONS : copyOptions.clone();
56+
this.copyOptions = copyOptions == null ? PathUtils.EMPTY_COPY_OPTIONS : copyOptions.clone();
57+
}
58+
59+
/**
60+
* Constructs a new visitor that deletes files except for the files and directories explicitly given.
61+
*
62+
* @param pathCounter How to count visits.
63+
* @param pathFilter How to filter paths.
64+
* @param sourceDirectory The source directory
65+
* @param targetDirectory The target directory
66+
* @param copyOptions Specifies how the copying should be done.
67+
* @since 2.9.0
68+
*/
69+
public CopyDirectoryVisitor(final PathCounters pathCounter, final PathFilter pathFilter, final Path sourceDirectory, final Path targetDirectory,
70+
final CopyOption... copyOptions) {
71+
super(pathCounter, pathFilter);
72+
this.sourceDirectory = sourceDirectory;
73+
this.targetDirectory = targetDirectory;
74+
this.copyOptions = copyOptions == null ? PathUtils.EMPTY_COPY_OPTIONS : copyOptions.clone();
5875
}
5976

6077
/**

0 commit comments

Comments
 (0)