package net.sourceforge.javautil.common.io;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import net.sourceforge.javautil.common.io.VirtualArtifactWatcher.VirtualArtifactChange;
import net.sourceforge.javautil.common.io.VirtualArtifactWatcher.VirtualArtifactWatchable;
import net.sourceforge.javautil.common.io.IVirtualArtifactWatcherListener.VirtualArtifactWatcherEvent.Type;
/**
* This will allow a {@link IVirtualDirectory} to be watched by a {@link VirtualArtifactWatcher}
* along with a few customizable options. It will also keep track of files that have been removed
* and new files.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class VirtualDirectoryWatched implements VirtualArtifactWatchable<IVirtualDirectory> {
protected final IVirtualDirectory watched;
protected final boolean recursive;
protected Set<IVirtualPath> paths;
public VirtualDirectoryWatched(IVirtualDirectory watched, boolean recursive) {
this.watched = watched;
this.recursive = recursive;
}
public IVirtualDirectory getArtifact() { return watched; }
public List<VirtualArtifactChange> getArtifactChangeList(long since) {
List<IVirtualArtifact> artifacts = recursive ? new ArrayList<IVirtualArtifact>(watched.getRecursiveArtifacts()) : new ArrayList<IVirtualArtifact>();
if (!recursive) for (Iterator<IVirtualArtifact> a = watched.getArtifacts(); a.hasNext(); ) artifacts.add(a.next());
if (paths == null) {
paths = new LinkedHashSet<IVirtualPath>();
for (IVirtualArtifact artifact : artifacts) paths.add(artifact.getPath());
}
long check = System.currentTimeMillis();
List<VirtualArtifactChange> changes = new ArrayList<VirtualArtifactChange>();
List<IVirtualPath> available = new ArrayList<IVirtualPath>(paths);
IVirtualArtifact artifact = null;
IVirtualPath path = null;
for (int i=0; i<artifacts.size(); i++) {
artifact = artifacts.get(i);
path = artifact.getPath();
if (available.contains(path)) {
if (artifact.getLastModified() <= since) { available.remove(path); continue; }
changes.add(new VirtualArtifactChange(watched, path, Type.MODIFIED, artifact.getLastModified()));
} else {
paths.add(path);
changes.add(new VirtualArtifactChange(watched, path, Type.NEW, artifact.getLastModified()));
}
available.remove(path);
}
for (int a=0; a<available.size(); a++) {
changes.add(new VirtualArtifactChange(watched, available.get(a), Type.REMOVED, check));
paths.remove(available.get(a));
}
return changes.size() == 0 ? null : changes;
}
}