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 d6877f494 Add FileAlterationObserver.Builder() and deprecate most 
constructors
d6877f494 is described below

commit d6877f494fc801bf95655a73a35c15f425908c75
Author: Gary Gregory <[email protected]>
AuthorDate: Thu Oct 17 09:53:23 2024 -0400

    Add FileAlterationObserver.Builder() and deprecate most constructors
---
 src/changes/changes.xml                            |   1 +
 .../commons/io/monitor/FileAlterationObserver.java | 113 ++++++++++++++--
 .../commons/io/monitor/AbstractMonitorTest.java    |   2 +-
 .../io/monitor/FileAlterationObserverTest.java     | 150 +++++++++++++++++++--
 4 files changed, 245 insertions(+), 21 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 3a2e57787..cc3ed7140 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -58,6 +58,7 @@ The <action> type attribute can be add,update,fix,remove.
       <action dev="ggregory" type="add"                due-to="Gary 
Gregory">Add a "Safe Deserialization" section to the User Guide for the 
site.</action>
       <action dev="ggregory" type="add"                due-to="Gary 
Gregory">Add IORandomAccessFile.</action>
       <action dev="ggregory" type="add"                due-to="Gary 
Gregory">Add RandomAccessFileMode.io(String).</action>
+      <action dev="ggregory" type="add"                due-to="Gary 
Gregory">Add FileAlterationObserver.Builder() and deprecate most 
constructors.</action>
       <!-- UPDATE -->
       <action dev="ggregory" type="update"             due-to="Gary 
Gregory">Bump org.apache.commons:commons-parent from 74 to 77 #670, #676, 
#679.</action>
       <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>
diff --git 
a/src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java 
b/src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java
index 4b3289a9b..393867319 100644
--- a/src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java
+++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java
@@ -18,6 +18,7 @@ package org.apache.commons.io.monitor;
 
 import java.io.File;
 import java.io.FileFilter;
+import java.io.IOException;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -29,6 +30,7 @@ import java.util.stream.Stream;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOCase;
+import org.apache.commons.io.build.AbstractOriginSupplier;
 import org.apache.commons.io.comparator.NameFileComparator;
 import org.apache.commons.io.filefilter.TrueFileFilter;
 
@@ -44,6 +46,7 @@ import org.apache.commons.io.filefilter.TrueFileFilter;
  * <li>Either register the observer(s) with a {@link FileAlterationMonitor} or 
run manually.</li>
  * </ul>
  * <h2>Basic Usage</h2> Create a {@link FileAlterationObserver} for the 
directory and register the listeners:
+ *
  * <pre>
  *      File directory = new File(FileUtils.current(), "src");
  *      FileAlterationObserver observer = new 
