View Javadoc

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 }