source: release-kits/lirk3/resources/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java@ 14982

Last change on this file since 14982 was 14982, checked in by oranfry, 16 years ago

initial import of LiRK3

File size: 6.0 KB
Line 
1/*
2 * Copyright 2000-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.apache.tools.ant.taskdefs.optional.depend;
18
19import java.io.File;
20import java.io.FileInputStream;
21import java.io.IOException;
22import java.util.Enumeration;
23import java.util.Stack;
24import java.util.Vector;
25
26/**
27 * An iterator which iterates through the contents of a java directory. The
28 * iterator should be created with the directory at the root of the Java
29 * namespace.
30 *
31 */
32public class DirectoryIterator implements ClassFileIterator {
33
34 /**
35 * This is a stack of current iterators supporting the depth first
36 * traversal of the directory tree.
37 */
38 private Stack enumStack;
39
40 /**
41 * The current directory iterator. As directories encounter lower level
42 * directories, the current iterator is pushed onto the iterator stack
43 * and a new iterator over the sub directory becomes the current
44 * directory. This implements a depth first traversal of the directory
45 * namespace.
46 */
47 private Enumeration currentEnum;
48
49 /**
50 * The length of the root directory. This is used to remove the root
51 * directory from full paths.
52 */
53 private int rootLength;
54
55 /**
56 * Creates a directory iterator. The directory iterator is created to
57 * scan the root directory. If the changeInto flag is given, then the
58 * entries returned will be relative to this directory and not the
59 * current directory.
60 *
61 * @param rootDirectory the root if the directory namespace which is to
62 * be iterated over
63 * @param changeInto if true then the returned entries will be relative
64 * to the rootDirectory and not the current directory.
65 * @exception IOException if there is a problem reading the directory
66 * information.
67 */
68 public DirectoryIterator(File rootDirectory, boolean changeInto)
69 throws IOException {
70 super();
71
72 enumStack = new Stack();
73
74 if (rootDirectory.isAbsolute() || changeInto) {
75 rootLength = rootDirectory.getPath().length() + 1;
76 } else {
77 rootLength = 0;
78 }
79
80 Vector filesInRoot = getDirectoryEntries(rootDirectory);
81
82 currentEnum = filesInRoot.elements();
83 }
84
85 /**
86 * Get a vector covering all the entries (files and subdirectories in a
87 * directory).
88 *
89 * @param directory the directory to be scanned.
90 * @return a vector containing File objects for each entry in the
91 * directory.
92 */
93 private Vector getDirectoryEntries(File directory) {
94 Vector files = new Vector();
95
96 // File[] filesInDir = directory.listFiles();
97 String[] filesInDir = directory.list();
98
99 if (filesInDir != null) {
100 int length = filesInDir.length;
101
102 for (int i = 0; i < length; ++i) {
103 files.addElement(new File(directory, filesInDir[i]));
104 }
105 }
106
107 return files;
108 }
109
110 /**
111 * Template method to allow subclasses to supply elements for the
112 * iteration. The directory iterator maintains a stack of iterators
113 * covering each level in the directory hierarchy. The current iterator
114 * covers the current directory being scanned. If the next entry in that
115 * directory is a subdirectory, the current iterator is pushed onto the
116 * stack and a new iterator is created for the subdirectory. If the
117 * entry is a file, it is returned as the next element and the iterator
118 * remains valid. If there are no more entries in the current directory,
119 * the topmost iterator on the stack is popped off to become the
120 * current iterator.
121 *
122 * @return the next ClassFile in the iteration.
123 */
124 public ClassFile getNextClassFile() {
125 ClassFile nextElement = null;
126
127 try {
128 while (nextElement == null) {
129 if (currentEnum.hasMoreElements()) {
130 File element = (File) currentEnum.nextElement();
131
132 if (element.isDirectory()) {
133
134 // push the current iterator onto the stack and then
135 // iterate through this directory.
136 enumStack.push(currentEnum);
137
138 Vector files = getDirectoryEntries(element);
139
140 currentEnum = files.elements();
141 } else {
142
143 // we have a file. create a stream for it
144 FileInputStream inFileStream
145 = new FileInputStream(element);
146
147 if (element.getName().endsWith(".class")) {
148
149 // create a data input stream from the jar
150 // input stream
151 ClassFile javaClass = new ClassFile();
152
153 javaClass.read(inFileStream);
154
155 nextElement = javaClass;
156 }
157 }
158 } else {
159 // this iterator is exhausted. Can we pop one off the stack
160 if (enumStack.empty()) {
161 break;
162 } else {
163 currentEnum = (Enumeration) enumStack.pop();
164 }
165 }
166 }
167 } catch (IOException e) {
168 nextElement = null;
169 }
170
171 return nextElement;
172 }
173
174}
175
Note: See TracBrowser for help on using the repository browser.