org.sadun.util.polling
Class DirectoryPoller

java.lang.Object
  extended byBaseSignalSourceThread
      extended byorg.sadun.util.polling.DirectoryPoller
Direct Known Subclasses:
ManagedDirectoryPoller

public class DirectoryPoller
extends BaseSignalSourceThread

A Thread class to periodically poll the contents of one or more directories. External asynchronous processes may put some files in one of the controlled directories, and the poller can be used to detect their arrival.

Once started, this thread polls one or more directories every x milliseconds, (see setPollInterval() and getPollInterval()), looking for new files satisfying a given filter.
Optionally, the thread may start by going to sleep (if setStartBySleeping() is invoked).

To communicate results, the thread notifies events to any registered listener (see below). Notably, if any files are "found", a FileSetFoundEvent event is notified.

A java.io.FilenameFilter can be provided at construction to identify the files to look for. Besides, the poller can be set to run in two different time-based filtering modes (disabled by default), which select only files satisfying the user-given filter and

Use setTimeBased() and isTimeBased() to enable the time-based mode and setPollingTimeBased() and isPollingTimeBased() to select the specific subtype of time-based mode.

Without time-based mode, on every pass the poller will select all the files in a controlled directory that match the filter, so it's client code responsability to phisically move the files already processed somewhere else (see also the automove mode below).

The poller always notifies an event for a set of file discovered in a particular directory. It may optionally notify a separate event for each file (see setSendSingleFileEvent() and isSendSingleFileEvent()).

The following events (all time-stamped) are produced:

Any object implementing the com.deltax.Listener interface can be registered and be notified of these events. However, a predefined listener, DefaultListener is provided, which dispatches events to an object implementing the PollManager interface, and a base implementation of PollManager, BasePollManager is provided as well.

The simplest way to receive events from the poller is therefore to create a class extending BasePollManager overriding the proper method(s) and register it to the directory poller by using addPollManager().

The order in which file events are received can be controlled by providing a Comparator object which assigns an order to the file sets read on each cycle and assigning it by setFilesSortComparator(Comparator). By default, no order is imposed, i.e. the file events will be fired in an arbitrary order, depending on the operating system. (Two pre-packaged comparators DirectoryPoller.ModificationTimeComparator and DirectoryPoller.FileSizeComparator are provided by this class).

Note: listeners will receive events asynchronously with respect to the poller thread. Therefore, if file processing is performed without moving the file out of the polled directory, the polling interval should be big enough to allow such processing to complete, or the same file may be notified more than once (expecially if time-based polling is disabled).

The version 1.2 of the class adds a new runtime mode - the autoMove mode. When running in this mode, the poller automatically moves all the files found in a controlled directory to an associated directory (which is not polled) before notifying the listeners and/or the pollmanager. The events notified will refer to the new location of the file.

This allows the user to set very short polling periods while ensuring that even slow file processing will not cause the same file to be polled more than once (even if the time-based polling mode is disabled).

If any exception occurs during the move operation, the relevant methods of PollManager are invoked (as a consequence of the notification of an underlying com.deltax.util.listener.ExceptionSignal).

If autoMove mode is enabled (see setAutoMove()) an arbitary directory may be explicitly associated to one of the controlled directories by using setAutoMoveDirectory().

If autoMove mode is enabled and the byPassLockedFiles property is true (defaults to false), locked files will be ignored. Otherwise, an exception signal will be raised if any file found in the controlled directory is locked.

If not, the poller will automatically associate to each controlled directory a subdirectory whose name is defined by the public constant DirectoryPoller.DEFAULT_AUTOMOVE_DIRECTORY. The poller will attempt to create the associated directory, if necessary - and on failure, an ExceptionSignal is sent to the listeners, and the poller shuts down.

Note that ExceptionSignals are sent only when the auto-move mode is enabled.

(*) as returned by File.lastModified().

Version:
1.4.4
Author:
C. Sadun (patched by Doug.Liao@fnf.com)
See Also:
Serialized Form

Nested Class Summary
 class DirectoryPoller.AutomoveDeleteException
          An exception raised by the poller when auto-move mode is enabled, but the target file of the move operation exists and cannot be deleted.
 class DirectoryPoller.AutomoveException
          An exception raised by the poller when auto-move mode is enabled, but the move operation failed.
