Clover coverage report - Alipes Project - 0.1
Coverage timestamp: Sat Sep 10 2005 21:25:58 BST
file stats: LOC: 303   Methods: 17
NCLOC: 146   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
AbstractFileStateMonitor.java 2.8% 16.7% 47.1% 16.8%
coverage coverage
 1    /*
 2    * $Id: AbstractFileStateMonitor.java,v 1.1 2004/04/27 10:59:15 johndavidtaylor Exp $ Created on Apr 26, 2004 by jdt@roe.ac.uk The alipes project Copyright
 3    * (c) Astrigrid 2004. All rights reserved.
 4    *
 5    */
 6    package org.abraracourcix.alipes.monitors.file;
 7    import java.io.File;
 8    import java.util.Date;
 9    import java.util.HashMap;
 10    import java.util.Iterator;
 11    import java.util.Map;
 12    import java.util.Set;
 13    import org.abraracourcix.alipes.listeners.Listener;
 14    import org.abraracourcix.alipes.listeners.ListenerException;
 15    import org.abraracourcix.alipes.monitors.PollingMonitor;
 16    /**
 17    * Factors out everything we know about FileStateMonitors, leaving subclasses
 18    * to decide how to manage the files we want to monitor
 19    *
 20    * @author jdt
 21    */
 22    public abstract class AbstractFileStateMonitor extends PollingMonitor {
 23    /**
 24    * Commons logger
 25    */
 26    private static final org.apache.commons.logging.Log log =
 27    org.apache.commons.logging.LogFactory.getLog(
 28    AbstractFileStateMonitor.class);
 29    /**
 30    * Constructor - pass through to superclass
 31    *
 32    * @param listener see superclass
 33    * @param pollingFrequency see superclass
 34    */
 35  3 public AbstractFileStateMonitor(
 36    final Listener listener,
 37    final long pollingFrequency) {
 38  3 super(listener, pollingFrequency);
 39    }
 40    /**
 41    * Number of milliseconds in a second
 42    */
 43    private static final int MILLIS_PER_SEC = 1000;
 44    /**
 45    * Map of Files to Fileinfos
 46    */
 47    private Map fileInfos = new HashMap();
 48    /**
 49    * @author jdt Java Enum for the states a file could have
 50    */
 51    protected static final class FileState {
 52    /**
 53    * Constructor
 54    *
 55    * @param message some useful description
 56    */
 57  8 private FileState(final String message) {
 58  8 this.message = message;
 59    }
 60    /**
 61    * human readable description
 62    */
 63    private String message;
 64    /**
 65    * Enum value
 66    */
 67    public static final FileState FILE_EXISTS =
 68    new FileState("File exists");
 69    /**
 70    * Enum value
 71    */
 72    public static final FileState FILE_EXISTS_STALE =
 73    new FileState("File exists, but is old.");
 74    /**
 75    * Enum value
 76    */
 77    public static final FileState FILE_NO_EXIST =
 78    new FileState("File does not exist");
 79    /**
 80    * Enum value
 81    */
 82    public static final FileState UNKNOWN = new FileState("Je ne sais pas");
 83    /**
 84    * Usual toString
 85    *
 86    * @return description of filestate
 87    */
 88  0 public String toString() {
 89  0 return message;
 90    }
 91    /**
 92    * utility method - does the file exist?
 93    *
 94    * @return true if exists
 95    */
 96  0 public boolean doesExist() {
 97  0 return (this == FILE_EXISTS || this == FILE_EXISTS_STALE);
 98    }
 99    /**
 100    * utility method - is the file absent
 101    *
 102    * @return true if file is absent
 103    */
 104  0 public boolean doesNotExist() {
 105  0 return (this == FILE_NO_EXIST);
 106    }
 107    /**
 108    * utility method - is the file state?
 109    *
 110    * @return true if the file is old
 111    */
 112  0 public boolean isStale() {
 113  0 return this == FILE_EXISTS_STALE;
 114    }
 115    }
 116    /**
 117    * Simply a dataholder we can stick in a map containing info about a file
 118    *
 119    * @author jdt
 120    */
 121    protected static final class FileInfo {
 122    /**
 123    * file's timestamp
 124    */
 125    private Date dateStamp;
 126    /**
 127    * File's state
 128    */
 129    private FileState fileState;
 130    /**
 131    * Constructor
 132    *
 133    * @param fileState The State of the file
 134    * @param dateStamp The time when it was measured
 135    */
 136  307 public FileInfo(final FileState fileState, final Date dateStamp) {
 137  307 this.dateStamp = dateStamp;
 138  307 this.fileState = fileState;
 139    }
 140    /**
 141    * Getter
 142    *
 143    * @return Returns the dateStamp.
 144    */
 145  0 public Date getDateStamp() {
 146  0 return dateStamp;
 147    }
 148    /**
 149    * Getter
 150    *
 151    * @return Returns the fileState.
 152    */
 153  0 public FileState getFileState() {
 154  0 return fileState;
 155    }
 156    }
 157    /**
 158    * After this # of millis the file is considered stale
 159    */
 160    private int staleIntervalMillis = NEVER;
 161    /**
 162    * Hardcoded value to say that files should never be considered stale
 163    */
 164    public static final int NEVER = -1;
 165    /**
 166    * Check the status of this file and fire off any events as appropriate
 167    *
 168    * @param file file to check
 169    * @param info the file's previous info
 170    * @return the file's new info
 171    * @throws ListenerException - need to deal with this
 172    * @TODO deal with exception properly
 173    */
 174  0 private FileInfo checkFile(final File file, final FileInfo info)
 175    throws ListenerException {
 176  0 assert file != null;
 177  0 assert info != null;
 178  0 final FileState oldFileState = info.getFileState();
 179  0 final Date oldStamp = info.getDateStamp();
 180  0 assert oldFileState != null;
 181  0 assert oldStamp != null;
 182  0 final FileState newFileState =
 183  0 file.exists() ? FileState.FILE_EXISTS : FileState.FILE_NO_EXIST;
 184  0 final Date newStamp = new Date(file.lastModified());
 185    //@TODO what is this if file no exist?
 186  0 FileInfo newInfo = new FileInfo(newFileState, newStamp);
 187  0 log.debug("checkFile: file=" + file);
 188  0 log.debug("Old state=" + oldFileState + ", old datestamp=" + oldStamp);
 189  0 log.debug("New state=" + newFileState + ", new datestamp=" + newStamp);
 190  0 if (newFileState.doesExist()) {
 191  0 signalListener(FileEvent.EXISTS, file);
 192  0 } else if (newFileState.doesNotExist()) {
 193  0 signalListener(FileEvent.DOES_NOT_EXIST, file);
 194    }
 195  0 if (newFileState.doesExist() && oldFileState.doesNotExist()) {
 196  0 signalListener(FileEvent.CREATED, file);
 197    }
 198  0 if (newFileState.doesNotExist() && oldFileState.doesExist()) {
 199  0 signalListener(FileEvent.DELETED, file);
 200    }
 201  0 if (newFileState.doesExist() && oldFileState.doesExist()) {
 202  0 if (newStamp.after(oldStamp)) {
 203  0 signalListener(FileEvent.UPDATED, file);
 204    }
 205    }
 206  0 if (staleIntervalMillis != NEVER && newFileState.doesExist()) {
 207  0 final Date limit =
 208    new Date(new Date().getTime() - staleIntervalMillis);
 209  0 log.debug("Time limit for stale: " + limit);
 210  0 if (newStamp.before(limit)) {
 211  0 signalListener(FileEvent.IS_STALE, file);
 212  0 newInfo = new FileInfo(FileState.FILE_EXISTS_STALE, newStamp);
 213    }
 214    }
 215  0 if (newInfo.getFileState().isStale() && !oldFileState.isStale() && oldFileState!=FileState.UNKNOWN) {
 216  0 signalListener(FileEvent.GONE_STALE, file);
 217    }
 218  0 return newInfo;
 219    }
 220    /**
 221    * Stale interval in seconds
 222    *
 223    * @return Returns the staleIntervalMillis.
 224    */
 225  2 public final int getStaleInterval() {
 226  2 return staleIntervalMillis / MILLIS_PER_SEC;
 227    }
 228    /**
 229    * Stale interval in seconds - the time after which the file goes stale use
 230    * setStaleInterval(FileStateMonitor.NEVER) if the files are never
 231    * considered stale.
 232    *
 233    * @param staleInterval The staleIntervalMillis to set.
 234    */
 235  2 public final void setStaleInterval(final int staleInterval) {
 236  2 this.staleIntervalMillis = staleInterval * MILLIS_PER_SEC;
 237    }
 238    /**
 239    * Add a file the list we monitor and set its state to unknown
 240    *
 241    * @param file another file
 242    * @param state the initial state of the file added
 243    */
 244  307 public final void addFile(final File file, final FileState state) {
 245  307 fileInfos.put(file, new FileInfo(state, new Date()));
 246    }
 247    /**
 248    * Check the file list and respond acccordingly (non-Javadoc) @TODO deal
 249    * with exception properly
 250    *
 251    */
 252  0 protected final void checkTheFiles() {
 253  0 assert fileInfos != null;
 254  0 final Set files = fileInfos.keySet();
 255  0 final Iterator it = files.iterator();
 256  0 while (it.hasNext()) {
 257  0 final File file = (File) it.next();
 258  0 FileInfo info = (FileInfo) fileInfos.get(file);
 259  0 try {
 260  0 info = checkFile(file, info);
 261    } catch (ListenerException e) {
 262    // TODO Auto-generated catch block
 263  0 e.printStackTrace();
 264    }
 265  0 fileInfos.put(file, info);
 266    }
 267    }
 268    /**
 269    * Add files to the list we monitor and set their state to unknown
 270    *
 271    * @param files the files to add
 272    */
 273  0 public final void addFiles(final File[] files) {
 274  0 for (int i = 0; i < files.length; ++i) {
 275  0 fileInfos.put(
 276    files[i],
 277    new FileInfo(FileState.UNKNOWN, new Date()));
 278    }
 279    }
 280    /**
 281    * Adds a file with unknown state to the list of files to be monitored
 282    *
 283    * @param file the file
 284    */
 285  2 public final void addFile(final File file) {
 286  2 addFile(file, FileState.UNKNOWN);
 287    }
 288    /**
 289    * Get a collection of the files we're monitoring
 290    *
 291    * @return sais files
 292    */
 293  2 protected final Set getMonitoredFiles() {
 294  2 assert fileInfos != null;
 295  2 return fileInfos.keySet();
 296    }
 297    }
 298    /*
 299    * $Log: AbstractFileStateMonitor.java,v $
 300    * Revision 1.1 2004/04/27 10:59:15 johndavidtaylor
 301    * Refactored and added a directory monitor
 302    *
 303    */