Package org.tmatesoft.hg.internal

Source Code of org.tmatesoft.hg.internal.PathScope

/*
* Copyright (c) 2011-2012 TMate Software Ltd
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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 General Public License for more details.
*
* For information on how to redistribute this software under
* the terms of a license other than GNU General Public License
* contact TMate Software at support@hg4j.com
*/
package org.tmatesoft.hg.internal;

import static org.tmatesoft.hg.util.Path.CompareResult.*;

import java.util.ArrayList;

import org.tmatesoft.hg.util.FileIterator;
import org.tmatesoft.hg.util.Path;
import org.tmatesoft.hg.util.Path.CompareResult;

/**
* <ul>
* <li> Specify folder to get all files in there included, but no subdirs
* <li> Specify folder to get all files and files in subdirectories included
* <li> Specify exact set files (with option to accept or not paths leading to them)
* </ul>
* @author Artem Tikhomirov
* @author TMate Software Ltd.
*/
public class PathScope implements Path.Matcher {
  private final Path[] files;
  private final Path[] dirs;
  private final boolean includeNestedDirs;
  private final boolean includeParentDirs;
  private final boolean includeDirContent;
 
  /**
   * See {@link PathScope#PathScope(boolean, boolean, Path...)}
   */
  public PathScope(boolean recursiveDirs, Path... paths) {
    this(true, recursiveDirs, true, paths);
  }

  /**
   * With <code>matchParentDirs</code>, <code>recursiveDirs</code> and <code>matchDirContent</code> set to <code>false</code>,
   * this scope matches only exact paths specified.
   * <p>
   * With <code>matchParentDirs</code> set to <code>true</code>, parent directories for files and folders listed in
   * the <code>paths</code> would get accepted as well (handy for {@link FileIterator FileIterators}).
   * Note, if supplied path lists a file, parent directory for the file is not matched unless <code>matchParentDirs</code>
   * is <code>true</code>. To match file's immediate parent without matching all other parents up to the root, just add file parent
   * along with the file to <code>paths</code>.
   * <p>
   * With <code>recursiveDirs</code> set to <code>true</code>, subdirectories (with files) of directories listed in <code>paths</code> would
   * be matched as well. Similar to `a/b/**`
   * <p>
   * With <code>matchDirContent</code> set to <code>true</code>, files right under any directory listed in <code>path</code> would be matched.
   * Similar to `a/b/*`. Makes little sense to set to <code>false</code> when <code>recursiceDirs</code> is <code>true</code>, although may still
   * be useful in certain scenarios, e.g. PathScope(false, true, false, "a/") matches files under "a/b/*" and "a/b/c/*", but not files "a/*".
   *
   * @param matchParentDirs <code>true</code> to accept parent dirs of supplied paths
   * @param recursiveDirs <code>true</code> to include subdirectories and files of supplied paths
   * @param includeDirContent
   * @param paths files and folders to match
   */
  public PathScope(boolean matchParentDirs, boolean recursiveDirs, boolean matchDirContent, Path... paths) {
    if (paths == null) {
      throw new IllegalArgumentException();
    }
    includeParentDirs = matchParentDirs;
    includeNestedDirs = recursiveDirs;
    includeDirContent = matchDirContent;
    ArrayList<Path> f = new ArrayList<Path>(5);
    ArrayList<Path> d = new ArrayList<Path>(5);
    for (Path p : paths) {
      if (p.isDirectory()) {
        d.add(p);
      } else {
        f.add(p);
      }
    }
    files = f.toArray(new Path[f.size()]);
    dirs = d.toArray(new Path[d.size()]);
  }

  public boolean accept(Path path) {
    if (path.isDirectory()) {
      // either equals to or a parent of a directory we know about (i.e. configured dir is *nested* in supplied arg).
      // Also, accept arg if it happened to be nested into configured dir (i.e. one of them is *parent* for the arg),
      //       and recursiveDirs is true.
      for (Path d : dirs) {
        switch(d.compareWith(path)) {
        case Same : return true;
        case ImmediateChild :
        case Nested : return includeParentDirs; // path is parent to one of our locations
        case ImmediateParent :
        case Parent : return includeNestedDirs; // path is nested in one of our locations
        }
      }
      if (!includeParentDirs) {
        return false;
      }
      // If one of configured files is nested under the path, and we shall report parents, accept.
      // Note, I don't respect includeDirContent here as with file it's easy to add parent to paths explicitly, if needed.
      // (if includeDirContent == .f and includeParentDirs == .f, directory than owns a scope file won't get reported) 
      for (Path f : files) {
        CompareResult cr = f.compareWith(path);
        if (cr == Nested || cr == ImmediateChild) {
          return true;
        }
      }
    } else {
      for (Path f : files) {
        if (f.equals(path)) {
          return true;
        }
      }
      // if interested in nested/recursive dirs, shall check if supplied file is under any of our configured locations
      if (!includeNestedDirs && !includeDirContent) {
        return false;
      }
      for (Path d : dirs) {
        CompareResult cr = d.compareWith(path);
        if (includeNestedDirs && cr == Parent) {
          // file is nested in one of our locations
          return true;
        }
        if (includeDirContent && cr == ImmediateParent) {
          // file is right under one of our directories, and includeDirContents is .t
          return true;
        }
        // try another directory
      }
    }
    return false;
  }
}
TOP

Related Classes of org.tmatesoft.hg.internal.PathScope

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.