static class DirectoryPoller.FileSizeComparator
          This comparator can be used to list files based on size.
static class DirectoryPoller.ModificationTimeComparator
          This comparator can be used to list files based on modification time.
static class DirectoryPoller.NullFilenameFilter
           
 
Field Summary
static java.lang.String DEFAULT_AUTOMOVE_DIRECTORY
          The name of subdirectory automatically associated by the poller to any controlled directory for the autoMode mode, unless setAutoMoveDirectory() is explicitly called before starting the poller.
protected  java.util.List pollManagersList
           
 
Constructor Summary
DirectoryPoller()
          Create a poller initially not bound to any directory, which will match any file.
DirectoryPoller(java.io.File directory)
          Create a poller over the given directory, which will match any file.
DirectoryPoller(java.io.File[] dirs)
          Create a poller over the given directories, which will match any file.
DirectoryPoller(java.io.File[] dirs, java.io.FilenameFilter filter)
          Create a poller over the given directories, using the given filter.
DirectoryPoller(java.io.File[] dirs, java.io.FilenameFilter filter, boolean timeBased)
          Create a poller over the given directories, using the given filter and time-based filtering as well (see class comment).
DirectoryPoller(java.io.File directory, java.io.FilenameFilter filter)
          Create a poller over the given directory, using the given filter.
DirectoryPoller(java.io.File directory, java.io.FilenameFilter filter, boolean timeBased)
          Create a poller over the given directory, using the given filter and time-based filtering as well (see class comment).
DirectoryPoller(java.io.FilenameFilter filter)
          Create a poller initially not bound to any directory, which uses the given filter.
DirectoryPoller(java.io.FilenameFilter filter, boolean timeBased)
          Create a poller initially not bound to any directory, which uses the given filter and time-based filtering as well (see class comment).
 
Method Summary
 void addDirectory(java.io.File dir)
          Add one directory to the controlled set.
 void addPollManager(PollManager pm)
          Adds on PollManager to the poller, which will be notified on polling events.
protected  void checkIfManaged(java.io.File directory)
           
 boolean getAutoMove()
          Verify the autoMove mode (see setAutoMove() and class description).
 java.io.File getAutoMoveDirectory(java.io.File directory)
          Returns the directory associated to the given controlled directory, where files polled are automatically moved if the autoMove mode is active (see setAutoMove() and class description).
 long getBaseTime(java.io.File directory)
          Return the current base time for the given directory.
 java.io.File[] getDirectories()
          Return the directories controlled by the poller.
 java.util.Comparator getFilesSortComparator()
          Return the comparator to use to order file found events.
 java.io.FilenameFilter getFilter()
          Get the current filter
 long getPollInterval()
          Return the current poll interval.
 boolean isBypassLockedFiles()
          Get the value of the BypassLockedFiles property.
 boolean isDebugExceptions()
          Turns on exception debugging.
 boolean isPollingTimeBased()
          Return true if the poller is time based, and uses last-polling time as a basis for the lookup (see class comment)
 boolean isSendSingleFileEvent()
          Return true if the poller is currently instructed to send per-file events to the listeners (see class comment).
 boolean isShuttingDown()
          Return true if a shutdown has been requested.
 boolean isSleeping()
           
 boolean isStartBySleeping()
          Return if the poller starts by sweeping the controlled directories, or going immediatly to sleep.
 boolean isTimeBased()
          Return true if the poller is using time-based filtering (see class comment).
 boolean isVerbose()
          Return the verbose level.
 void removeDirectory(java.io.File dir)
          Remove one directory from the controlled set.
 void run()
          Invoked when the thread is started.
 void setAutoMove(boolean v)
          Instruct the poller to automatically move the file to the directory associated to each directory under control, which can be set/retrieved by setAutoMoveDirectory()/getAutoMoveDirectory() (see also class description).
 void setAutoMoveDirectory(java.io.File directory, java.io.File autoMoveDirectory)
          Associate a directory to one of the controlled directories, for the autoMove mode (see class description).
 void setBaseTime(java.io.File directory, long time)
          Reset the base time for the given directory.
 void setBaseTime(long time)
          Reset the base time for the all the directories under control of the poller.
 void setBypassLockedFiles(boolean supportSlowTransfer)
          Set the value of the BypassLockedFiles property.
 void setDebugExceptions(boolean debugExceptions)
          Turns on exception debugging.
 void setDirectories(java.io.File[] dirs)
          Set the directories controlled by the poller.
 void setFilesSortComparator(java.util.Comparator filesSortComparator)
          Set the comparator to use to order file found events.
 void setFilter(java.io.FilenameFilter filter)
          Set the current filter.
 void setPollingTimeBased(boolean v)
          Sets the subtype of time-based filtering used by the poller.
 void setPollInterval(long pollInterval)
          Set the poll interval.
 void setSendSingleFileEvent(boolean v)
          Instruct the poller whether to notify per-file events to the listeners or not (see class comment).
 void setStartBySleeping(boolean v)
          Instruct the poller whether to start by sweeping the controlled directories, or by going immediatly to sleep.
 void setTimeBased(boolean v)
          Sets the usage of time-based filtering (besides the normal filtering).
 void setVerbose(boolean v)
          Set the verbose level.
 void shutdown()
          Request the poller to shut down.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFAULT_AUTOMOVE_DIRECTORY

