comparison src/org/tmatesoft/hg/util/FileWalker.java @ 229:1ec6b327a6ac

Scope for status reworked: explicit files or a general matcher
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 31 May 2011 05:23:07 +0200
parents fffe4f882248
children ed6b74a58c66
comparison
equal deleted inserted replaced
228:fffe4f882248 229:1ec6b327a6ac
29 29
30 private final File startDir; 30 private final File startDir;
31 private final Path.Source pathHelper; 31 private final Path.Source pathHelper;
32 private final LinkedList<File> dirQueue; 32 private final LinkedList<File> dirQueue;
33 private final LinkedList<File> fileQueue; 33 private final LinkedList<File> fileQueue;
34 private final Path.Matcher scope;
34 private File nextFile; 35 private File nextFile;
35 private Path nextPath; 36 private Path nextPath;
36 37
37 public FileWalker(File dir, Path.Source pathFactory) { 38 public FileWalker(File dir, Path.Source pathFactory) {
39 this(dir, pathFactory, null);
40 }
41
42 /**
43 *
44 * @param dir
45 * @param pathFactory
46 * @param scopeMatcher - this matcher shall be capable to tell not only files of interest, but
47 * also whether directories shall be traversed or not (Paths it gets in {@link Path.Matcher#accept(Path)} may
48 * point to directories)
49 */
50 public FileWalker(File dir, Path.Source pathFactory, Path.Matcher scopeMatcher) {
38 startDir = dir; 51 startDir = dir;
39 pathHelper = pathFactory; 52 pathHelper = pathFactory;
40 dirQueue = new LinkedList<File>(); 53 dirQueue = new LinkedList<File>();
41 fileQueue = new LinkedList<File>(); 54 fileQueue = new LinkedList<File>();
55 scope = scopeMatcher;
42 reset(); 56 reset();
43 } 57 }
44 58
45 public void reset() { 59 public void reset() {
46 fileQueue.clear(); 60 fileQueue.clear();
69 public File file() { 83 public File file() {
70 return nextFile; 84 return nextFile;
71 } 85 }
72 86
73 public boolean inScope(Path file) { 87 public boolean inScope(Path file) {
74 return true; // no limits, all files are of interest 88 /* by default, no limits, all files are of interest */
89 return scope == null ? true : scope.accept(file);
75 } 90 }
76 91
77 // returns non-null 92 // returns non-null
78 private File[] listFiles(File f) { 93 private File[] listFiles(File f) {
79 // in case we need to solve os-related file issues (mac with some encodings?) 94 // in case we need to solve os-related file issues (mac with some encodings?)
89 return false; 104 return false;
90 } 105 }
91 while (!dirQueue.isEmpty()) { 106 while (!dirQueue.isEmpty()) {
92 File dir = dirQueue.removeFirst(); 107 File dir = dirQueue.removeFirst();
93 for (File f : listFiles(dir)) { 108 for (File f : listFiles(dir)) {
94 if (f.isDirectory()) { 109 final boolean isDir = f.isDirectory();
95 if (!".hg".equals(f.getName())) { 110 Path path = pathHelper.path(isDir ? ensureTrailingSlash(f.getPath()) : f.getPath());
111 if (!inScope(path)) {
112 continue;
113 }
114 if (isDir) {
115 if (!".hg/".equals(path.toString())) {
96 dirQueue.addLast(f); 116 dirQueue.addLast(f);
97 } 117 }
98 } else { 118 } else {
99 fileQueue.addLast(f); 119 fileQueue.addLast(f);
100 } 120 }
102 break; 122 break;
103 } 123 }
104 } 124 }
105 return !fileQueue.isEmpty(); 125 return !fileQueue.isEmpty();
106 } 126 }
127
128 private static String ensureTrailingSlash(String dirName) {
129 if (dirName.length() > 0) {
130 char last = dirName.charAt(dirName.length() - 1);
131 if (last == '/' || last == File.separatorChar) {
132 return dirName;
133 }
134 // if path already has platform-specific separator (which, BTW, it shall, according to File#getPath),
135 // add similar, otherwise use our default.
136 return dirName.indexOf(File.separatorChar) != -1 ? dirName.concat(File.separator) : dirName.concat("/");
137 }
138 return dirName;
139 }
107 } 140 }