comparison src/share/tools/ProjectCreator/DirectoryTree.java @ 1972:f95d63e2154a

6989984: Use standard include model for Hospot Summary: Replaced MakeDeps and the includeDB files with more standardized solutions. Reviewed-by: coleenp, kvn, kamg
author stefank
date Tue, 23 Nov 2010 13:22:55 -0800
parents src/share/tools/MakeDeps/DirectoryTree.java@c18cbe5936b8
children 15d6977f04b0
comparison
equal deleted inserted replaced
1971:e33f46fc48ed 1972:f95d63e2154a
1 /*
2 * Copyright (c) 1999, 2010, 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 nodes.add(rootNode);
59 prune();
60 }
61 public boolean hasNext() {
62 return nodes.size() > 0;
63 }
64 public Object next() {
65 Node last = (Node)nodes.remove(nodes.size() - 1);
66 prune();
67 return new File(last.getName());
68 }
69
70 public void remove() {
71 throw new RuntimeException();
72 }
73
74 private void prune() {
75 while (nodes.size() > 0) {
76 Node last = (Node)nodes.get(nodes.size() - 1);
77
78 if (last.isDirectory()) {
79 nodes.remove(nodes.size() - 1);
80 nodes.addAll(last.children);
81 } else {
82 // Is at file
83 return;
84 }
85 }
86 }
87 }
88
89 public Iterator getFileIterator() {
90 return new FileIterator(rootNode);
91 }
92
93 /** Output "."'s to System.out as directories are read. Defaults
94 to false. */
95 public void setVerbose(boolean newValue) {
96 verbose = newValue;
97 }
98
99 public boolean getVerbose() {
100 return verbose;
101 }
102
103 public String getRootNodeName() {
104 return rootNode.getName();
105 }
106
107 /** Takes an absolute path to the root directory of this
108 DirectoryTree. Throws IllegalArgumentException if the given
109 string represents a plain file or nonexistent directory. */
110
111 public void readDirectory(String baseDirectory)
112 throws IllegalArgumentException {
113 File root = new File(Util.normalize(baseDirectory));
114 if (!root.isDirectory()) {
115 throw new IllegalArgumentException("baseDirectory \"" +
116 baseDirectory +
117 "\" does not exist or " +
118 "is not a directory");
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 }