Skip to content

Commit d6877f4

Browse files
committed
Add FileAlterationObserver.Builder() and deprecate most constructors
1 parent 84aff3f commit d6877f4

4 files changed

Lines changed: 245 additions & 21 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ The <action> type attribute can be add,update,fix,remove.
5858
<action dev="ggregory" type="add" due-to="Gary Gregory">Add a "Safe Deserialization" section to the User Guide for the site.</action>
5959
<action dev="ggregory" type="add" due-to="Gary Gregory">Add IORandomAccessFile.</action>
6060
<action dev="ggregory" type="add" due-to="Gary Gregory">Add RandomAccessFileMode.io(String).</action>
61+
<action dev="ggregory" type="add" due-to="Gary Gregory">Add FileAlterationObserver.Builder() and deprecate most constructors.</action>
6162
<!-- UPDATE -->
6263
<action dev="ggregory" type="update" due-to="Gary Gregory">Bump org.apache.commons:commons-parent from 74 to 77 #670, #676, #679.</action>
6364
<action dev="ggregory" type="update" due-to="Gary Gregory">Bump commons.bytebuddy.version from 1.15.1 to 1.15.4 #672, #673, #685.</action>

src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java

Lines changed: 102 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.io.File;
2020
import java.io.FileFilter;
21+
import java.io.IOException;
2122
import java.io.Serializable;
2223
import java.util.ArrayList;
2324
import java.util.Arrays;
@@ -29,6 +30,7 @@
2930

3031
import org.apache.commons.io.FileUtils;
3132
import org.apache.commons.io.IOCase;
33+
import org.apache.commons.io.build.AbstractOriginSupplier;
3234
import org.apache.commons.io.comparator.NameFileComparator;
3335
import org.apache.commons.io.filefilter.TrueFileFilter;
3436

