1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.creadur.whisker.scan;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.LinkedList;
26 import java.util.Queue;
27 import java.util.Set;
28 import java.util.TreeSet;
29
30
31
32
33 public class FromFileSystem {
34
35
36
37
38 public FromFileSystem() {
39 super();
40 }
41
42
43
44
45
46
47
48 public Collection<Directory> withBase(final String base)
49 throws IOException {
50 return new Builder(base).build();
51 }
52
53
54
55
56 private final static class Builder {
57
58 private static final int DEFAULT_INITIAL_CAPACITY = 64;
59
60 private final File base;
61
62 private final Set<Directory> directories;
63
64 private final Queue<Work> workInProgress;
65
66 private final Collection<Work> workDone;
67
68
69
70
71
72
73 public Builder(final String base) {
74 this(base, DEFAULT_INITIAL_CAPACITY);
75 }
76
77
78
79
80
81
82 public Builder(final String base, final int initialCapacity) {
83 super();
84 this.base = new File(base);
85 directories = new TreeSet<Directory>();
86 workInProgress = new LinkedList<Work>();
87 workDone = new ArrayList<Work>(initialCapacity);
88 }
89
90
91
92
93
94
95 public Collection<Directory> build() throws IOException {
96 put(base).andWork().untilDone();
97 return directories;
98 }
99
100
101
102
103 private void untilDone() { }
104
105
106
107
108
109
110 private Builder put(final File file) {
111 return put(new Work(file));
112 }
113
114
115
116
117
118
119 private Builder put(final Work work) {
120 if (work != null) {
121 if (workDone.contains(work)) {
122 alreadyDone(work);
123 } else {
124 this.workInProgress.add(work);
125 }
126 }
127 return this;
128 }
129
130
131
132
133
134 private void alreadyDone(final Work work) {
135 System.out.println("Already done " + work);
136 }
137
138
139
140
141
142 private Builder andWork() {
143 while (!workInProgress.isEmpty()) {
144 workDone.add(workOn(workInProgress.poll()));
145 }
146 return this;
147 }
148
149
150
151
152
153
154 private Work workOn(final Work next) {
155 for (final String name: next.contents()) {
156 put(next.whenDirectory(name));
157 }
158 directories.add(next.build());
159 return next;
160 }
161
162
163
164
165 private static final class Work {
166
167 private static final String BASE_DIRECTORY = ".";
168
169 private final String name;
170
171 private final File file;
172
173
174
175
176
177 public Work(final File file) {
178 this(BASE_DIRECTORY, file);
179 }
180
181
182
183
184
185
186 public Work(final String name, final File file) {
187 if (!file.exists()) {
188 throw new IllegalArgumentException(
189 "Expected '" + file.getAbsolutePath() + "' to exist");
190 }
191 if (!file.isDirectory()) {
192 throw new IllegalArgumentException(
193 "Expected '" + file.getAbsolutePath() + "' to be a directory");
194 }
195 this.name = name;
196 this.file = file;
197 }
198
199
200
201
202
203 public String[] contents() {
204 final String[] contents = file.list();
205 if (contents == null) {
206 throw new IllegalArgumentException("Cannot list content of " + file);
207 }
208 return contents;
209 }
210
211
212
213
214
215 public Directory build() {
216 final Directory result = new Directory().setName(name);
217 for (final String name : contents()) {
218 if (isResource(name)) {
219 result.addResource(name);
220 }
221 }
222 return result;
223 }
224
225
226
227
228
229
230
231 private boolean isResource(final String name) {
232 return !isDirectory(name);
233 }
234
235
236
237
238
239
240
241 private boolean isDirectory(final String name) {
242 return file(name).isDirectory();
243 }
244
245
246
247
248
249
250
251 public Work whenDirectory(final String name) {
252 final File file = file(name);
253 final Work result;
254 if (file.isDirectory()) {
255 result = new Work(path(name), file);
256 } else {
257 result = null;
258 }
259 return result;
260 }
261
262
263
264
265
266
267 private String path(final String name) {
268 final String result;
269 if (isBaseDirectory()) {
270 result = name;
271 } else {
272 result = this.name + "/" + name;
273 }
274 return result;
275 }
276
277
278
279
280
281 private boolean isBaseDirectory() {
282 return BASE_DIRECTORY.equals(this.name);
283 }
284
285
286
287
288
289
290 private File file(String name) {
291 return new File(this.file, name);
292 }
293
294
295
296
297
298
299 @Override
300 public int hashCode() {
301 final int prime = 31;
302 int result = 1;
303 result = prime * result
304 + ((file == null) ? 0 : file.hashCode());
305 result = prime * result
306 + ((name == null) ? 0 : name.hashCode());
307 return result;
308 }
309
310
311
312
313
314
315
316 @Override
317 public boolean equals(final Object obj) {
318 if (this == obj) {
319 return true;
320 }
321 if (obj == null) {
322 return false;
323 }
324 if (getClass() != obj.getClass()) {
325 return false;
326 }
327 final Work other = (Work) obj;
328 if (file == null) {
329 if (other.file != null)
330 return false;
331 } else if (!file.equals(other.file))
332 return false;
333 if (name == null) {
334 if (other.name != null) {
335 return false;
336 }
337 } else if (!name.equals(other.name)) {
338 return false;
339 }
340 return true;
341 }
342
343
344
345
346
347
348 @Override
349 public String toString() {
350 return "Work [name=" + name + ", file=" + file + "]";
351 }
352 }
353 }
354 }