package com.bc.util.watch; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.Timer; import java.util.TimerTask; public class FileWatch { public FileWatch() { fileList = new ArrayList(); listeners = new ArrayList(); } synchronized public int getNumFiles() { return fileList.size(); } synchronized public void add(File file) { if (file != null) { if (!file.isFile()) { throw new IllegalArgumentException("The argument: " + file.getPath() + " is not a file"); } final int index = getFileIndex(file); if (index < 0) { FileTimeContainer container = new FileTimeContainer(); container.setFile(file); container.setLastModified(file.lastModified()); fileList.add(container); } } } synchronized public void remove(File file) { final int index = getFileIndex(file); if (index >= 0) { fileList.remove(index); } } synchronized public int getNumListeners() { return listeners.size(); } synchronized public void addListener(FileWatchListener listener) { if ((listener != null) && (!listeners.contains(listener))) { listeners.add(listener); } } synchronized public void removeListener(FileWatchListener listener) { listeners.remove(listener); } public void start(long rate) { timer = new Timer(); timer.scheduleAtFixedRate(new FileWatchTask(), 0, rate); } public void stop() { if (timer != null) { timer.cancel(); timer = null; } } /////////////////////////////////////////////////////////////////////////// /////// END OF PUBLIC /////////////////////////////////////////////////////////////////////////// private final ArrayList fileList; private final ArrayList listeners; private Timer timer; protected void checkForModifiedFiles() { File[] changedFiles = getChangedFiles(); if (changedFiles.length > 0) { for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { FileWatchListener fileWatchListener = (FileWatchListener) iterator.next(); fileWatchListener.filesChanged(changedFiles); } } } protected File[] getChangedFiles() { ArrayList changedFiles = new ArrayList(); for (Iterator iterator = fileList.iterator(); iterator.hasNext();) { final FileTimeContainer container = (FileTimeContainer) iterator.next(); final File file = container.getFile(); final long lastModified = file.lastModified(); if (container.getLastModified() != lastModified) { container.setLastModified(lastModified); changedFiles.add(file); } } File[] fileArray = new File[changedFiles.size()]; return (File[]) changedFiles.toArray(fileArray); } private int getFileIndex(File file) { final FileTimeContainer container = new FileTimeContainer(); container.setFile(file); return fileList.indexOf(container); } private class FileTimeContainer { private long lastModified; private File file; public File getFile() { return file; } public void setFile(File file) { this.file = file; } public long getLastModified() { return lastModified; } public void setLastModified(long lastModified) { this.lastModified = lastModified; } /** * @noinspection InstanceofInterfaces */ public boolean equals(Object obj) { if (obj instanceof FileTimeContainer) { FileTimeContainer other = (FileTimeContainer) obj; return other.getFile().equals(file); } return false; } } private class FileWatchTask extends TimerTask { /** * The action to be performed by this timer task. */ public void run() { checkForModifiedFiles(); } } }