1 /*
2 * $Id: AbstractGHDirectory.java 2993 2011-11-24 19:51:48Z andrewinkler $
3 * ============================================================================
4 * Project gluehloch-homepage-core
5 * Copyright (c) 2004-2010 by Andre Winkler. All rights reserved.
6 * ============================================================================
7 * GNU LESSER GENERAL PUBLIC LICENSE
8 * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26 package de.awtools.homegen.directory.utils;
27
28 import java.io.File;
29 import java.util.Collections;
30 import java.util.Iterator;
31 import java.util.LinkedList;
32 import java.util.List;
33
34 import org.apache.commons.lang.Validate;
35
36 import de.awtools.homegen.directory.FileWorker;
37 import de.awtools.homegen.directory.GHDirectory;
38 import de.awtools.homegen.directory.GHEntry;
39 import de.awtools.homegen.directory.GHFile;
40
41 /**
42 * Utility Implementierung von {@link GHDirectory}.
43 *
44 * @version $LastChangedRevision: 2993 $ $LastChangedDate: 2011-11-24 20:51:48 +0100 (Thu, 24 Nov 2011) $
45 * @author by Andre Winkler, $LastChangedBy: andrewinkler $
46 */
47 public abstract class AbstractGHDirectory extends AbstractGHEntry implements
48 GHDirectory {
49
50 /**
51 * Konstruktor für das Wurzelverzeichnis.
52 *
53 * @param _rootDir Das Wurzelverzeichnis.
54 */
55 protected AbstractGHDirectory(final File _rootDir) {
56 this(null, _rootDir, null, 0);
57 }
58
59 /**
60 * Konstruktor.
61 *
62 * @param _parent Das übergeordnete Verzeichnis.
63 * @param _directory Das zugeordnete Verzeichnis.
64 * @param _name Name für das Verzeichnis.
65 * @param _level Der sogenannte 'level from root'.
66 */
67 protected AbstractGHDirectory(final GHDirectory _parent,
68 final File _directory, final String _name, final int _level) {
69
70 Validate.isTrue(_level >= 0, "_level lower then zero!");
71
72 directory = _directory;
73 level = _level;
74
75 if (level == 0) {
76 parent = null;
77 name = GHEntry.ROOT_DIR;
78 } else {
79 name = _name;
80 parent = _parent;
81 }
82 }
83
84 // -- name ----------------------------------------------------------------
85
86 /** Der Name für das Verzeichnis. */
87 private final String name;
88
89 /**
90 * Der Name für das Verzeichnis.
91 *
92 * @return Der Name für das Verzeichnis.
93 */
94 @Override
95 public final String getName() {
96 return name;
97 }
98
99 /**
100 * Liefert einen Pfad von der Wurzel bis in dieses Verzeichnis. Die
101 * einzelnen Verzeichnisse auf diesem Pfad sind '/' separiert.
102 *
103 * @return Eine '/' separierte Aufzählung von Verzeichnissen.
104 */
105 @Override
106 public final String getPath() {
107 StringBuilder sb = new StringBuilder();
108 if (isRootDir()) {
109 // Do nothing
110 //sb.append(getName());
111 } else {
112 sb.append(getParent().getPath());
113 sb.append(getName());
114 //sb.append('/');
115 }
116 return (sb.toString());
117 }
118
119 /**
120 * Liefert den {@link GHDirectory} Pfad von der Wurzel bis zu diesem
121 * Eintrag.
122 *
123 * @return Eine Liste mit dem {@link GHDirectory}-Pfad von der Wurzel bis
124 * zu diesem Eintrag.
125 */
126 @Override
127 public final List<GHDirectory> getDirectoryPath() {
128 LinkedList<GHDirectory> path = new LinkedList<GHDirectory>();
129 GHDirectory iterator = this;
130 path.addFirst(iterator);
131 while (!iterator.isRootDir()) {
132 iterator = iterator.getParent();
133 path.addFirst(iterator);
134 }
135
136 return path;
137 }
138
139 // -- directory -----------------------------------------------------------
140
141 /** Das zugeordnete Verzeichnis. */
142 private final File directory;
143
144 /**
145 * @see de.awtools.homegen.directory.GHDirectory#getFile()
146 */
147 @Override
148 public final File getFile() {
149 return directory;
150 }
151
152 // -- level ---------------------------------------------------------------
153
154 /**
155 * Der sogenannte Level vom Root. Im Root-Verzeichnis steht dieser Wert
156 * auf <code>0</code>.
157 */
158 private final int level;
159
160 /**
161 * @see de.awtools.homegen.directory.GHDirectory#getLevelFromRoot()
162 */
163 @Override
164 public final int getLevelFromRoot() {
165 return level;
166 }
167
168 /**
169 * @see de.awtools.homegen.directory.GHDirectory#isRootDir()
170 */
171 @Override
172 public final boolean isRootDir() {
173 return (level == 0);
174 }
175
176 // -- parent --------------------------------------------------------------
177
178 /** Verweis auf das übergeordnete Verzeichnis. */
179 private final GHDirectory parent;
180
181 /**
182 * Liefert das übergeordnete Verzeichnis.
183 *
184 * @return Ein übergeordnetes Verzeichnis oder <code>null</code>, wenn
185 * dies das Wurzelverzeichnis ist.
186 *
187 * @see GHDirectory#getParent()
188 */
189 @Override
190 public final GHDirectory getParent() {
191 return parent;
192 }
193
194 /**
195 * Liefer das Root-Verzeichnis für diese Verzeichnishierarchie.
196 *
197 * @return Das Wurzelverzeichnis.
198 */
199 @Override
200 public final GHDirectory getRoot() {
201 if (parent == null) {
202 return this;
203 } else {
204 return parent.getRoot();
205 }
206 }
207
208 // -- directories ---------------------------------------------------------
209
210 /** Die Unterverzeichnisse. */
211 private final List<GHDirectory> directories = new LinkedList<GHDirectory>();
212
213 /**
214 * Liefert die Unterverzeichnisse.
215 *
216 * @return Unterverzeichnisse.
217 *
218 * @see GHDirectory#getDirectories()
219 */
220 @Override
221 public final List<GHDirectory> getDirectories() {
222 return Collections.unmodifiableList(directories);
223 }
224
225 /**
226 * Liefert das Verzeichnis mit dem übergebenen Namen.
227 *
228 * @param criteria Der Name des gesuchten Verzeichnisses.
229 * @return Das gefundene Verzeichnis oder <code>null</code> wenn keins
230 * gefunden.
231 */
232 @Override
233 public final GHDirectory getDirectory(final String criteria) {
234 GHDirectory result = null;
235 for (GHDirectory dir : directories) {
236 if (dir.getName().equals(criteria)) {
237 result = dir;
238 break;
239 }
240 }
241 return result;
242 }
243
244 /**
245 * Fügt ein weiteres Unterverzeichnis hinzu.
246 *
247 * @param dir Ein Unterverzeichnis.
248 */
249 @Override
250 public final void addDirectory(final GHDirectory dir) {
251 if (directories.contains(dir)) {
252 throw new IllegalArgumentException("Directory '" + dir
253 + "' already added!");
254 }
255 directories.add(dir);
256 }
257
258 // -- snippetHtmlFiles ----------------------------------------------------
259
260 /** Die (XHTML) Snippets. */
261 private final List<GHFile> htmlFiles = new LinkedList<GHFile>();
262
263 /**
264 * @see de.awtools.homegen.directory.GHDirectory#getFiles()
265 */
266 @Override
267 public final List<GHFile> getFiles() {
268 return Collections.unmodifiableList(htmlFiles);
269 }
270
271 /**
272 * Fügt ein weiteres Snippet hinzu.
273 *
274 * @param file Ein File.
275 *
276 * @see de.awtools.homegen.directory.GHDirectory#addFile(de.awtools.homegen.directory.GHFile)
277 */
278 @Override
279 public final void addFile(final GHFile file) {
280 if (htmlFiles.contains(file)) {
281 throw new IllegalArgumentException("File '" + file
282 + "' already added!");
283 }
284 htmlFiles.add(file);
285 }
286
287 /**
288 * Iterator über alle Dateien in dem Verzeichnis und allen
289 * Unterverzeichnissen.
290 *
291 * @return Iterator über alle Dateien und Unterdateien.
292 */
293 @Override
294 public final Iterator<GHFile> iterator() {
295 return new FileIterator();
296 }
297
298 /**
299 * Liefert alle Dateien aus allen Verzeichnissen und Unterverzeichnissen.
300 *
301 * @return Alle Dateien aus allen Unterverzeichnissen.
302 */
303 @Override
304 public final List<GHFile> getAllFiles() {
305 LinkedList<GHFile> files = new LinkedList<GHFile>();
306 addFiles(this, files);
307 return files;
308 }
309
310 /**
311 * Sucht nach einer Datei mit dem angegebenen Namen. Es werden <b>keine</b>
312 * Unterverzeichnisse durchsucht!
313 *
314 * @param _name Der Name der gesuchten Datei.
315 * @return Die gefundene Datei.
316 */
317 @Override
318 public final GHFile getFile(final String _name) {
319 GHFile found = null;
320 for (GHFile file : htmlFiles) {
321 if (file.getName().equals(_name)) {
322 found = file;
323 }
324 }
325 return found;
326 }
327
328 /**
329 * Sucht nach einem {@link GHFile}, welches dem übergebenen File ähnlich
330 * ist in Dateiname <b>und</b> Pfad.
331 *
332 * @param findme Ein Muster der zu suchenden Datei.
333 * @return Die gefundene Datei oder <code>null</code> wenn nichts gefunden.
334 */
335 @Override
336 public final GHFile findFile(final GHFile findme) {
337 return (GHFileUtils.findFile(findme, this));
338 }
339
340 /**
341 * Sucht nach einem {@link GHFile}, welches dem übergebenen File ähnlich
342 * ist in Dateiname und Pfad. Die Datei-Extension wird bei dem Vergleich,
343 * von <code>findMe</code> ignoriert und der Parameter
344 * <code>fileExtension</code> für die Suche herangezogen.
345 *
346 * @param findme Ein Muster der zu suchenden Datei.
347 * @param fileExtension .
348 * @return Die gefundene Datei oder <code>null</code> wenn nichts gefunden.
349 */
350 @Override
351 public final GHFile findFile(final GHFile findme, final String fileExtension) {
352 return (GHFileUtils
353 .findFileIgnoreExtension(findme, this, fileExtension));
354 }
355
356 /**
357 * Startet die Bearbeitung aller Verzeichnisse und Unterverzeichnisse
358 * durch einen {@link FileWorker}.
359 *
360 * @param fileWorker Bearbeitet eine Datei.
361 */
362 @Override
363 public final void apply(final FileWorker fileWorker) {
364 for (GHFile file : htmlFiles) {
365 if (fileWorker.accept(file)) {
366 fileWorker.apply(file);
367 }
368 }
369 for (GHDirectory dir : directories) {
370 dir.apply(fileWorker);
371 }
372 }
373
374 /**
375 * Ermittelt alle Dateien aus allen Unterverzeichnissen.
376 *
377 * @param _dir Das zu untersuchende Verzeichnis.
378 * @param _files Die gefundenen Dateien.
379 */
380 private void addFiles(final GHDirectory _dir, final List<GHFile> _files) {
381 _files.addAll(_dir.getFiles());
382 for (GHDirectory dir : _dir.getDirectories()) {
383 addFiles(dir, _files);
384 }
385 }
386
387 @Override
388 public final String printGraph() {
389 StringBuilder spaces = new StringBuilder();
390 for (int tab = 0; tab < getLevelFromRoot(); tab++) {
391 spaces.append(" ");
392 }
393 spaces.append("+-");
394 spaces.append("Directory: ").append(getName()).append("\r\n")
395 .toString();
396 for (GHFile file : getFiles()) {
397 spaces.append(file.printGraph());
398 }
399 for (GHDirectory dir : getDirectories()) {
400 spaces.append(dir.printGraph());
401 }
402 return spaces.toString();
403 }
404
405 // ------------------------------------------------------------------------
406
407 @Override
408 public String toString() {
409 StringBuilder buf = new StringBuilder("[Level='");
410 buf.append(level).append("', Directory='");
411 buf.append(directory).append("']");
412 return (buf.toString());
413 }
414
415 @Override
416 public boolean equals(final Object _directory) {
417 boolean result = false;
418 if (_directory instanceof AbstractGHDirectory) {
419 AbstractGHDirectory aghd = (AbstractGHDirectory) _directory;
420 result = getPath().equals(aghd.getPath());
421 }
422 return result;
423 }
424
425 @Override
426 public int hashCode() {
427 return getPath().hashCode();
428 }
429
430 // ------------------------------------------------------------------------
431
432 private class FileIterator implements Iterator<GHFile> {
433
434 private final LinkedList<GHFile> files = new LinkedList<GHFile>();
435
436 private final Iterator<GHFile> iterator;
437
438 /**
439 * Ermittelt alle Dateien und Unterdateien.
440 */
441 public FileIterator() {
442 addFiles(AbstractGHDirectory.this, files);
443 iterator = files.iterator();
444 }
445
446 /* (non-Javadoc)
447 * @see java.util.Iterator#hasNext()
448 */
449 @Override
450 public boolean hasNext() {
451 return iterator.hasNext();
452 }
453
454 /* (non-Javadoc)
455 * @see java.util.Iterator#next()
456 */
457 @Override
458 public GHFile next() {
459 return iterator.next();
460 }
461
462 /* (non-Javadoc)
463 * @see java.util.Iterator#remove()
464 */
465 @Override
466 public void remove() {
467 throw new UnsupportedOperationException();
468 }
469
470 }
471
472 }