/*******************************************************************************
* Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at http://www.gnu.org/licenses/lgpl.txt
******************************************************************************/
package com.opendoorlogistics.core.utils.io;
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import java.io.File;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.List;
final public class WatchSingleDirectory implements Runnable {
private static boolean DEBUG_LOG_TO_CONSOLE = false;
private final File directory;
private final DirectoryChangedListener listener;
private final WatchService watchService;
private final WatchKey watchKey;
private final Thread thread;
public interface DirectoryChangedListener {
void onDirectoryChanged(File directory);
}
private WatchSingleDirectory(File directory, DirectoryChangedListener listener) {
this.directory = directory;
this.listener = listener;
this.thread = new Thread(this);
try {
watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get(directory.getAbsolutePath());
watchKey = path.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public static WatchSingleDirectory launch(File directory, DirectoryChangedListener listener) {
if(DEBUG_LOG_TO_CONSOLE){
System.out.println("" + Thread.currentThread().getId()+ " Launching");
}
WatchSingleDirectory watcher = new WatchSingleDirectory(directory, listener);
watcher.thread.start();
return watcher;
}
public File getDirectory(){
return directory;
}
public void run() {
if (watchService == null || watchKey == null) {
return;
}
if(DEBUG_LOG_TO_CONSOLE){
System.out.println("" + Thread.currentThread().getId()+ " Started run method");
}
try {
do {
WatchKey watchKey = watchService.take();
List<WatchEvent<?>> events = watchKey.pollEvents();
if (events != null && events.size() > 0) {
if(DEBUG_LOG_TO_CONSOLE){
System.out.println("" + Thread.currentThread().getId()+ " Received change event");
}
// fire listener
listener.onDirectoryChanged(directory);
}
} while (watchKey.reset());
} catch (Throwable e) {
// terminating
if(DEBUG_LOG_TO_CONSOLE){
System.out.println("" + Thread.currentThread().getId()+ " Exception: " + e.toString());
}
}
}
public void shutdown() {
try {
if(DEBUG_LOG_TO_CONSOLE){
System.out.println("" + Thread.currentThread().getId()+ " Calling shutdown");
}
if (watchService != null) {
watchService.close();
}
if(DEBUG_LOG_TO_CONSOLE){
System.out.println("" + Thread.currentThread().getId()+ " Waiting for thread to finish");
}
// wait until thread finished
thread.join();
if(DEBUG_LOG_TO_CONSOLE){
System.out.println("" + Thread.currentThread().getId()+ " Thread has finished");
}
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}