comparison src/share/tools/MakeDeps/DirectoryTree.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c18cbe5936b8
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 1999-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any 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 }