public static final java.lang.String DEFAULT_AUTOMOVE_DIRECTORY
The name of subdirectory automatically associated by the poller to any controlled directory for the autoMode mode, unless setAutoMoveDirectory() is explicitly called before starting the poller.

The current value is "received"

See Also:
Constant Field Values

pollManagersList

protected java.util.List pollManagersList
Constructor Detail

DirectoryPoller

public DirectoryPoller(java.io.File[] dirs,
                       java.io.FilenameFilter filter)
Create a poller over the given directories, using the given filter.

SubDirectories are automatically filtered.

Parameters:
dirs - an array of directories
filter - a filter for files to look up

DirectoryPoller

public DirectoryPoller(java.io.File[] dirs)
Create a poller over the given directories, which will match any file.

SubDirectories are automatically filtered.

Parameters:
dirs - an array of directories

DirectoryPoller

public DirectoryPoller(java.io.File directory,
                       java.io.FilenameFilter filter)
Create a poller over the given directory, using the given filter.

SubDirectories are automatically filtered.

Parameters:
filter - a filter for files to look up

DirectoryPoller

public DirectoryPoller(java.io.File directory)
Create a poller over the given directory, which will match any file.

SubDirectories are automatically filtered.


DirectoryPoller

public DirectoryPoller(java.io.FilenameFilter filter)
Create a poller initially not bound to any directory, which uses the given filter.

SubDirectories are automatically filtered.

Before starting the poller, a single call to setDirectories(java.io.File[]) must be done to bind the poller to a specific directory.

Parameters:
filter - a filter for files to look up

DirectoryPoller

public DirectoryPoller()
Create a poller initially not bound to any directory, which will match any file.

SubDirectories are automatically filtered.

Before starting the poller, a single call to setDirectories(java.io.File[]) must be done to bind the poller to a specific directory.


DirectoryPoller

public DirectoryPoller(java.io.File[] dirs,
                       java.io.FilenameFilter filter,
                       boolean timeBased)
Create a poller over the given directories, using the given filter and time-based filtering as well (see class comment).

SubDirectories are automatically filtered.

Parameters:
dirs - an array of directories
filter - a filter for files to look up
timeBased - if true, the poller uses time-based lookup

DirectoryPoller

public DirectoryPoller(java.io.File directory,
                       java.io.FilenameFilter filter,
                       boolean timeBased)
Create a poller over the given directory, using the given filter and time-based filtering as well (see class comment).

SubDirectories are automatically filtered.

Parameters:
filter - a filter for files to look up

DirectoryPoller

public DirectoryPoller(java.io.FilenameFilter filter,
                       boolean timeBased)
Create a poller initially not bound to any directory, which uses the given filter and time-based filtering as well (see class comment).

SubDirectories are automatically filtered.

Before starting the poller, a single call to setDirectories(java.io.File[]) must be done to bind the poller to a specific directory.

Parameters:
filter - a filter for files to look up
Method Detail

addDirectory

public void addDirectory(java.io.File dir)
Add one directory to the controlled set. It can be called only if the poller thread hasn't started yet. * @param dir the directory to add

Throws:
java.lang.IllegalStateException - if the poller has already started.
java.lang.IllegalArgumentException - if String does not contain a directory path

