src/share/tools/MakeDeps/DirectoryTree.java

Sat, 01 Dec 2007 00:00:00 +0000

author
duke
date
Sat, 01 Dec 2007 00:00:00 +0000
changeset 435
a61af66fc99e
child 1907
c18cbe5936b8
permissions
-rw-r--r--

Initial load

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

mercurial