Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.softwaremagico.tm.file.watcher;
import com.softwaremagico.tm.log.MachineLog;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.ClosedWatchServiceException;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
/*-
* #%L
* Think Machine (Rules)
* %%
* Copyright (C) 2017 - 2019 Softwaremagico
* %%
* This software is designed by Jorge Hortelano Otero. Jorge Hortelano Otero
* Valencia (Spain).
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; If not, see .
* #L%
*/
public class FileWatcher {
private WatchQueueReader fileWatcher = null;
private String directoryToWatch = null;
private Set fileModifiedListeners;
private Set fileAddedListeners;
private Set fileRemovedListeners;
private Thread thread;
private Path pathToWatch = null;
private WatchService watcher = null;
public interface FileModifiedListener {
void changeDetected(Path pathToFile);
}
public interface FileAddedListener {
void fileCreated(Path pathToFile);
}
public interface FileRemovedListener {
void fileDeleted(Path pathToFile);
}
/**
* Check some files in a specific path
*
* @param directoryToWatch directory where the files are stored.
* @param filesNames the files to check
* @throws IOException
*/
public FileWatcher(String directoryToWatch, Set filesNames) throws IOException {
if (directoryToWatch != null) {
setDirectoryToWatch(directoryToWatch);
} else {
setDirectoryToWatch(FileReader.class.getClassLoader().getResource(".").toString());
}
if (filesNames == null) {
filesNames = new HashSet<>();
}
fileModifiedListeners = new HashSet<>();
fileAddedListeners = new HashSet<>();
fileRemovedListeners = new HashSet<>();
// Remove unexisting files.
for (final String fileName : new ArrayList<>(filesNames)) {
final File file = new File(directoryToWatch + File.pathSeparator + fileName);
if (!file.exists()) {
filesNames.remove(fileName);
}
}
if (!filesNames.isEmpty()) {
startWatcher(filesNames);
}
}
/**
* Check some files in the resource directory.
*
* @param filesNames
* @throws IOException
*/
public FileWatcher(Set filesNames) throws IOException {
this(null, filesNames);
}
/**
* Only check for a directory. Watch if any file is added, updated or deleted.
*
* @param directoryToWatch
* @throws IOException
*/
public FileWatcher(String directoryToWatch) throws IOException {
this(directoryToWatch, null);
}
public void addFileModifiedListener(FileModifiedListener listener) {
fileModifiedListeners.add(listener);
}
public void addFileAddedListener(FileAddedListener listener) {
fileAddedListeners.add(listener);
}
public void addFileRemovedListener(FileRemovedListener listener) {
fileRemovedListeners.add(listener);
}
private Path getDirectoryToWatch() {
if (pathToWatch == null) {
pathToWatch = Paths.get(directoryToWatch);
}
return pathToWatch;
}
private WatchService getWatchService() throws IOException {
if (watcher == null) {
if (getDirectoryToWatch() == null) {
throw new UnsupportedOperationException("Directory not found");
}
watcher = getDirectoryToWatch().getFileSystem().newWatchService();
}
return watcher;
}
private void startWatcher(final Set filesNames) {
try {
fileWatcher = new WatchQueueReader(getWatchService(), getDirectoryToWatch());
fileWatcher.setFilesNames(filesNames);
stopThread();
thread = new Thread(fileWatcher, "FileWatcher");
thread.start();
pathToWatch.register(getWatchService(), StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_DELETE);
// Ensure to close the watcher.
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
MachineLog.debug(this.getClass().getName(),
"Closing filewatcher for directory '{}' and files '{}'.", directoryToWatch, filesNames);
if (watcher != null) {
watcher.close();
}
} catch (Exception e) {
MachineLog.errorMessage(this.getClass().getName(), e);
}
}
});
} catch (NoSuchFileException e) {
MachineLog.warning(this.getClass().getName(), "Folder '{}' not found!", getDirectoryToWatch());
} catch (IOException e) {
MachineLog.errorMessage(this.getClass().getName(), e);
}
}
private class WatchQueueReader implements Runnable {
private WatchService watcher;
private Path pathToWatch;
private Set filesNames;
WatchQueueReader(WatchService watcher, Path pathToWatch) {
this.watcher = watcher;
this.pathToWatch = pathToWatch;
}
@Override
public void run() {
try {
// Get the first event before looping
WatchKey key = watcher.take();
while (key != null) {
// We have a polled event, now we traverse it and receive
// all the states from it
for (final WatchEvent> event : key.pollEvents()) {
// Event on a directory or a set of files.
if (filesNames == null || (filesNames.contains(event.context().toString()))) {
if (event.kind().equals(StandardWatchEventKinds.ENTRY_MODIFY)) {
for (final FileModifiedListener fileModifiedListener : new HashSet<>(fileModifiedListeners)) {
fileModifiedListener.changeDetected(combine(pathToWatch, (Path) event.context()));
}
} else if (event.kind().equals(StandardWatchEventKinds.ENTRY_CREATE)) {
for (final FileAddedListener fileCreationListener : new HashSet<>(fileAddedListeners)) {
fileCreationListener.fileCreated(combine(pathToWatch, (Path) event.context()));
}
} else if (event.kind().equals(StandardWatchEventKinds.ENTRY_DELETE)) {
for (final FileRemovedListener fileDeletionListener : new HashSet<>(fileRemovedListeners)) {
fileDeletionListener.fileDeleted(combine(pathToWatch, (Path) event.context()));
}
} else if (event.kind().equals(StandardWatchEventKinds.OVERFLOW)) {
MachineLog.severe(this.getClass().getName(), "File Watcher events vents may have been lost or discarded.");
}
}
}
key.reset();
key = watcher.take();
}
} catch (InterruptedException e) {
MachineLog.errorMessage(this.getClass().getName(), e);
Thread.currentThread().interrupt();
} catch (ClosedWatchServiceException e) {
// watcher closed. Do nothing.
return;
}
}
public void setFilesNames(Set filesNames) {
this.filesNames = filesNames;
}
}
protected static Path combine(Path path1, Path path2) {
return Paths.get(path1.toString(), path2.toString());
}
public void closeFileWatcher() {
pathToWatch = null;
if (watcher != null) {
try {
watcher.close();
stopThread();
} catch (IOException e) {
MachineLog.errorMessage(this.getClass().getName(), e);
}
}
watcher = null;
}
public void setDirectoryToWatch(String directoryToWatch) {
if (!directoryToWatch.equals(this.directoryToWatch)) {
this.directoryToWatch = directoryToWatch;
closeFileWatcher();
}
}
public void stopThread() {
if (thread != null) {
thread.interrupt();
}
}
}