removeDirectory

public void removeDirectory(java.io.File dir)
Remove one directory from the controlled set. It can be called only if the poller thread hasn't started yet.

Parameters:
dir - the directory to remove
Throws:
java.lang.IllegalStateException - if the poller has already started.
java.lang.IllegalArgumentException - if the directory is not among the controlled ones

setDirectories

public void setDirectories(java.io.File[] dirs)
Set the directories controlled by the poller. It can be called only if the poller thread hasn't started yet.

Parameters:
dirs - the directories to be controlled by the poller
Throws:
java.lang.IllegalStateException - if the poller has already started.
java.lang.IllegalArgumentException - if any of the File objects is not a directory

getDirectories

public java.io.File[] getDirectories()
Return the directories controlled by the poller.

Returns:
the directories controlled by the poller

setAutoMove

public void setAutoMove(boolean v)
Instruct the poller to automatically move the file to the directory associated to each directory under control, which can be set/retrieved by setAutoMoveDirectory()/getAutoMoveDirectory() (see also class description).

Parameters:
v - if true, the poller will automatically move selected files in the "received" directory associated to each directory under control

getAutoMove

public boolean getAutoMove()
Verify the autoMove mode (see setAutoMove() and class description).

Returns:
true if autoMove mode is active

getAutoMoveDirectory

public java.io.File getAutoMoveDirectory(java.io.File directory)
                                  throws java.lang.IllegalArgumentException
Returns the directory associated to the given controlled directory, where files polled are automatically moved if the autoMove mode is active (see setAutoMove() and class description).

If no directory is associated by setAutoMoveDirectory(), the subdirectory DEFAULT_AUTOMOVE_DIRECTORY is associated automatically.

Parameters:
directory - the directory for which the associated "automove" directory is requested
Throws:
java.lang.IllegalArgumentException - if directory is not under control of the poller

setAutoMoveDirectory

public void setAutoMoveDirectory(java.io.File directory,
                                 java.io.File autoMoveDirectory)
                          throws java.lang.IllegalArgumentException,
                                 java.lang.IllegalStateException
Associate a directory to one of the controlled directories, for the autoMove mode (see class description).

This method can be called only if the poller has not started yet.

Parameters:
directory - the controlled directory
autoMoveDirectory - the directory associated to the controlled directory
Throws:
java.lang.IllegalArgumentException - if directory is not a controlled directory
java.lang.IllegalStateException

checkIfManaged

protected void checkIfManaged(java.io.File directory)

setVerbose

public void setVerbose(boolean v)
Set the verbose level. Verbosity is mainly for debugging/tracing purposes, since the poller delivers events to any listener, which can therefore perform the tracing.

Parameters:
v - if true, the poller logs to system out.

isVerbose

public boolean isVerbose()
Return the verbose level. See setVerbose(boolean).

Returns:
the verbose level

setTimeBased

public void setTimeBased(boolean v)
Sets the usage of time-based filtering (besides the normal filtering). It can be called only if the poller thread hasn't started yet.

Parameters:
v - if true the poller will use time-based filtering
Throws:
java.lang.IllegalStateException - if the poller has already started.

isTimeBased

public boolean isTimeBased()
Return true if the poller is using time-based filtering (see class comment).

Returns:
true if the poller is using time-based filtering (see class comment)

setBaseTime

public void setBaseTime(java.io.File directory,
                        long time)
Reset the base time for the given directory.

It's irrelevant if time-based filtering is not enabled (see class comment).

Parameters:
time - the new base time
Throws:
java.lang.IllegalArgumentException - if the given directory is not under control of the poller

setBaseTime

public void setBaseTime(long time)
Reset the base time for the all the directories under control of the poller.

It's irrelevant if time-based filtering is not enabled (see class comment).

Parameters:
time - the new base time

getBaseTime

public long getBaseTime(java.io.File directory)
Return the current base time for the given directory.

The returned value is unpredictable if time-based filtering is not enabled (see class comment).

Returns:
the current base time, if time-based filtering is enabled
Throws:
java.lang.IllegalArgumentException - if the given directory is not under control of the poller

isPollingTimeBased

public boolean isPollingTimeBased()
Return true if the poller is time based, and uses last-polling time as a basis for the lookup (see class comment)