FileAlterationObserver(directory);
@@ -53,6 +56,7 @@ import org.apache.commons.io.filefilter.TrueFileFilter;
  * <p>
  * To manually observe a directory, initialize the observer and invoked the 
{@link #checkAndNotify()} method as required:
  * </p>
+ *
  * <pre>
  *      // initialize
  *      observer.init();
@@ -68,6 +72,7 @@ import org.apache.commons.io.filefilter.TrueFileFilter;
  * <p>
  * Alternatively, register the observer(s) with a {@link 
FileAlterationMonitor}, which creates a new thread, invoking the observer at 
the specified interval:
  * </p>
+ *
  * <pre>
  *      long interval = ...
  *      FileAlterationMonitor monitor = new FileAlterationMonitor(interval);
@@ -76,6 +81,7 @@ import org.apache.commons.io.filefilter.TrueFileFilter;
  *      ...
  *      monitor.stop();
  * </pre>
+ *
  * <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
  * that are of interest. This makes it more efficient and reduces the noise 
from <em>unwanted</em> file system events.
  * <p>
@@ -86,6 +92,7 @@ import org.apache.commons.io.filefilter.TrueFileFilter;
  * 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
  * {@link FileAlterationObserver} in the following way:
  * </p>
+ *
  * <pre>
  *      // Create a FileFilter
  *      IOFileFilter directories = FileFilterUtils.and(
@@ -101,12 +108,12 @@ import org.apache.commons.io.filefilter.TrueFileFilter;
  *      observer.addListener(...);
  *      observer.addListener(...);
  * </pre>
+ *
  * <h2>FileEntry</h2>
  * <p>
- * {@link FileEntry} represents the state of a file or directory, capturing 
{@link File} attributes at a point in time. Custom
- * implementations of {@link FileEntry} can be used to capture additional 
properties that the basic implementation does not support. The
- * {@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
- * {@link File}'s properties.
+ * {@link FileEntry} represents the state of a file or directory, capturing 
{@link File} attributes at a point in time. Custom implementations of
+ * {@link FileEntry} can be used to capture additional properties that the 
basic implementation does not support. The {@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 {@link File}'s properties.
  * </p>
  * <h2>Deprecating Serialization</h2>
  * <p>
@@ -119,8 +126,76 @@ import org.apache.commons.io.filefilter.TrueFileFilter;
  */
 public class FileAlterationObserver implements Serializable {
 
+    /**
+     * Builds instances of {@link FileAlterationObserver}.
+     *
+     * @since 2.18.0
+     */
+    public static final class Builder extends 
AbstractOriginSupplier<FileAlterationObserver, Builder> {
+
+        private FileEntry rootEntry;
+        private FileFilter fileFilter;
+        private IOCase ioCase;
+
+        private Builder() {
+            // empty
+        }
+
+        /**
+         * Gets a new {@link FileAlterationObserver} instance.
+         */
+        @Override
+        public FileAlterationObserver get() throws IOException {
+            return new FileAlterationObserver(rootEntry != null ? rootEntry : 
new FileEntry(checkOrigin().getFile()), fileFilter, toComparator(ioCase));
+        }
+
+        /**
+         * Sets the file filter or null if none.
+         *
+         * @param fileFilter file filter or null if none.
+         * @return This instance.
+         */
+        public Builder setFileFilter(final FileFilter fileFilter) {
+            this.fileFilter = fileFilter;
+            return asThis();
+        }
+
+        /**
+         * Sets what case sensitivity to use comparing file names, null means 
system sensitive.
+         *
+         * @param ioCase what case sensitivity to use comparing file names, 
null means system sensitive.
+         * @return This instance.
+         */
+        public Builder setIOCase(final IOCase ioCase) {
+            this.ioCase = ioCase;
+            return asThis();
+        }
+
+        /**
+         * Sets the root directory to observe.
+         *
+         * @param rootEntry the root directory to observe.
+         * @return This instance.
+         */
+        public Builder setRootEntry(final FileEntry rootEntry) {
+            this.rootEntry = rootEntry;
+            return asThis();
+        }
+
+    }
+
     private static final long serialVersionUID = 1185122225658782848L;
 
+    /**
+     * Creates a new builder.
+     *
+     * @return a new builder.
+     * @since 2.18.0
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
     private static Comparator<File> toComparator(final IOCase ioCase) {
         switch (IOCase.value(ioCase, IOCase.SYSTEM)) {
         case SYSTEM:
@@ -156,7 +231,9 @@ public class FileAlterationObserver implements Serializable 
{
      * Constructs an observer for the specified directory.
      *
      * @param directory the directory to observe.
+     * @deprecated Use {@link #builder()}.
      */
+    @Deprecated
     public FileAlterationObserver(final File directory) {
         this(directory, null);
     }
@@ -164,9 +241,11 @@ public class FileAlterationObserver implements 
Serializable {
     /**
      * Constructs an observer for the specified directory and file filter.
      *
-     * @param directory  the directory to observe.
+     * @param directory  The directory to observe.
      * @param fileFilter The file filter or null if none.
+     * @deprecated Use {@link #builder()}.
      */
+    @Deprecated
     public FileAlterationObserver(final File directory, final FileFilter 
fileFilter) {
         this(directory, fileFilter, null);
     }
@@ -174,10 +253,12 @@ public class FileAlterationObserver implements 
Serializable {
     /**
      * Constructs an observer for the specified directory, file filter and 
file comparator.
      *
-     * @param directory  the directory to observe.
+     * @param directory  The directory to observe.
      * @param fileFilter The file filter or null if none.
-     * @param ioCase     what case sensitivity to use comparing file names, 
null means system sensitive.
+     * @param ioCase     What case sensitivity to use comparing file names, 
null means system sensitive.
+     * @deprecated Use {@link #builder()}.
      */
+    @Deprecated
     public FileAlterationObserver(final File directory, final FileFilter 
fileFilter, final IOCase ioCase) {
         this(new FileEntry(directory), fileFilter, ioCase);
     }
@@ -185,9 +266,9 @@ public class FileAlterationObserver implements Serializable 
{
     /**
      * Constructs an observer for the specified directory, file filter and 
file comparator.
      *
-     * @param rootEntry  the root directory to observe.
+     * @param rootEntry  The root directory to observe.
      * @param fileFilter The file filter or null if none.
-     * @param comparator how to compare files.
+     * @param comparator How to compare files.
      */
     private FileAlterationObserver(final FileEntry rootEntry, final FileFilter 
fileFilter, final Comparator<File> comparator) {
         Objects.requireNonNull(rootEntry, "rootEntry");
@@ -200,9 +281,9 @@ public class FileAlterationObserver implements Serializable 
{
     /**
      * Constructs an observer for the specified directory, file filter and 
file comparator.
      *
-     * @param rootEntry  the root directory to observe.
+     * @param rootEntry  The root directory to observe.
      * @param fileFilter The file filter or null if none.
-     * @param ioCase     what case sensitivity to use comparing file names, 
null means system sensitive.
+     * @param ioCase     What case sensitivity to use comparing file names, 
null means system sensitive.
      */
     protected FileAlterationObserver(final FileEntry rootEntry, final 
FileFilter fileFilter, final IOCase ioCase) {
         this(rootEntry, fileFilter, toComparator(ioCase));
@@ -212,7 +293,9 @@ public class FileAlterationObserver implements Serializable 
{
      * Constructs an observer for the specified directory.
      *
      * @param directoryName the name of the directory to observe.
+     * @deprecated Use {@link #builder()}.
      */
+    @Deprecated
     public FileAlterationObserver(final String directoryName) {
         this(new File(directoryName));
     }
@@ -222,7 +305,9 @@ public class FileAlterationObserver implements Serializable 
{
      *
      * @param directoryName the name of the directory to observe.
      * @param fileFilter    The file filter or null if none.
+     * @deprecated Use {@link #builder()}.
      */
+    @Deprecated
     public FileAlterationObserver(final String directoryName, final FileFilter 
fileFilter) {
         this(new File(directoryName), fileFilter);
     }
@@ -233,7 +318,9 @@ public class FileAlterationObserver implements Serializable 
{
      * @param directoryName the name of the directory to observe.
      * @param fileFilter    The file filter or null if none.
      * @param ioCase        what case sensitivity to use comparing file names, 
null means system sensitive.
+     * @deprecated Use {@link #builder()}.
      */
+    @Deprecated
     public FileAlterationObserver(final String directoryName, final FileFilter 
fileFilter, final IOCase ioCase) {
         this(new File(directoryName), fileFilter, ioCase);
     }
@@ -376,6 +463,10 @@ public class FileAlterationObserver implements 
Serializable {
         });
     }
 
+    Comparator<File> getComparator() {
+        return comparator;
+    }
+
     /**
      * Returns the directory being observed.
      *
diff --git 
a/src/test/java/org/apache/commons/io/monitor/AbstractMonitorTest.java 
b/src/test/java/org/apache/commons/io/monitor/AbstractMonitorTest.java
index 6f076d096..d807179fe 100644
--- a/src/test/java/org/apache/commons/io/monitor/AbstractMonitorTest.java
+++ b/src/test/java/org/apache/commons/io/monitor/AbstractMonitorTest.java
@@ -98,7 +98,7 @@ public abstract class AbstractMonitorTest {
      * @param fileFilter The file filter to apply
      */
     protected void createObserver(final File file, final FileFilter 
fileFilter) {
-        observer = new FileAlterationObserver(file, fileFilter);
+        observer = 
FileAlterationObserver.builder().setFile(file).setFileFilter(fileFilter).getUnchecked();
         observer.addListener(listener);
         observer.addListener(new FileAlterationListenerAdaptor());
         try {
diff --git 
a/src/test/java/org/apache/commons/io/monitor/FileAlterationObserverTest.java 
b/src/test/java/org/apache/commons/io/monitor/FileAlterationObserverTest.java
index b51ffcd1e..29db41d54 100644
--- 
a/src/test/java/org/apache/commons/io/monitor/FileAlterationObserverTest.java
+++ 
b/src/test/java/org/apache/commons/io/monitor/FileAlterationObserverTest.java
@@ -26,8 +26,12 @@ import java.io.IOException;
 import java.util.Iterator;
 
 import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOCase;
+import org.apache.commons.io.comparator.NameFileComparator;
 import org.apache.commons.io.filefilter.CanReadFileFilter;
 import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.apache.commons.io.monitor.FileAlterationObserver.Builder;
 import org.junit.jupiter.api.Test;
 
 /**
@@ -35,6 +39,8 @@ import org.junit.jupiter.api.Test;
  */
 public class FileAlterationObserverTest extends AbstractMonitorTest {
 
+    private static final String PATH_STRING_FIXTURE = "/foo";
+
     /**
      * Constructs a new instance.
      */
@@ -49,12 +55,16 @@ public class FileAlterationObserverTest extends 
AbstractMonitorTest {
         observer.checkAndNotify();
     }
 
+    private String directoryToUnixString(final FileAlterationObserver 
observer) {
+        return 
FilenameUtils.separatorsToUnix(observer.getDirectory().toString());
+    }
+
     /**
      * Test add/remove listeners.
      */
     @Test
     public void testAddRemoveListeners() {
-        final FileAlterationObserver observer = new 
FileAlterationObserver("/foo");
+        final FileAlterationObserver observer = 
FileAlterationObserver.builder().setFile(PATH_STRING_FIXTURE).getUnchecked();
         // Null Listener
         observer.addListener(null);
         assertFalse(observer.getListeners().iterator().hasNext(), 
"Listeners[1]");
@@ -74,10 +84,134 @@ public class FileAlterationObserverTest extends 
AbstractMonitorTest {
         assertFalse(observer.getListeners().iterator().hasNext(), 
"Listeners[5]");
     }
 
+    @Test
+    public void testBuilder_File() {
+        final File file = new File(PATH_STRING_FIXTURE);
+        final FileAlterationObserver observer = 
FileAlterationObserver.builder().setFile(file).getUnchecked();
+        assertEquals(file, observer.getDirectory());
+    }
+
+    @Test
+    public void testBuilder_File_FileFilter() {
+        final File file = new File(PATH_STRING_FIXTURE);
+        // @formatter:off
+        final FileAlterationObserver observer = 
FileAlterationObserver.builder()
+                .setFile(file)
+                .setFileFilter(CanReadFileFilter.CAN_READ)
+                .getUnchecked();
+        // @formatter:on
+        assertEquals(file, observer.getDirectory());
+        assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
+    }
+
+    @Test
+    public void testBuilder_File_FileFilter_IOCase() {
+        final File file = new File(PATH_STRING_FIXTURE);
+        // @formatter:off
+        final FileAlterationObserver observer = 
FileAlterationObserver.builder()
+                .setFile(file)
+                .setFileFilter(CanReadFileFilter.CAN_READ)
+                .setIOCase(IOCase.INSENSITIVE)
+                .getUnchecked();
+        // @formatter:on
+        assertEquals(file, observer.getDirectory());
+        assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
+        assertEquals(NameFileComparator.NAME_INSENSITIVE_COMPARATOR, 
observer.getComparator());
+    }
+
+    @Test
+    public void testBuilder_String() {
+        final String file = PATH_STRING_FIXTURE;
+        final FileAlterationObserver observer = 
FileAlterationObserver.builder().setFile(file).getUnchecked();
+        assertEquals(file, directoryToUnixString(observer));
+    }
+
+    @Test
+    public void testBuilder_String_FileFilter() {
+        final String file = PATH_STRING_FIXTURE;
+        // @formatter:off
+        final FileAlterationObserver observer = 
FileAlterationObserver.builder()
+                .setFile(file)
+                .setFileFilter(CanReadFileFilter.CAN_READ)
+                .getUnchecked();
+        // @formatter:on
+        assertEquals(file, directoryToUnixString(observer));
+        assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
+    }
+
+    @Test
+    public void testBuilder_String_FileFilter_IOCase() {
+        final String file = PATH_STRING_FIXTURE;
+        // @formatter:off
+        final FileAlterationObserver observer = 
FileAlterationObserver.builder()
+                .setFile(file)
+                .setFileFilter(CanReadFileFilter.CAN_READ)
+                .setIOCase(IOCase.INSENSITIVE)
+                .getUnchecked();
+        // @formatter:on
+        assertEquals(file, directoryToUnixString(observer));
+        assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
+        assertEquals(NameFileComparator.NAME_INSENSITIVE_COMPARATOR, 
observer.getComparator());
+    }
+
+    @Test
+    public void testConstructor_File() {
+        final File file = new File(PATH_STRING_FIXTURE);
+        @SuppressWarnings("deprecation")
+        final FileAlterationObserver observer = new 
FileAlterationObserver(file);
+        assertEquals(file, observer.getDirectory());
+    }
+
+    @Test
+    public void testConstructor_File_FileFilter() {
+        final File file = new File(PATH_STRING_FIXTURE);
+        @SuppressWarnings("deprecation")
+        final FileAlterationObserver observer = new 
FileAlterationObserver(file, CanReadFileFilter.CAN_READ);
+        assertEquals(file, observer.getDirectory());
+        assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
+    }
+
+    @Test
+    public void testConstructor_File_FileFilter_IOCase() {
+        final File file = new File(PATH_STRING_FIXTURE);
+        @SuppressWarnings("deprecation")
+        final FileAlterationObserver observer = new 
FileAlterationObserver(file, CanReadFileFilter.CAN_READ, IOCase.INSENSITIVE);
+        assertEquals(file, observer.getDirectory());
+        assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
+        assertEquals(NameFileComparator.NAME_INSENSITIVE_COMPARATOR, 
observer.getComparator());
+    }
+
+    @Test
+    public void testConstructor_String() {
+        final String file = PATH_STRING_FIXTURE;
+        @SuppressWarnings("deprecation")
+        final FileAlterationObserver observer = new 
FileAlterationObserver(file);
+        assertEquals(file, directoryToUnixString(observer));
+    }
+
+    @Test
+    public void testConstructor_String_FileFilter() {
+        final String file = PATH_STRING_FIXTURE;
+        @SuppressWarnings("deprecation")
+        final FileAlterationObserver observer = new 
FileAlterationObserver(file, CanReadFileFilter.CAN_READ);
+        assertEquals(file, directoryToUnixString(observer));
+        assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
+    }
+
+    @Test
+    public void testConstructor_String_FileFilter_IOCase() {
+        final String file = PATH_STRING_FIXTURE;
+        @SuppressWarnings("deprecation")
+        final FileAlterationObserver observer = new 
FileAlterationObserver(file, CanReadFileFilter.CAN_READ, IOCase.INSENSITIVE);
+        assertEquals(file, directoryToUnixString(observer));
+        assertEquals(CanReadFileFilter.CAN_READ, observer.getFileFilter());
+        assertEquals(NameFileComparator.NAME_INSENSITIVE_COMPARATOR, 
observer.getComparator());
+    }
+
     /**
-     * Test checkAndNotify() method
+     * Tests checkAndNotify() method
      *
-     * @throws Exception
+     * @throws Exception Thrown on test failure.
      */
     @Test
     public void testDirectory() throws Exception {
@@ -373,14 +507,12 @@ public class FileAlterationObserverTest extends 
AbstractMonitorTest {
      */
     @Test
     public void testToString() {
-        final File file = new File("/foo");
-
-        FileAlterationObserver observer = new FileAlterationObserver(file);
+        final File file = new File(PATH_STRING_FIXTURE);
+        final Builder builder = FileAlterationObserver.builder();
+        FileAlterationObserver observer = builder.setFile(file).getUnchecked();
         assertEquals("FileAlterationObserver[file='" + file.getPath() + "', 
true, listeners=0]", observer.toString());
-
-        observer = new FileAlterationObserver(file, 
CanReadFileFilter.CAN_READ);
+        observer = 
builder.setFileFilter(CanReadFileFilter.CAN_READ).getUnchecked();
         assertEquals("FileAlterationObserver[file='" + file.getPath() + "', 
CanReadFileFilter, listeners=0]", observer.toString());
-
         assertEquals(file, observer.getDirectory());
     }
 }

Reply via email to