hotspot/src/share/tools/ProjectCreator/DirectoryTree.java
changeset 13909 9b94bf4dcc0c
parent 13908 6fa036b39eb9
parent 13907 52873e4bbeaa
child 13911 e59cfb5f223b
equal deleted inserted replaced
13908:6fa036b39eb9 13909:9b94bf4dcc0c
     1 /*
       
     2  * Copyright (c) 1999, 2011, 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     public void addSubdirToIgnore(String subdir) {
       
    51         subdirsToIgnore.add(subdir);
       
    52     }
       
    53 
       
    54     private class FileIterator implements Iterator {
       
    55         private Vector nodes = new Vector();
       
    56 
       
    57         public FileIterator(Node rootNode) {
       
    58             if(rootNode == null) {
       
    59                 return;
       
    60             }
       
    61             nodes.add(rootNode);
       
    62             prune();
       
    63         }
       
    64         public boolean hasNext() {
       
    65             return nodes.size() > 0;
       
    66         }
       
    67         public Object next() {
       
    68             Node last = (Node)nodes.remove(nodes.size() - 1);
       
    69             prune();
       
    70             return new File(last.getName());
       
    71         }
       
    72 
       
    73         public void remove() {
       
    74             throw new RuntimeException();
       
    75         }
       
    76 
       
    77         private void prune() {
       
    78             while (nodes.size() > 0) {
       
    79                 Node last = (Node)nodes.get(nodes.size() - 1);
       
    80 
       
    81                 if (last.isDirectory()) {
       
    82                     nodes.remove(nodes.size() - 1);
       
    83                     nodes.addAll(last.children);
       
    84                 } else {
       
    85                     // Is at file
       
    86                     return;
       
    87                 }
       
    88             }
       
    89         }
       
    90     }
       
    91 
       
    92     public Iterator getFileIterator() {
       
    93         return new FileIterator(rootNode);
       
    94     }
       
    95 
       
    96     /** Output "."'s to System.out as directories are read. Defaults
       
    97         to false. */
       
    98     public void setVerbose(boolean newValue) {
       
    99         verbose = newValue;
       
   100     }
       
   101 
       
   102     public boolean getVerbose() {
       
   103         return verbose;
       
   104     }
       
   105 
       
   106     public String getRootNodeName() {
       
   107         return rootNode.getName();
       
   108     }
       
   109 
       
   110     /** Takes an absolute path to the root directory of this
       
   111         DirectoryTree. Throws IllegalArgumentException if the given
       
   112         string represents a plain file or nonexistent directory. */
       
   113 
       
   114     public void readDirectory(String baseDirectory)
       
   115         throws IllegalArgumentException {
       
   116         File root = new File(Util.normalize(baseDirectory));
       
   117         if (!root.isDirectory()) {
       
   118             return;
       
   119         }
       
   120         try {
       
   121             root = root.getCanonicalFile();
       
   122         }
       
   123         catch (IOException e) {
       
   124             throw new RuntimeException(e.toString());
       
   125         }
       
   126         rootNode = new Node(root);
       
   127         readDirectory(rootNode, root);
       
   128     }
       
   129 
       
   130     /** Queries the DirectoryTree for a file or directory name. Takes
       
   131         only the name of the file or directory itself (i.e., no parent
       
   132         directory information should be in the passed name). Returns a
       
   133         List of DirectoryTreeNodes specifying the full paths of all of
       
   134         the files or directories of this name in the DirectoryTree.
       
   135         Returns null if the directory tree has not been read from disk
       
   136         yet or if the file was not found in the tree. */
       
   137     public List findFile(String name) {
       
   138         if (rootNode == null) {
       
   139             return null;
       
   140         }
       
   141 
       
   142         if (nameToNodeListTable == null) {
       
   143             nameToNodeListTable = new Hashtable();
       
   144             try {
       
   145                 buildNameToNodeListTable(rootNode);
       
   146             } catch (IOException e) {
       
   147                 e.printStackTrace();
       
   148                 return null;
       
   149             }
       
   150         }
       
   151 
       
   152         return (List) nameToNodeListTable.get(name);
       
   153     }
       
   154 
       
   155     private void buildNameToNodeListTable(Node curNode)
       
   156       throws IOException {
       
   157         String fullName = curNode.getName();
       
   158         String parent = curNode.getParent();
       
   159         String separator = System.getProperty("file.separator");
       
   160 
       
   161         if (parent != null) {
       
   162           if (!fullName.startsWith(parent)) {
       
   163             throw new RuntimeException(
       
   164                 "Internal error: parent of file name \"" + fullName +
       
   165                 "\" does not match file name \"" + parent + "\""
       
   166             );
       
   167           }
       
   168 
       
   169           int len = parent.length();
       
   170           if (!parent.endsWith(separator)) {
       
   171             len += separator.length();
       
   172           }
       
   173 
       
   174           String fileName = fullName.substring(len);
       
   175 
       
   176           if (fileName == null) {
       
   177             throw new RuntimeException(
       
   178                 "Internal error: file name was empty"
       
   179             );
       
   180           }
       
   181 
       
   182           List nodeList = (List) nameToNodeListTable.get(fileName);
       
   183           if (nodeList == null) {
       
   184             nodeList = new Vector();
       
   185             nameToNodeListTable.put(fileName, nodeList);
       
   186           }
       
   187 
       
   188           nodeList.add(curNode);
       
   189         } else {
       
   190           if (curNode != rootNode) {
       
   191             throw new RuntimeException(
       
   192                 "Internal error: parent of file + \"" + fullName + "\"" +
       
   193                 " was null"
       
   194             );
       
   195           }
       
   196         }
       
   197 
       
   198         if (curNode.isDirectory()) {
       
   199           Iterator iter = curNode.getChildren();
       
   200           if (iter != null) {
       
   201             while (iter.hasNext()) {
       
   202               buildNameToNodeListTable((Node) iter.next());
       
   203             }
       
   204           }
       
   205         }
       
   206     }
       
   207 
       
   208     /** Reads all of the files in the given directory and adds them as
       
   209         children of the directory tree node. Requires that the passed
       
   210         node represents a directory. */
       
   211 
       
   212     private void readDirectory(Node parentNode, File parentDir) {
       
   213         File[] children = parentDir.listFiles();
       
   214         if (children == null)
       
   215             return;
       
   216         if (verbose) {
       
   217             System.out.print(".");
       
   218             System.out.flush();
       
   219         }
       
   220         for (int i = 0; i < children.length; i++) {
       
   221             File child = children[i];
       
   222             children[i] = null;
       
   223             boolean isDir = child.isDirectory();
       
   224             boolean mustSkip = false;
       
   225             if (isDir) {
       
   226                 for (Iterator iter = subdirsToIgnore.iterator();
       
   227                      iter.hasNext(); ) {
       
   228                     if (child.getName().equals((String) iter.next())) {
       
   229                         mustSkip = true;
       
   230                         break;
       
   231                     }
       
   232                 }
       
   233             }
       
   234             if (!mustSkip) {
       
   235                 Node childNode = new Node(child);
       
   236                 parentNode.addChild(childNode);
       
   237                 if (isDir) {
       
   238                     readDirectory(childNode, child);
       
   239                 }
       
   240             }
       
   241         }
       
   242     }
       
   243 
       
   244     private class Node implements DirectoryTreeNode {
       
   245         private File file;
       
   246         private Vector children;
       
   247 
       
   248         /** file must be a canonical file */
       
   249         Node(File file) {
       
   250             this.file = file;
       
   251             children = new Vector();
       
   252         }
       
   253 
       
   254         public boolean isFile() {
       
   255             return file.isFile();
       
   256         }
       
   257 
       
   258         public boolean isDirectory() {
       
   259             return file.isDirectory();
       
   260         }
       
   261 
       
   262         public String getName() {
       
   263             return file.getPath();
       
   264         }
       
   265 
       
   266         public String getParent() {
       
   267             return file.getParent();
       
   268         }
       
   269 
       
   270         public void addChild(Node n) {
       
   271             children.add(n);
       
   272         }
       
   273 
       
   274         public Iterator getChildren() throws IllegalArgumentException {
       
   275             return children.iterator();
       
   276         }
       
   277 
       
   278         public int getNumChildren() throws IllegalArgumentException {
       
   279             return children.size();
       
   280         }
       
   281 
       
   282         public DirectoryTreeNode getChild(int i)
       
   283             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
       
   284             return (DirectoryTreeNode) children.get(i);
       
   285         }
       
   286     }
       
   287 }