package net.sourceforge.javautil.common.io.impl;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.regex.Pattern;
import net.sourceforge.javautil.common.io.IVirtualArtifact;
import net.sourceforge.javautil.common.io.IVirtualDirectory;
import net.sourceforge.javautil.common.io.VirtualDirectoryVisitorContext;
import net.sourceforge.javautil.common.io.IVirtualFile;
import net.sourceforge.javautil.common.io.IVirtualPath;
import net.sourceforge.javautil.common.io.impl.ArtifactCollector.PatternFilter.ComparisonType;
import net.sourceforge.javautil.common.io.impl.ArtifactCollector.PatternFilter.Type;
import net.sourceforge.javautil.common.visitor.IVisitorSimple;
/**
* This is a special type of {@link VirtualDirectoryVisitor} that has the purpose
* of collecting a list of {@link IVirtualFile}'s or {@link IVirtualDirectory}'s and
* also allows for more complex filtering.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: ArtifactCollector.java 2356 2010-07-27 21:01:59Z ponderator $
*/
public class ArtifactCollector<A extends IVirtualArtifact> extends ArtifactCollectorFilterComposite implements IVisitorSimple<VirtualDirectoryVisitorContext> {
protected boolean includeFiles = true;
protected boolean includeDirectories = true;
protected Set<A> collected = new LinkedHashSet<A>();
public void visit(VirtualDirectoryVisitorContext ctx) {
if (!this.includeFiles && ctx.getVisited() instanceof IVirtualFile) return;
if (!this.includeDirectories && ctx.getVisited() instanceof IVirtualDirectory) {
return;
}
CollectResult result = this.collect(ctx);
if (result == CollectResult.EXCLUDED) ctx.skip();
else if (result == CollectResult.INCLUDED || isCollectionDefault()) collected.add((A)ctx.getVisited());
}
/**
* @return True if this collector will include {@link IVirtualFile}'s, otherwise false
*/
public boolean isIncludeFiles() { return includeFiles; }
public ArtifactCollector setIncludeFiles(boolean includeFiles) { this.includeFiles = includeFiles; return this; }
/**
* @return True if this collector will include {@link IVirtualDirectory}'s, otherwise false
*/
public boolean isIncludeDirectories() { return includeDirectories; }
public ArtifactCollector setIncludeDirectories(boolean includeDirectories) { this.includeDirectories = includeDirectories; return this; }
/**
* @return The artifacts that were collected when visiting
*/
public Set<A> getCollected() { return collected; }
/**
* This will cause files/directories that have names that match this pattern to be
* included in the collecting process.
*
* @param pattern The pattern to use to include files/directories
*/
public ArtifactCollector addInclusionPatternFilter (Pattern pattern) { this.add(new PatternFilter(pattern, Type.Inclusion, ComparisonType.Name)); return this; }
/**
* This will cause files/directories that have names that match this pattern to be
* excluded in the collecting process.
*
* @param pattern The pattern to use to exclude files/directories
*/
public ArtifactCollector addExclusionPatternFilter (Pattern pattern) { this.add(new PatternFilter(pattern, Type.Exclusion, ComparisonType.Name)); return this; }
/**
* This will cause files/directories that have paths that match this pattern to be
* excluded in the collecting process.
*
* @param pattern The pattern to use to exclude files/directories
*/
public ArtifactCollector addExclusionPathPatternFilter (Pattern pattern) { this.add(new PatternFilter(pattern, Type.Exclusion, ComparisonType.Path)); return this; }
/**
* This will cause files/directories that have paths that match this pattern to be
* included in the collecting process.
*
* @param pattern The pattern to use to include files/directories
*/
public ArtifactCollector addInclusionPathPatternFilter (Pattern pattern) { this.add(new PatternFilter(pattern, Type.Inclusion, ComparisonType.Path)); return this; }
@Override public ArtifactCollector add(IArtifactCollectorFilter filter) { super.add(filter); return this; }
/**
* A standard filter using a regular expression {@link Pattern}.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: ArtifactCollector.java 2356 2010-07-27 21:01:59Z ponderator $
*/
public static class PatternFilter implements IArtifactCollectorFilter {
public enum Type { Inclusion, Exclusion }
public enum ComparisonType { Name, Path }
protected final Pattern pattern;
protected final Type type;
protected final ComparisonType comparisonType;
public PatternFilter(Pattern pattern, Type type, ComparisonType comparisonType) {
this.pattern = pattern;
this.type = type;
this.comparisonType = comparisonType;
}
public CollectResult collect(VirtualDirectoryVisitorContext ctx) {
switch (this.comparisonType) {
case Name:
if (type == Type.Inclusion) {
return pattern.matcher(ctx.getVisited().getName()).matches() ? CollectResult.INCLUDED : CollectResult.DEFAULT;
} else {
return !pattern.matcher(ctx.getVisited().getName()).matches() ? CollectResult.EXCLUDED : CollectResult.DEFAULT;
}
case Path:
IVirtualPath path = ctx.getVisitable().getRelativePath(ctx.getVisited());
if (type == Type.Inclusion) {
return pattern.matcher(path.toString("/")).matches() ? CollectResult.INCLUDED : CollectResult.DEFAULT;
} else {
return !pattern.matcher(path.toString("/")).matches() ? CollectResult.INCLUDED : CollectResult.DEFAULT;
}
default:
}
return CollectResult.DEFAULT;
}
}
}