001    /* Copyright 2000, 2001, Compaq Computer Corporation */
002    
003    package javafe.filespace;
004    
005    
006    import java.io.*;
007    
008    import javafe.genericfile.*;
009    
010    
011    /**
012     * A FileTree is a Tree that mirrors the contents of a disk filesystem;
013     * the constructor takes in a directory and returns a tree representing
014     * the filesystem rooted at that directory.<p>
015     *
016     * FileTree works by scanning directories the first time clients
017     * ask for information about that part of the tree.  If the filesystem
018     * is changed afterwards, the changes will not be visible in the
019     * FileTree.<p>
020     *
021     * The data field of every (sub)node in a FileTree contains a
022     * non-null NormalGenericFile representing the file it mirrors on disk.<p>
023     */
024    
025    class FileTree extends PreloadedTree {
026    
027        /** The directory we are a snapshot of */
028        protected File dir;
029    
030    
031        /***************************************************
032         *                                                 *
033         * Creation:                                       *
034         *                                                 *
035         **************************************************/
036    
037        /** Create a root node: */
038        //@ requires dir != null;
039        public FileTree(File dir) {
040            super(new NormalGenericFile(dir));
041            this.dir = dir;
042        }
043    
044        /** Create a non-root node: */
045        //@ requires dir != null;
046        //@ requires parent != null && label != null;
047        protected FileTree(Tree parent, String label, File dir) {
048            super(parent, label, new NormalGenericFile(dir));
049            this.dir = dir;
050        }
051    
052    
053        /***************************************************
054         *                                                 *
055         * Loading the edges map:                          *
056         *                                                 *
057         **************************************************/
058    
059        /** Load the edges map for use.  */
060        protected void loadEdges() {
061            /*
062             * If our directory is null or not an actual existing directory
063             * on disk, we have no children:
064             */
065            if (dir == null || !dir.isDirectory())
066                return;
067    
068            /*
069             * Get all the filenames in our directory.  If the directory is
070             * unreadable (permission errors, etc.), we have no children:
071             */
072            String[] filenames = dir.list();
073            if (filenames == null)
074                return;
075    
076            /*
077             * Add all of them as either sub-FileTree's (if a directory) or
078             * LeafTree's (if not a directory):
079             */
080            for (int i=0; i<filenames.length; i++) {
081               if (filenames[i]==null)
082                    continue;
083    
084                File file = new File(dir, filenames[i]);
085    
086                Tree subtree;
087                if (file.isDirectory())
088                    subtree = new FileTree(this, filenames[i], file);
089                else
090                    subtree = new LeafTree(this, filenames[i],
091                                            new NormalGenericFile(file));
092    
093                edges.put(filenames[i], subtree);
094            }
095        }
096    
097    
098        /***************************************************
099         *                                                 *
100         * Debugging functions:                            *
101         *                                                 *
102         **************************************************/
103    
104        /** A simple test driver */
105        //@ requires \nonnullelements(args);
106        public static void main(String[] args) {
107            if (args.length>1) {
108                System.out.println("FileTree: usage [<directory>]");
109                return;
110            }
111            String dirName = ".";           // Default directory = .
112            if (args.length==1)
113                dirName = args[0];
114    
115            /*
116             * Create a new FileTree rooted at the given directory name then
117             * print it out.
118             */
119            Tree T = new FileTree(new File(dirName));
120            T.print("");
121        }
122    }