setPollingTimeBased

public void setPollingTimeBased(boolean v)
Sets the subtype of time-based filtering used by the poller.

For the call to have any meaning, the poller must be in time-based mode, that is, setTimeBased() must have been called with true as parameter (se class comment): if the parameter is true, the poller will select only files older than the last polling time (besides applying any user-defined filter); if the parameter is false, the poller will select only files whose last modification time is higher than the higher last modification time found in the last polling cycle.

Parameters:
v - determines the time-based filtering subtype

setSendSingleFileEvent

public void setSendSingleFileEvent(boolean v)
Instruct the poller whether to notify per-file events to the listeners or not (see class comment).

Parameters:
v - if true, the poller will notify each file to the listeners

isSendSingleFileEvent

public boolean isSendSingleFileEvent()
Return true if the poller is currently instructed to send per-file events to the listeners (see class comment).

Returns:
true if the poller is currently instructed to send per-file events to the listeners

getPollInterval

public long getPollInterval()
Return the current poll interval. See class comments for notes.

Returns:
the current poll interval

setPollInterval

public void setPollInterval(long pollInterval)
Set the poll interval. The poller sleeps for pollInterval milliseconds and then performs a lookup in the bound directories. See class comments for notes.


setStartBySleeping

public void setStartBySleeping(boolean v)
Instruct the poller whether to start by sweeping the controlled directories, or by going immediatly to sleep.

Parameters:
v - if true the poller starts by going immediatly to sleep

isStartBySleeping

public boolean isStartBySleeping()
Return if the poller starts by sweeping the controlled directories, or going immediatly to sleep.

Returns:
if the poller starts by sweeping the controlled directories, or going immediatly to sleep.

addPollManager

public void addPollManager(PollManager pm)
Adds on PollManager to the poller, which will be notified on polling events.

You may add many poll managers, but there is no support for inter-poll manager coordination, so if a PollManager deletes/moves a polled file, the others will still receive the associated event, but may not be able to perform proper processing.


shutdown

public void shutdown()
Request the poller to shut down.

If a notification is in course, the notification is completed before shutting down. Therefore, the event handler may want to check whether a shutdown has been requested before reacting to an event.


isShuttingDown

public boolean isShuttingDown()
Return true if a shutdown has been requested.

Returns:
true if a shutdown has been requested.

run

public void run()
Invoked when the thread is started. Performs a polling, notifying the registered listeners of related events. After each nofication, a check is done of whether a shutdown has been requested or not.


getFilter

public java.io.FilenameFilter getFilter()
Get the current filter


setFilter

public void setFilter(java.io.FilenameFilter filter)
Set the current filter. This can be invoked only when the poller is not running.

Parameters:
filter - the new filename filter to use.

getFilesSortComparator

public java.util.Comparator getFilesSortComparator()
Return the comparator to use to order file found events. Returns null if no comparator is set.

Returns:
the comparator to use to order file found events. Returns null if no comparator is set.

setFilesSortComparator

public void setFilesSortComparator(java.util.Comparator filesSortComparator)
Set the comparator to use to order file found events. Use null to set no comparator.

The comparator receives File objects and decides on their respective order.

Two pre-packaged comparators DirectoryPoller.ModificationTimeComparator and DirectoryPoller.FileSizeComparator are provided by this class.

Parameters:
filesSortComparator -

isBypassLockedFiles

public boolean isBypassLockedFiles()
Get the value of the BypassLockedFiles property. If the property is true, locked files will be ignored in automove mode.

Returns:
the value of the BypassLockedFiles property.

setBypassLockedFiles

public void setBypassLockedFiles(boolean supportSlowTransfer)
Set the value of the BypassLockedFiles property. If the property is true, locked files will be ignored in automove mode.


isSleeping

public boolean isSleeping()

isDebugExceptions

public boolean isDebugExceptions()
Turns on exception debugging. In case of exception signals are raised by the poller, they will be printed on standard output

Returns:
true if exception debugging is active, false otherwise

setDebugExceptions

public void setDebugExceptions(boolean debugExceptions)
Turns on exception debugging. In case of exception signals are raised by the poller, they will be printed on standard output

Parameters:
debugExceptions - true to enable exception printing, false otherwise


Copyright © 1999, 2000 Cristiano Sadun. This software is released under GPL.