Developing a file monitoring solution using SFMF4J is pretty simple. You simply need to:
When writing code against SFMF4J, you need only add a compile-time dependency on sfmf4j-api. You can (and should) defer the choice of implementation to the application architecture.
SFMF4J uses an event/listener paradigm for handling file system changes at the directory level. SFMF4J supports three types of events:
Sometimes you may only be interested in a subset of these events. For example, you may have a process which monitors a folder on an FTP server where users upload files, so you only really care about new files being added. In such a case, you are encouraged to extend DirectoryListenerAdapter and override its no-op implementations.
The act of monitoring the file system for changes and notifying interested parties is handled by a FileMonitorService. How you obtain a reference to a FileMonitorService is up to you, but for your convenience, you can create a pre-configured instance from a FileMonitorServiceFactory.
You will need to maintain a reference to your FileMonitorService in order to later unregister the listener when you no longer have any interest in file system events.
Deploying an application with file monitoring is easy.
Adding an SFMF4J implementation to your application is a simple matter of ensuring the implementation's jar is on the application's classpath (along with its dependencies). For OSGi environments, the implementation bundle needs to be installed in the OSGi container.
You should give some consideration to which implementation you choose, as each has its own advantages and drawbacks.
In Java 6+ environments, implementations can be loaded via Java SPI (a.k.a. java.util.ServiceLoader). Note that when using this method, you must invoke the lifecycle methods initialize and shutdown yourself.
import com.github.sworisbreathing.sfmf4j.api.FileMonitorServiceFactory; import java.util.Iterator; import java.util.ServiceLoader; static FileMonitorServiceFactory loadFileMonitorServiceFactory() { ServiceLoader<FileMonitorServiceFactory> serviceLoader = ServiceLoader.load( FileMonitorServiceFactory.class); Iterator<FileMonitorServiceFactory> implementationIterator = serviceLoader.iterator(); if(implementationIterator.hasNext()) { return implementationIterator.next(); } } static FileMonitorService newFileMonitorServiceInstance() { FileMonitorServiceFactory implementationFactory = loadFileMonitorServiceFactory(); FileMonitorService results = implementationFactory.createFileMonitorService(); return results; }
In OSGi environments, implementations are registered as services via Blueprint. Using this approach, you can easily rely on the OSGi container to manage the file monitor service's lifecycle for you, simply by declaring the init-method and destroy-method.
<reference id="implementationFactory" interface="com.github.sworisbreathing.sfmf4j.api.FileMonitorServiceFactory" /> <bean id="fileMonitorService" class="com.github.sworisbreathing.sfmf4j.api.FileMonitorService" factory-ref="implementationFactory" factory-method="createFileMonitorService" init-method="initialize" destroy-method="shutdown"/>
Once your application has a FileMonitorService instance, it must be made available to interested parties. If you are using a dependency injection framework, such as Spring, then this should be fairly easy. Otherwise, you may need to register the service via JNDI or make it available via some other mechanism. This largely depends on how the library code expects to obtain the FileMonitorService instance.
By default, each instance of FileMonitorService runs in its own dedicated thread, from which it detects file change events and invokes DirectoryListener callbacks. If this is a concern for you, you have a few options, such as: