hotspot/src/share/tools/MakeDeps/DirectoryTree.java
changeset 7397 5b173b4ca846
parent 7396 518b01b064ff
child 7398 e4aa6d9bda09
child 7401 ebde7415b521
child 7405 e6fc8d3926f8
child 7426 dba53a0065f8
child 7427 d7b79a367474
child 7447 32c42d627f41
equal deleted inserted replaced
7396:518b01b064ff 7397:5b173b4ca846
     1 /*
       
     2  * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 /** Encapsulates a notion of a directory tree. Designed to allow fast
       
    26     querying of full paths for unique filenames in the hierarchy. */
       
    27 
       
    28 import java.io.*;
       
    29 import java.util.*;
       
    30 
       
    31 public class DirectoryTree {
       
    32 
       
    33     /** The root of the read directoryTree */
       
    34     private Node rootNode;
       
    35 
       
    36     /** Subdirs to ignore; Vector of Strings */
       
    37     private Vector subdirsToIgnore;
       
    38 
       
    39     /** This maps file names to Lists of nodes. */
       
    40     private Hashtable nameToNodeListTable;
       
    41 
       
    42     /** Output "."'s as directories are read. Defaults to false. */
       
    43     private boolean verbose;
       
    44 
       
    45     public DirectoryTree() {
       
    46         subdirsToIgnore = new Vector();
       
    47         verbose = false;
       
    48     }
       
    49 
       
    50     /** Takes an absolute path to the root directory of this
       
    51         DirectoryTree. Throws IllegalArgumentException if the given
       
    52         string represents a plain file or nonexistent directory. */
       
    53 
       
    54     public DirectoryTree(String baseDirectory) {
       
    55         this();
       
    56         readDirectory(baseDirectory);
       
    57     }
       
    58 
       
    59     public void addSubdirToIgnore(String subdir) {
       
    60         subdirsToIgnore.add(subdir);
       
    61     }
       
    62 
       
    63     /** Output "."'s to System.out as directories are read. Defaults
       
    64         to false. */
       
    65     public void setVerbose(boolean newValue) {
       
    66         verbose = newValue;
       
    67     }
       
    68 
       
    69     public boolean getVerbose() {
       
    70         return verbose;
       
    71     }
       
    72 
       
    73     public String getRootNodeName() {
       
    74         return rootNode.getName();
       
    75     }
       
    76 
       
    77     /** Takes an absolute path to the root directory of this
       
    78         DirectoryTree. Throws IllegalArgumentException if the given
       
    79         string represents a plain file or nonexistent directory. */
       
    80 
       
    81     public void readDirectory(String baseDirectory)
       
    82         throws IllegalArgumentException {
       
    83         File root = new File(baseDirectory);
       
    84         if (!root.isDirectory()) {
       
    85             throw new IllegalArgumentException("baseDirectory \"" +
       
    86                                                baseDirectory +
       
    87                                                "\" does not exist or " +
       
    88                                                "is not a directory");
       
    89         }
       
    90         try {
       
    91             root = root.getCanonicalFile();
       
    92         }
       
    93         catch (IOException e) {
       
    94             throw new RuntimeException(e.toString());
       
    95         }
       
    96         rootNode = new Node(root);
       
    97         readDirectory(rootNode, root);
       
    98     }
       
    99 
       
   100     /** Queries the DirectoryTree for a file or directory name. Takes
       
   101         only the name of the file or directory itself (i.e., no parent
       
   102         directory information should be in the passed name). Returns a
       
   103         List of DirectoryTreeNodes specifying the full paths of all of
       
   104         the files or directories of this name in the DirectoryTree.
       
   105         Returns null if the directory tree has not been read from disk
       
   106         yet or if the file was not found in the tree. */
       
   107     public List findFile(String name) {
       
   108         if (rootNode == null) {
       
   109             return null;
       
   110         }
       
   111 
       
   112         if (nameToNodeListTable == null) {
       
   113             nameToNodeListTable = new Hashtable();
       
   114             try {
       
   115                 buildNameToNodeListTable(rootNode);
       
   116             } catch (IOException e) {
       
   117                 e.printStackTrace();
       
   118                 return null;
       
   119             }
       
   120         }
       
   121 
       
   122         return (List) nameToNodeListTable.get(name);
       
   123     }
       
   124 
       
   125     private void buildNameToNodeListTable(Node curNode)
       
   126       throws IOException {
       
   127         String fullName = curNode.getName();
       
   128         String parent = curNode.getParent();
       
   129         String separator = System.getProperty("file.separator");
       
   130 
       
   131         if (parent != null) {
       
   132           if (!fullName.startsWith(parent)) {
       
   133             throw new RuntimeException(
       
   134                 "Internal error: parent of file name \"" + fullName +
       
   135                 "\" does not match file name \"" + parent + "\""
       
   136             );
       
   137           }
       
   138 
       
   139           int len = parent.length();
       
   140           if (!parent.endsWith(separator)) {
       
   141             len += separator.length();
       
   142           }
       
   143 
       
   144           String fileName = fullName.substring(len);
       
   145 
       
   146           if (fileName == null) {
       
   147             throw new RuntimeException(
       
   148                 "Internal error: file name was empty"
       
   149             );
       
   150           }
       
   151 
       
   152           List nodeList = (List) nameToNodeListTable.get(fileName);
       
   153           if (nodeList == null) {
       
   154             nodeList = new Vector();
       
   155             nameToNodeListTable.put(fileName, nodeList);
       
   156           }
       
   157 
       
   158           nodeList.add(curNode);
       
   159         } else {
       
   160           if (curNode != rootNode) {
       
   161             throw new RuntimeException(
       
   162                 "Internal error: parent of file + \"" + fullName + "\"" +
       
   163                 " was null"
       
   164             );
       
   165           }
       
   166         }
       
   167 
       
   168         if (curNode.isDirectory()) {
       
   169           Iterator iter = curNode.getChildren();
       
   170           if (iter != null) {
       
   171             while (iter.hasNext()) {
       
   172               buildNameToNodeListTable((Node) iter.next());
       
   173             }
       
   174           }
       
   175         }
       
   176     }
       
   177 
       
   178     /** Reads all of the files in the given directory and adds them as
       
   179         children of the directory tree node. Requires that the passed
       
   180         node represents a directory. */
       
   181 
       
   182     private void readDirectory(Node parentNode, File parentDir) {
       
   183         File[] children = parentDir.listFiles();
       
   184         if (children == null)
       
   185             return;
       
   186         if (verbose) {
       
   187             System.out.print(".");
       
   188             System.out.flush();
       
   189         }
       
   190         for (int i = 0; i < children.length; i++) {
       
   191             File child = children[i];
       
   192             children[i] = null;
       
   193             boolean isDir = child.isDirectory();
       
   194             boolean mustSkip = false;
       
   195             if (isDir) {
       
   196                 for (Iterator iter = subdirsToIgnore.iterator();
       
   197                      iter.hasNext(); ) {
       
   198                     if (child.getName().equals((String) iter.next())) {
       
   199                         mustSkip = true;
       
   200                         break;
       
   201                     }
       
   202                 }
       
   203             }
       
   204             if (!mustSkip) {
       
   205                 Node childNode = new Node(child);
       
   206                 parentNode.addChild(childNode);
       
   207                 if (isDir) {
       
   208                     readDirectory(childNode, child);
       
   209                 }
       
   210             }
       
   211         }
       
   212     }
       
   213 
       
   214     private class Node implements DirectoryTreeNode {
       
   215         private File file;
       
   216         private Vector children;
       
   217 
       
   218         /** file must be a canonical file */
       
   219         Node(File file) {
       
   220             this.file = file;
       
   221             children = new Vector();
       
   222         }
       
   223 
       
   224         public boolean isFile() {
       
   225             return file.isFile();
       
   226         }
       
   227 
       
   228         public boolean isDirectory() {
       
   229             return file.isDirectory();
       
   230         }
       
   231 
       
   232         public String getName() {
       
   233             return file.getPath();
       
   234         }
       
   235 
       
   236         public String getParent() {
       
   237             return file.getParent();
       
   238         }
       
   239 
       
   240         public void addChild(Node n) {
       
   241             children.add(n);
       
   242         }
       
   243 
       
   244         public Iterator getChildren() throws IllegalArgumentException {
       
   245             return children.iterator();
       
   246         }
       
   247 
       
   248         public int getNumChildren() throws IllegalArgumentException {
       
   249             return children.size();
       
   250         }
       
   251 
       
   252         public DirectoryTreeNode getChild(int i)
       
   253             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
       
   254             return (DirectoryTreeNode) children.get(i);
       
   255         }
       
   256     }
       
   257 }