001/* ----------------------------------------------------------------------------
002   The Kiwi Toolkit - A Java Class Library
003   Copyright (C) 1998-2004 Mark A. Lindner
004
005   This library is free software; you can redistribute it and/or
006   modify it under the terms of the GNU General Public License as
007   published by the Free Software Foundation; either version 2 of the
008   License, or (at your option) any later version.
009
010   This library is distributed in the hope that it will be useful,
011   but WITHOUT ANY WARRANTY; without even the implied warranty of
012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013   General Public License for more details.
014
015   You should have received a copy of the GNU General Public License
016   along with this library; if not, write to the Free Software
017   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018   02111-1307, USA.
019 
020   The author may be contacted at: mark_a_lindner@yahoo.com
021   ----------------------------------------------------------------------------
022   $Log: FilesystemTraverser.java,v $
023   Revision 1.6  2004/05/05 21:36:35  markl
024   comment block updates
025
026   Revision 1.5  2003/01/19 09:37:12  markl
027   Javadoc & comment header updates.
028
029   Revision 1.4  2001/03/12 06:01:17  markl
030   Javadoc cleanup.
031
032   Revision 1.3  2001/03/12 01:58:42  markl
033   Source code cleanup.
034
035   Revision 1.2  1999/01/10 03:34:00  markl
036   added GPL header & RCS tag
037   ----------------------------------------------------------------------------
038*/
039
040package kiwi.io;
041
042import java.io.*;
043
044/** This class represents a filesystem traverser. A depth-first traversal of a
045  * directory tree rooted at a specified node is performed, with each file and
046  * directory encountered being passed to a <code>FileConsumer</code>.
047  *
048  * @see kiwi.io.FileConsumer
049  *
050  * @author Mark Lindner
051  */
052
053public class FilesystemTraverser
054  {
055  private File root;
056  private FilenameFilter filter;
057  private FileConsumer consumer = null;
058
059  /** Construct a new <code>FilesystemTraverser</code>.
060    *
061    * @param root The root of the directory tree to traverse.
062    * @param consumer The <code>FileConsumer</code> class to pass each
063    * encountered file and directory to.
064    * @param filter The <code>FilenameFilter</code> to filter files through
065    * before passing them to the consumer.
066    */
067
068  public FilesystemTraverser(File root, FilenameFilter filter,
069                             FileConsumer consumer)
070    {
071    this.root = root;
072    this.filter = filter;
073    this.consumer = consumer;
074    }
075
076  /** Construct a new <code>FilesystemTraverser</code>.
077    *
078    * @param root The root of the directory tree to traverse.
079    * @param consumer The <code>FileConsumer</code> class to pass each
080    * encountered file and directory to.
081    */
082
083  public FilesystemTraverser(File root, FileConsumer consumer)
084    {
085    this(root, null, consumer);
086    }
087
088  /** Traverse the filesystem. If the root node does not exist or is
089    * not a directory, this method returns immediately with a value of
090    * <code>false</code>.  Each file encountered during the traversal
091    * is passed to the <code>FileConsumer</code>'s
092    * <code>accept()</code> method; if that method returns
093    * <code>false</code>, the traversal is interrupted and this method
094    * returns <code>false</code>; otherwise the traversal continues
095    * through the end and the method returns <code>true</code>.
096    *
097    * @see kiwi.io.FileConsumer#accept
098    */
099
100  public boolean traverse()
101    {
102    if(!root.exists()) return(false);
103    if(!root.isDirectory()) return(true);
104    else return(_traverse(root));
105    }
106
107  /* one iteration of traversal */
108
109  private boolean _traverse(File dir)
110    {
111    String files[] = ((filter == null) ? dir.list() : dir.list(filter));
112
113    for(int i = 0; i < files.length; i++)
114      {
115      File f = new File(dir, files[i]);
116
117      if(f.isDirectory())
118        {
119        if(!f.canRead())
120          {
121          if(!consumer.accessError(f)) return(false);
122          }
123        if(!consumer.accept(f)) return(false);
124        else if(!_traverse(f)) return(false);
125        }
126      else
127        {
128        if(!consumer.accept(f)) return(false);
129        }
130      }
131
132    return(true);
133    }
134  
135  }
136
137/* end of source file */