@@ -44,6 +46,7 @@
4446
* <li>Either register the observer(s) with a {@link FileAlterationMonitor} or run manually.</li>
4547
* </ul>
4648
* <h2>Basic Usage</h2> Create a {@link FileAlterationObserver} for the directory and register the listeners:
49+
*
4750
* <pre>
4851
* File directory = new File(FileUtils.current(), "src");
4952
* FileAlterationObserver observer = new FileAlterationObserver(directory);
@@ -53,6 +56,7 @@
5356
* <p>
5457
* To manually observe a directory, initialize the observer and invoked the {@link #checkAndNotify()} method as required:
5558
* </p>
59+
*
5660
* <pre>
5761
* // initialize
5862
* observer.init();
@@ -68,6 +72,7 @@
6872
* <p>
6973
* Alternatively, register the observer(s) with a {@link FileAlterationMonitor}, which creates a new thread, invoking the observer at the specified interval:
7074
* </p>
75+
*
7176
* <pre>
7277
* long interval = ...
7378
* FileAlterationMonitor monitor = new FileAlterationMonitor(interval);
@@ -76,6 +81,7 @@
7681
* ...
7782
* monitor.stop();
7883
* </pre>
84+
*
7985
* <h2>File Filters</h2> This implementation can monitor portions of the file system by using {@link FileFilter}s to observe only the files and/or directories
8086
* that are of interest. This makes it more efficient and reduces the noise from <em>unwanted</em> file system events.
8187
* <p>
@@ -86,6 +92,7 @@
8692
* For example, to only observe 1) visible directories and 2) files with a ".java" suffix in a root directory called "src" you could set up a
8793
* {@link FileAlterationObserver} in the following way:
8894
* </p>
95+
*
8996
* <pre>
9097
* // Create a FileFilter
9198
* IOFileFilter directories = FileFilterUtils.and(
@@ -101,12 +108,12 @@
101108
* observer.addListener(...);
102109
* observer.addListener(...);
103110
* </pre>
111+
*
104112
* <h2>FileEntry</h2>
105113
* <p>
106-
* {@link FileEntry} represents the state of a file or directory, capturing {@link File} attributes at a point in time. Custom
107-
* implementations of {@link FileEntry} can be used to capture additional properties that the basic implementation does not support. The
108-
* {@link FileEntry#refresh(File)} method is used to determine if a file or directory has changed since the last check and stores the current state of the
109-
* {@link File}'s properties.
114+
* {@link FileEntry} represents the state of a file or directory, capturing {@link File} attributes at a point in time. Custom implementations of
115+
* {@link FileEntry} can be used to capture additional properties that the basic implementation does not support. The {@link FileEntry#refresh(File)} method is
116+
* used to determine if a file or directory has changed since the last check and stores the current state of the {@link File}'s properties.
110117
* </p>
111118
* <h2>Deprecating Serialization</h2>
112119
* <p>
@@ -119,8 +126,76 @@
119126
*/
120127
public class FileAlterationObserver implements Serializable {
121128

129+
/**
130+
* Builds instances of {@link FileAlterationObserver}.
131+
*
132+
* @since 2.18.0
133+
*/
134+
public static final class Builder extends AbstractOriginSupplier<FileAlterationObserver, Builder> {
135+
136+
private FileEntry rootEntry;
137+
private FileFilter fileFilter;
138+
private IOCase ioCase;
139+
140+
private Builder() {
141+
// empty
142+
}
143+
144+
/**
145+
* Gets a new {@link FileAlterationObserver} instance.
146+
*/
147+
@Override
148+
public FileAlterationObserver get() throws IOException {
149+
return new FileAlterationObserver(rootEntry != null ? rootEntry : new FileEntry(checkOrigin().getFile()), fileFilter, toComparator(ioCase));
150+
}
151+
152+
/**
153+
* Sets the file filter or null if none.
154+
*
155+
* @param fileFilter file filter or null if none.
156+
* @return This instance.
157+
*/
158+
public Builder setFileFilter(final FileFilter fileFilter) {
159+
this.fileFilter = fileFilter;
160+
return asThis();
161+
}
162+
163+
/**
164+
* Sets what case sensitivity to use comparing file names, null means system sensitive.
165+
*
166+
* @param ioCase what case sensitivity to use comparing file names, null means system sensitive.
167+
* @return This instance.
168+
*/
169+
public Builder setIOCase(final IOCase ioCase) {
170+
this.ioCase = ioCase;
171+
return asThis();
172+
}
173+
174+
/**
175+
* Sets the root directory to observe.
176+
*
177+
* @param rootEntry the root directory to observe.
178+
* @return This instance.
179+
*/
180+
public Builder setRootEntry(final FileEntry rootEntry) {
181+
this.rootEntry = rootEntry;
182+
return asThis();
183+
}
184+
185+
}
186+
122187
private static final long serialVersionUID = 1185122225658782848L;
123188

189+
/**
190+
* Creates a new builder.
191+
*
192+
* @return a new builder.
193+
* @since 2.18.0
194+
*/
195+
public static Builder builder() {
196+
return new Builder();
197+
}
198+
124199
private static Comparator<File> toComparator(final IOCase ioCase) {
125200
switch (IOCase.value(ioCase, IOCase.SYSTEM)) {
126201
case SYSTEM:
@@ -156,38 +231,44 @@ private static Comparator<File> toComparator(final IOCase ioCase) {
156231
* Constructs an observer for the specified directory.
157232
*
158233
* @param directory the directory to observe.
234+
* @deprecated Use {@link #builder()}.
159235
*/
236+
@Deprecated
160237
public FileAlterationObserver(final File directory) {
161238
this(directory, null);
162239
}
163240

164241
/**
165242
* Constructs an observer for the specified directory and file filter.
166243
*
167-
* @param directory the directory to observe.
244+
* @param directory The directory to observe.
168245
* @param fileFilter The file filter or null if none.
246+
* @deprecated Use {@link #builder()}.
169247
*/
248+
@Deprecated
170249
public FileAlterationObserver(final File directory, final FileFilter fileFilter) {
171250
this(directory, fileFilter, null);
172251
}
173252

174253
/**
175254
* Constructs an observer for the specified directory, file filter and file comparator.
176255
*
177-
* @param directory the directory to observe.
256+
* @param directory The directory to observe.
178257
* @param fileFilter The file filter or null if none.
179-
* @param ioCase what case sensitivity to use comparing file names, null means system sensitive.
258+
* @param ioCase What case sensitivity to use comparing file names, null means system sensitive.
259+
* @deprecated Use {@link #builder()}.
180260
*/
261+
@Deprecated
181262
public FileAlterationObserver(final File directory, final FileFilter fileFilter, final IOCase ioCase) {
182263
this(new FileEntry(directory), fileFilter, ioCase);
183264
}
184265

185266
/**
186267
* Constructs an observer for the specified directory, file filter and file comparator.
187268
*
188-
* @param rootEntry the root directory to observe.
269+
* @param rootEntry The root directory to observe.
189270
* @param fileFilter The file filter or null if none.
190-
* @param comparator how to compare files.
271+
* @param comparator How to compare files.
191272
*/
192273
private FileAlterationObserver(final FileEntry rootEntry, final FileFilter fileFilter, final Comparator<File> comparator) {
193274
Objects.requireNonNull(rootEntry, "rootEntry");
@@ -200,9 +281,9 @@ private FileAlterationObserver(final FileEntry rootEntry, final FileFilter fileF
200281
/**
201282
* Constructs an observer for the specified directory, file filter and file comparator.
202283
*
203-
* @param rootEntry the root directory to observe.
284+
* @param rootEntry The root directory to observe.
204285
* @param fileFilter The file filter or null if none.
205-
* @param ioCase what case sensitivity to use comparing file names, null means system sensitive.
286+
* @param ioCase What case sensitivity to use comparing file names, null means system sensitive.
206287
*/
207288
protected FileAlterationObserver(final FileEntry rootEntry, final FileFilter fileFilter, final IOCase ioCase) {
208289
this(rootEntry, fileFilter, toComparator(ioCase));
@@ -212,7 +293,9 @@ protected FileAlterationObserver(final FileEntry rootEntry, final FileFilter fil
212293
* Constructs an observer for the specified directory.
213294
*
214295
* @param directoryName the name of the directory to observe.
296+
* @deprecated Use {@link #builder()}.
215297
*/
298+
@Deprecated
216299
public FileAlterationObserver(final String directoryName) {
217300
this(new File(directoryName));
218301
}
@@ -222,7 +305,9 @@ public FileAlterationObserver(final String directoryName) {
222305
*
223306
* @param directoryName the name of the directory to observe.
224307
* @param fileFilter The file filter or null if none.
308+
* @deprecated Use {@link #builder()}.
225309
*/
310+
@Deprecated
226311
public FileAlterationObserver(final String directoryName, final FileFilter fileFilter) {
227312
this(new File(directoryName), fileFilter);
228313
}
@@ -233,7 +318,9 @@ public FileAlterationObserver(final String directoryName, final FileFilter fileF
233318
* @param directoryName the name of the directory to observe.
234319
* @param fileFilter The file filter or null if none.
235320
* @param ioCase what case sensitivity to use comparing file names, null means system sensitive.
321+
* @deprecated Use {@link #builder()}.
236322
*/
323+
@Deprecated
237324
public FileAlterationObserver(final String directoryName, final FileFilter fileFilter, final IOCase ioCase) {
238325
this(new File(directoryName), fileFilter, ioCase);
239326
}
@@ -376,6 +463,10 @@ private void fireOnDelete(final FileEntry entry) {
376463
});
377464
}
378465

466+
Comparator<File> getComparator() {
467+
return comparator;
468+
}
469+
379470
/**
380471
* Returns the directory being observed.
381472
*

src/test/java/org/apache/commons/io/monitor/AbstractMonitorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ protected void checkCollectionSizes(String label,
9898
* @param fileFilter The file filter to apply
9999
*/
100100
protected void createObserver(final File file, final FileFilter fileFilter) {
101-
observer = new FileAlterationObserver(file, fileFilter);
101+
observer = FileAlterationObserver.builder().setFile(file).setFileFilter(fileFilter).getUnchecked();
102102
observer.addListener(listener);
103103
observer.addListener(new FileAlterationListenerAdaptor());
104104
try {

0 commit comments

Comments
 (0)