package de.axone.tools.watcher;
import java.io.File;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.axone.tools.Str;
/**
* Watches a set of Files for a change to any of them
*
* Note that this watcher can't handle file deletions directly.
* Deleted files are reported on any consequent call so you will
* need a new watcher for removed files.
*
* This is although true for added files of cause.
*
* @author flo
*/
public class FileListWatcher implements Watcher<List<File>> {
public static final Logger log =
LoggerFactory.getLogger( FileListWatcher.class );
private static final double TIMEOUT = 2000; //2 s
private List<File> files;
private double lastModifiedTime = -1;
private double lastCheckTime = -1;
private double timeout;
/**
* Create a FileSetWatcher for one file with the given
* timeout.
*
* @param files to watch
* @param timeout which has to pass until a new check is done
*/
public FileListWatcher( double timeout, List<File> files ){
this.timeout = timeout;
this.files = files;
}
/**
* Create a FileSetWatcher with a default timeout of 2s
*
* @param files
*/
public FileListWatcher( List<File> files ){
this( TIMEOUT, files );
}
@Override
public boolean haveChanged(){
boolean result = false;
double time = System.currentTimeMillis();
double div = time - lastCheckTime;
// See if timeout has passed to do a recheck
if( div >= timeout ){
lastCheckTime = time;
for( File file : files ){
if( ! file.exists() ){
log.warn( "File " + file.getAbsolutePath() + " does not exist" );
return true;
}
double modifiedTime = file.lastModified();
if( lastModifiedTime < modifiedTime ){
if( log.isDebugEnabled() ) log.debug(
String.format( "File %s has changed (%d<%d)",
file.getAbsolutePath(),
(int)(lastModifiedTime/1000),
(int)(modifiedTime/1000) )
);
lastModifiedTime = modifiedTime;
return true;
}
}
}
return result;
}
@Override
public List<File> getWatched(){
return files;
}
@Override
public String toString() {
return
"FileSetWatcher for: " + Str.join( (file,i) -> file.getAbsolutePath(), files )+
" timeout: " + timeout +
" Last modified: " + lastModifiedTime +
" Last check: + " + lastCheckTime;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ( ( files == null ) ? 0 : files.hashCode() );
return result;
}
@Override
public boolean equals( Object obj ) {
if( this == obj )
return true;
if( obj == null )
return false;
if( !( obj instanceof FileListWatcher ) )
return false;
FileListWatcher other = (FileListWatcher) obj;
if( files == null ) {
if( other.files != null )
return false;
} else if( !files.equals( other.files ) )
return false;
return true;
}
}