Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 1&1 Internet AG, http://www.1and1.org
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License as published by
   * the Free Software Foundation; either version 2 of the License,
   * or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 package net.sf.beezle.sushi.fs.filter;
 
 
 import java.util.List;

Similar to java.world.FileFilter or Ant File/Directory sets. A filter is basically a list of paths to include or exclude. Predicates can be used to further restrict the collected nodes. Paths always use slashes (/) - even on Windows - because a) it simplifies writings constants and b) a filter can be applied to any file system.

Usage. Create a new instance, use the various selections methods (include, exclude, etc.), and pass the instance for dir.find(). Selection methods return this to allow expressions.

A path is a list of names, separated by Filter.SEPARATOR. Paths must *not* start with a separator, i.e they have to be relative. Paths remain relative until the filter is actually applied to a tree. Paths must not end with a separator either.

Names use the familar glob syntax. Filters do not know about extensions.

 
 public class Filter {
     public static final int DEPTH_INFINITE = .;
     
     public static final char SEPARATOR_CHAR = '/';
     public static final String SEPARATOR = "" + ;
 
     //--
 
    
    
List of compiled paths. CP = (HEAD, NULL | CP); HEAD = Pattern | String
 
     private final List<Object[]> includes;
     private final List<StringincludesRepr;
    
    
List of compiled paths.
 
     private final List<Object[]> excludes;
     private final List<StringexcludesRepr;
     
     private final List<Predicatepredicates;
     
     private boolean ignoreCase;
     private boolean followLinks;
     
     private int minDepth;
     private int maxDepth;
     
     public Filter() {
         this. = new ArrayList<Object[]>();
         this. = new ArrayList<String>();
         this. = new ArrayList<Object[]>();
         this. = new ArrayList<String>();
         this. = new ArrayList<Predicate>();
         this. = false;
         this. = false;
         this. = 1;
         this. = ;
     }
     
     public Filter(Filter orig) {
         this. = new ArrayList<Object[]>(orig.includes);
         this. = new ArrayList<String>(orig.includesRepr);
         this. = new ArrayList<Object[]>(orig.excludes);
         this. = new ArrayList<String>(orig.excludesRepr);
         this. = new ArrayList<Predicate>(orig.predicates); // TODO: not a deep clone ...
         this. = orig.ignoreCase;
         this. = orig.followLinks;
         this. = orig.minDepth;
         this. = orig.maxDepth;
     }
 
     //-- selections methods
     
    
Does *not* affect previous calles to include/exclude
 
     public Filter ignoreCase() {
          = true;
         return this;
    }
    public Filter followLinks() {
    	 = true;
    	return this;
    }
    
    public Filter minDepth(int minDepth) {
        this. = minDepth;
        return this;
    }
    
    public Filter maxDepth(int maxDepth) {
        this. = maxDepth;
        return this;
    }
    
    public Filter predicate(Predicate p) {
        .add(p);
        return this;
    }
    
    public Filter includeAll() {
        return includeName("*");
    }
    
    public Filter include(String... paths) {
        return include(Arrays.asList(paths));
    }
    
    public Filter include(List<Stringpaths) {
        for (String path : paths) {
            .add(compile(path));
            .add(path);
        }
        return this;
    }
    
    public Filter includeName(String... names) {
        for (String name : names) {
            include(Strings.join("**"name));
        }
        return this;
    }
    
    public Filter exclude(String... paths) {
        return exclude(Arrays.asList(paths));
    }
    public Filter exclude(List<Stringpaths) {
        for (String path : paths) {
            .add(compile(path));
            .add(path);
        }
        return this;
    }
    
    public Filter excludeName(String... names) {
        for (String name : names) {
            exclude(Strings.join("**"name));
        }
        return this;
    }
    public String[] getIncludes() {
        return Strings.toArray();
    }
    public String[] getExcludes() {
        return Strings.toArray();
    }
    
    public List<PredicategetPredicates() {
        return ;
    }
 
    //-- select helper methods
    
    private Object[] compile(String path) {
        List<Stringlst;
        
        lst = Strings.split(path);
        if (lst.size() == 0) {
            throw new IllegalArgumentException("empty path: " + path);
        }
        if (lst.get(0).equals("")) {
            throw new IllegalArgumentException("absolute path not allowed: " + path);
        }
        if (lst.get(lst.size() - 1).equals("")) {
            throw new IllegalArgumentException(
                "path must not end with separator: " + path);
        }
        return compileTail(lst, 0);
    }
    
    

Parameters:
lst array of patterns
    private Object[] compileTail(List<Stringlstint start) {
        Object head;
        Object[] tail;
        
        if (start == lst.size()) {
            return null;
        } else {
            head = Glob.compile(lst.get(start), );
            tail = compileTail(lststart + 1);
            if (head == .) {
                if (tail == null) {
                    throw new IllegalArgumentException("** must be followed by some content");
                }
                if (tail[0] == .) {
                    throw new IllegalArgumentException("**/** is not allowed");
                }
            }
        }
        return new Object[] { headtail };
    }
    
    public List<Nodecollect(Node rootthrows IOException {
        List<Noderesult;
        
        result = new ArrayList<Node>();
        collect(rootresult);
        return result;
    }
    
    public void collect(Node rootList<Noderesultthrows IOException {
        invoke(rootnew CollectAction(result));
    }

    
Main methods of this class.

Throws:
java.io.IOException as thrown by the specified FileTask
    public void invoke(Node rootAction resultthrows IOException {
        doInvoke(0, rootroot.isLink(), new ArrayList<Object[]>(), new ArrayList<Object[]>(), result);
    }
    
    private void doInvoke(int currentDepthNode parentboolean parentIsLinkList<Object[]> includesList<Object[]> excludesAction result)
    throws IOException {
        List<? extends Nodechildren;
        List<Object[]> remainingIncludes;
        List<Object[]> remainingExcludes;
        String name;
        boolean childIsLink;
        boolean in;
        boolean ex;
        
        if (currentDepth >= ) {
            return;
        }
        if (! && parentIsLink) {
            return;
        }       
        try {
            children = list(parentincludes);
        } catch (IOException e) {
            result.enterFailed(parentparentIsLinke);
            return;
        }
        if (children == null) {
            // ignore file
        } else {
            result.enter(parentparentIsLink);
            currentDepth++;
            for (Node child : children) {
                name = child.getName();
                childIsLink = child.isLink();
                remainingIncludes = new ArrayList<Object[]>();
                remainingExcludes = new ArrayList<Object[]>();
                in = doMatch(nameincludesremainingIncludes);
                ex = doMatch(nameexcludesremainingExcludes);
                if (in && !ex && currentDepth >=  && matchPredicates(childchildIsLink)) {
                    result.select(childchildIsLink);
                }
                if (remainingIncludes.size() > 0 && !excludesAll(remainingExcludes)) {
                    doInvoke(currentDepthchildchildIsLinkremainingIncludesremainingExcludesresult);
                }
            }
            result.leave(parentparentIsLink);
        }
    }
    // avoids node.list() call with there is exactly 1 include with a literal head
    private List<? extends Nodelist(Node nodeList<Object[]> includesthrows IOException {
    	Node child;
    	
    	if (includes.size() == 1 && includes.get(0)[0] instanceof String) {
            child = node.join((Stringincludes.get(0)[0]);
            if (child.exists()) {
                return Collections.singletonList(child);
            } else {
                return Collections.emptyList();
            }
    	} else {
        	return node.list();    	
        }
    }
    private boolean matchPredicates(Node nodeboolean isLinkthrows IOException {
        for (Predicate p : ) {
            if (!p.matches(nodeisLink)) {
                return false;
            }
        }
        return true;
    }
    
    private static boolean excludesAll(List<Object[]> excludes) {
        int i;
        int max;
        Object[] pair;
        Object[] tail;
        
        max = excludes.size();
        for (i = 0; i < maxi++) {
            pair = excludes.get(i);
            tail = (Object[]) pair[1];
            if (pair[0] == . && tail[0] == .) {
                return true;
            }
        }
        return false;
    }
    
    private static boolean doMatch(String nameList<Object[]> pathsList<Object[]> remainingPaths) {
        boolean found;
        int i;
        int max;
        Object[] path;
        Object head;
        Object[] tail;
        
        found = false;
        max = paths.size();
        for (i = 0; i < maxi++) {
            path = paths.get(i);
            if (path == null) {
                throw new IllegalStateException("unexpected empty path");
            }
            head = path[0];
            tail = (Object[]) path[1];
            if (head == .) {
                remainingPaths.add(path);
                head = tail[0];
                tail = (Object[]) tail[1];
            }
            if (matches(headname)) {
                if (tail != null) {
                    remainingPaths.add(tail);
                } else {
                    found = true;
                }
            }
        }
        return found;
    }
    private static boolean matches(Object stringOrPatternString name) {
    	if (stringOrPattern instanceof String) {
    		return name.equals(stringOrPattern);
    	} else {
    		return Glob.matches((PatternstringOrPatternname);    	
    	}
    }
    @Override
    public String toString() {
        return "includes=" +  + ", excludes=" + ;
    }
New to GrepCode? Check out our FAQ X