1 package com.insanityengine.ghia.util;
2
3 import java.io.File;
4 import java.util.Vector;
5 import java.util.Stack;
6
7 /***
8 *
9 * <P>
10 * Towards a java replacement for the uberHandy UNIX find command
11 * </P>
12 *
13 * <P>
14 * % javadoc -d javadoc/ $( java -cp jfreak.jar com.insanityengine.ghia.util.Find -name "*.java" )
15 * </P>
16 *
17 * @author BrianHammond
18 *
19 * $Header: /usr/local/cvsroot/ghia/src/java/com/insanityengine/ghia/util/Find.java,v 1.5 2005/03/19 17:50:02 brian Exp $
20 *
21 */
22
23 public class Find {
24
25 /***
26 *
27 */
28 public static void usage() {
29 System.err.println( "boohoo" );
30 }
31
32 /***
33 *
34 */
35 public final static void main( String argv[] ) {
36
37 Vector directories = new Vector();
38 Vector filters = new Vector();
39
40 boolean dirs = true;
41 for ( int i = 0 ; i < argv.length ; ++i ) {
42 String arg = argv[ i ];
43
44 if ( dirs ) {
45 if ( '-' != arg.charAt( 0 ) ) {
46 directories.addElement( arg );
47 continue;
48 }
49 }
50
51 if ( i == argv.length - 1 ) usage();
52
53 String val = argv[ ++i ];
54
55 FileFilter filter = getFilterByName( arg );
56 if ( null == filter ) {
57 System.err.println( arg + " not supported" );
58 System.exit( 1 );
59 } else {
60 filter.init( val );
61 filters.addElement( filter );
62 }
63 }
64
65 find( directories, filters );
66 }
67
68 /***
69 *
70 */
71 public final static Class forName( String name ) {
72 Class lass = null;
73 try {
74 lass = Class.forName( name );
75 } catch ( Exception e ) {
76 }
77 return lass;
78 }
79
80
81
82 /***
83 * like -name --> NameFileFilter --> com.insanityengine.ghia.util.NameFileFilter
84 */
85 public final static FileFilter getFilterByName( String name ) {
86 FileFilter filter = null;
87
88 String interfaceName = "FileFilter";
89 String packageName = "com.insanityengine.ghia.util.";
90 String fullName = packageName + interfaceName;
91
92 name = name.toUpperCase().charAt( 1 ) + name.substring( 2 ) + interfaceName;
93
94 Class candidate = forName( name );
95 if ( null == candidate ) {
96 name = "com.insanityengine.ghia.util." + name;
97 candidate = forName( name );
98 }
99
100 if ( null != candidate ) {
101 Class[] interfaces = candidate.getInterfaces();
102 for ( int i = 0 ; i < interfaces.length ; ++i ) {
103 if ( fullName.equals( interfaces[ i ].getName() ) ) {
104 try {
105 filter = ( FileFilter ) candidate.newInstance();
106 } catch ( Exception e ) {
107 e.printStackTrace();
108 }
109 break;
110 }
111 }
112
113 }
114
115 return filter;
116 }
117
118 /***
119 *
120 * Invoke a number of filters on a file until a filter fails
121 *
122 * @param file to test
123 * @param filters to invoke
124 *
125 * @return true if all filters pass, false otherwise
126 *
127 */
128 public final static boolean passesFilters( File f, Vector filters ) {
129 return invokeFilters( f, filters, true );
130 }
131
132 /***
133 *
134 * Invoke a number of filters on a file
135 *
136 * @param file to test
137 * @param filters to invoke
138 *
139 * @return true if all filters pass, false otherwise
140 *
141 */
142 public final static boolean invokeFilters( File f, Vector filters ) {
143 return invokeFilters( f, filters, false );
144 }
145
146 /***
147 *
148 * Invoke a number of filters on a file
149 *
150 * @param file to test
151 * @param filters to invoke
152 * @param bailOnFirst if true, break out after first fail
153 *
154 * @return true if all filters pass, false otherwise
155 *
156 */
157 public final static boolean invokeFilters( File file, Vector filters, boolean bailOnFirst ) {
158 int fcount = filters.size();
159 boolean rvalue = true;
160
161 for ( int i = 0 ; i < fcount ; ++i ) {
162 FileFilter filter = ( FileFilter ) filters.elementAt( i );
163 if ( filter.accept( file ) ) {
164 } else {
165 rvalue = false;
166 if ( bailOnFirst ) {
167 break;
168 }
169 }
170 }
171
172 return rvalue;
173 }
174
175 /***
176 *
177 * Recurse down the directories in the dirname Vector
178 * and pass the files to the StdOutFilter
179 *
180 * @param dirnames Vector of String names of directories
181 *
182 */
183 public final static void find( Vector dirnames ) {
184 Vector callbacks = new Vector();
185
186 callbacks.addElement( new FileFilter() {
187 public void init( String val ) {}
188
189 public boolean accept( File f ) {
190 return true;
191 }
192
193 public String getName() {
194 return "YesFileFilter";
195 }
196 } );
197
198 find( dirnames, callbacks );
199 }
200
201 /***
202 *
203 * Recurse down the directories in the dirname Vector
204 * and pass the files to the Vector of callbacks
205 *
206 * @param dirnames Vector of String names of directories
207 * @param callbacks Vector of FileFilter to invoke
208 *
209 */
210 public final static void find( Vector dirnames, Vector callbacks ) {
211 Vector filters = new Vector();
212
213 filters.addElement( new FileFilter() {
214 public void init( String val ) {}
215
216 public boolean accept( File f ) {
217 System.out.println( f );
218 return true;
219 }
220
221 public String getName() {
222 return "StdOutFilter";
223 }
224 } );
225
226 find( dirnames, callbacks, filters );
227 }
228
229 /***
230 *
231 * Recurse down the directories in the dirname Vector,
232 * any which pass all the filters (logical and) and
233 * sent to each of the callbacks
234 *
235 * @param dirnames Vector of String names of directories
236 * @param callbacks Vector of FileFilter to invoke
237 * @param filters Vector of FileFilter to test each file with
238 *
239 */
240 public final static void find( Vector dirnames, Vector callbacks, Vector filters ) {
241
242 if ( dirnames.size() == 0 ) dirnames.addElement( "." );
243
244 Stack dirs = new Stack();
245 for ( int i = 0 ; i < dirnames.size() ; ++i ) {
246
247 dirs.push( new File( ( String ) dirnames.elementAt( i ) ) );
248 }
249
250 find( dirs, filters, callbacks );
251 }
252
253 /***
254 *
255 * Recurse down the directories on the stack, any which pass all the
256 * filters (logical and) and sent to each of the callbacks
257 *
258 * @param dirs Stack of File's to recurse down
259 * @param callbacks Vector of FileFilter to invoke
260 * @param filters Vector of FileFilter to test each file with
261 *
262 */
263 public final static void find( Stack dirs, Vector callbacks, Vector filters ) {
264
265 while ( !dirs.empty() ) {
266
267
268 File file = ( File ) dirs.pop();
269
270 if ( passesFilters( file, filters ) ) invokeFilters( file, callbacks );
271
272
273 if ( !file.isDirectory() ) continue;
274
275 File[] files = file.listFiles();
276 for ( int i = 0 ; i < files.length ; ++i ) {
277 file = files [ i ];
278 if ( passesFilters( file, filters ) ) invokeFilters( file, callbacks );
279
280 if ( file.isDirectory() ) dirs.push( file );
281 }
282 }
283 }
284
285 };
286
287 /***
288 *
289 * $Log: Find.java,v $
290 * Revision 1.5 2005/03/19 17:50:02 brian
291 * repackaging
292 *
293 * Revision 1.4 2004/09/01 01:10:42 brian
294 * fix class level javadoc placement
295 *
296 * Revision 1.3 2004/09/01 00:11:06 brian
297 * author, log and header stuff
298 *
299 *
300 */