1 package com.explosion.utilities;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import java.awt.Component;
24 import java.awt.Image;
25 import java.awt.MediaTracker;
26 import java.awt.Toolkit;
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.InputStream;
30 import java.net.URL;
31 import java.util.Collection;
32 import java.util.Iterator;
33 import java.util.Set;
34 import java.util.StringTokenizer;
35 import java.util.Vector;
36 import java.util.jar.Attributes;
37 import java.util.jar.JarEntry;
38 import java.util.jar.JarFile;
39 import java.util.jar.Manifest;
40
41 import javax.swing.JFileChooser;
42
43 import org.apache.log4j.LogManager;
44 import org.apache.log4j.Logger;
45
46 import com.explosion.utilities.exception.ExceptionManagerFactory;
47 import com.explosion.utilities.process.threads.ProcessThread;
48 import com.explosion.utilities.regex.RegExpFileAndDirectoryFilter;
49 import com.explosion.utilities.regex.RegExpFileNameFilter;
50
51 public class FileSystemUtils
52 {
53
54 private static Logger log = LogManager.getLogger(FileSystemUtils.class);
55
56 public static final int SAVETYPE = 0;
57
58 public static final int OPENTYPE = 1;
59
60 public static final int FILES_ONLY = 0;
61
62 public static final int FILES_AND_DIRECTORIES = 1;
63
64 public static final int DIRECTORIES_ONLY = 2;
65
66 private static Vector jarFileOnClassPath = null;
67
68 private static Set jarFileNamesOnClassPath = null;
69
70 private static Vector allManifestEntries = null;
71
72
73 /***
74 * The mode refers to FILES_ONLY, DIRECTORIES_ONLY or FILES_AND_DIRECTORIES
75 * The type refers to SAVE or OPEN The rest is pretty self explanatory
76 *
77 * @param parent
78 * @param type
79 * @param multipleFiles
80 * @param defaultFile
81 * @param mode
82 * @return @throws Exception
83 */
84 public static File[] chooseFiles(Component parent, int type, boolean multipleFiles, File defaultFile, int mode) throws Exception
85 {
86 return chooseFiles(parent, type, multipleFiles, defaultFile, mode, null);
87 }
88
89 /***
90 * The mode refers to FILES_ONLY, DIRECTORIES_ONLY or FILES_AND_DIRECTORIES
91 * The type refers to SAVE or OPEN The rest is pretty self explanatory
92 *
93 * @param parent
94 * @param type
95 * @param multipleFiles
96 * @param defaultFile
97 * @param mode
98 * @param title
99 * @return @throws Exception
100 */
101 public static File[] chooseFiles(Component parent, int type, boolean multipleFiles, File defaultFile, int mode, String title) throws Exception
102 {
103 JFileChooser fc = new JFileChooser();
104 fc.setDoubleBuffered(true);
105 fc.setMultiSelectionEnabled(multipleFiles);
106 File currentFile = null;
107
108 if (defaultFile != null && defaultFile.exists())
109 {
110 currentFile = defaultFile;
111 } else
112 {
113 currentFile = new File(System.getProperty("user.dir"));
114 }
115
116 if (currentFile.exists())
117 {
118 if (currentFile.getParent() != null)
119 {
120 fc.setCurrentDirectory(currentFile);
121 }
122 }
123
124 switch (mode)
125 {
126 case (FileSystemUtils.FILES_ONLY):
127 fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
128 break;
129 case (FileSystemUtils.FILES_AND_DIRECTORIES):
130 fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
131 break;
132 case (FileSystemUtils.DIRECTORIES_ONLY):
133 fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
134 break;
135 }
136
137 if (title != null) fc.setDialogTitle(title);
138
139 int result = -999;
140 if (type == SAVETYPE)
141 result = fc.showSaveDialog(parent);
142 else if (type == OPENTYPE) result = fc.showOpenDialog(parent);
143
144 if (result == JFileChooser.APPROVE_OPTION)
145 {
146 File[] selectedfiles = new File[1];
147 if (multipleFiles)
148 selectedfiles = fc.getSelectedFiles();
149 else
150 selectedfiles[0] = fc.getSelectedFile();
151
152 System.setProperty("user.dir", selectedfiles[0].getAbsolutePath());
153 return selectedfiles;
154 }
155 return null;
156 }
157
158 /***
159 * This method returns a list of all the jar files which are on the
160 * classpath. It is optimized and only actually parses the classpath once per VM.
161 *
162 * @return Vector - a list of the JarFile instance.
163 */
164 public static Vector getJarFileListFromClasspath() throws Exception
165 {
166 if (jarFileOnClassPath != null) return jarFileOnClassPath;
167
168 StringTokenizer tokenizer = new StringTokenizer(System.getProperty("java.class.path"), System.getProperty("path.separator"));
169
170 jarFileOnClassPath = new Vector();
171 while (tokenizer.hasMoreTokens())
172 {
173 String jarFilePath = tokenizer.nextToken();
174 try
175 {
176 JarFile jarFile = new JarFile(jarFilePath.trim());
177 jarFileOnClassPath.addElement(jarFile);
178 } catch (java.util.zip.ZipException e)
179 {
180
181
182
183 }
184 }
185 return jarFileOnClassPath;
186 }
187
188 /***
189 * This method returns a list of File objects in a Vector. It only returns
190 * those Files that are not in Jar files and are not jar files. ie all the
191 * free files
192 *
193 * @return Vector free files
194 */
195 public static Vector getFreeFileListFromClassPath() throws Exception
196 {
197 return getFreeFileListFromClassPath("");
198 }
199
200 /***
201 * This method returns a list of File objects in a Vector. It only returns
202 * those Files that are not in Jar files and are not jar files. ie all the
203 * free files and also only returns those ofthefreefiles that match the
204 * given pattern This method is not optimized and the classpath freefiles
205 * will be searched every time this method is called.
206 *
207 * @param pattern of files to include in the list
208 */
209 public static Vector getFreeFileListFromClassPath(String pattern) throws Exception
210 {
211
212 String classPath = System.getProperty("java.class.path");
213 Vector list = new Vector();
214
215 StringTokenizer tokenizer = new StringTokenizer(classPath, System.getProperty("path.separator"));
216
217
218
219
220
221 while (tokenizer.hasMoreElements())
222 {
223 String tokenPath = tokenizer.nextToken();
224 File directory = new File(tokenPath);
225
226 if (directory.exists() && directory.isDirectory())
227 {
228 Vector v = getFileList(true, directory.getAbsolutePath(), pattern, false);
229 for (int i = 0; i < v.size(); i++)
230 list.addElement(v.elementAt(i));
231 }
232 }
233 return list;
234 }
235
236 /***
237 * This method hunts down a mainfest file with an entry with the given name
238 * and returns the atributes for that entry
239 *
240 * @param manifestEntryName
241 * @return Attributes froentry
242 * @throws Exception
243 */
244 public static Attributes getManifestAttributesForEntry(String manifestEntryName) throws Exception
245 {
246 boolean found = false;
247 Attributes attributes = null;
248
249
250 Vector jarFileList = getJarFileListFromClasspath();
251 for (int i = 0; i < jarFileList.size(); i++)
252 {
253 JarFile jarFile = (JarFile) jarFileList.elementAt(i);
254
255 if (jarFile != null)
256 {
257 Manifest manifest = jarFile.getManifest();
258 if (manifest != null)
259 {
260 attributes = (Attributes) manifest.getEntries().get(manifestEntryName);
261
262 if (attributes != null)
263 {
264 found = true;
265 break;
266 }
267 }
268 }
269 }
270
271 if (!found)
272 {
273 Vector freeFiles = getFreeFileListFromClassPath("manifest.mf");
274 for (int i = 0; i < freeFiles.size(); i++)
275 {
276 Manifest manifest = new Manifest(new FileInputStream((File) freeFiles.elementAt(i)));
277 attributes = (Attributes) manifest.getEntries().get(manifestEntryName);
278 if (attributes != null) break;
279 }
280 }
281 return attributes;
282 }
283
284 /***
285 * This method hunts down all Entries in all manifest files on the class
286 * path. This is optimized to only perform the operation once.
287 *
288 * @return Vector of Attributes objects one for each Entry in all manifest
289 * files
290 * @throws Exception
291 */
292 public static Vector getAllManifestEntries(String manifestMustHave) throws Exception
293 {
294 if (allManifestEntries != null) return allManifestEntries;
295
296 allManifestEntries = new Vector();
297
298
299 Vector jarFileList = getJarFileListFromClasspath();
300 for (int i = 0; i < jarFileList.size(); i++)
301 {
302 JarFile jarFile = (JarFile) jarFileList.elementAt(i);
303
304 if (jarFile != null)
305 {
306 Manifest manifest = jarFile.getManifest();
307 if (manifest != null)
308 {
309 if (manifest.getMainAttributes().getValue(manifestMustHave) != null)
310 {
311 if (manifest.getEntries() != null)
312 {
313 Collection collection = manifest.getEntries().values();
314 Iterator it = collection.iterator();
315 while (it.hasNext())
316 allManifestEntries.addElement(it.next());
317 }
318 }
319 }
320 }
321 }
322 Vector freeFiles = getFreeFileListFromClassPath("manifest.mf");
323 for (int i = 0; i < freeFiles.size(); i++)
324 {
325 Manifest manifest = new Manifest(new FileInputStream((File) freeFiles.elementAt(i)));
326 Set set = manifest.getMainAttributes().keySet();
327 Iterator tit = set.iterator();
328
329 if (manifest.getMainAttributes().getValue(manifestMustHave) != null)
330 {
331 if (manifest.getEntries() != null)
332 {
333 Collection collection = manifest.getEntries().values();
334 Iterator it = collection.iterator();
335 while (it.hasNext())
336 allManifestEntries.addElement(it.next());
337 }
338 }
339 }
340
341 return allManifestEntries;
342 }
343
344 /***
345 * The following method loads an image from the classes on the classpath.
346 * It uses the classloader which loaded the component to search for the image.
347 * If that doesn;t work it tries the system classloader
348 */
349 public static synchronized Image loadImage(String imagePath, Component component ) throws Exception
350 {
351 URL url = null;
352 Image img = null;
353
354 try
355 {
356 url = component.getClass().getClassLoader().getResource(imagePath);
357
358 if (url == null) url = ClassLoader.getSystemResource(imagePath);
359
360 if (url == null) url = component.getClass().getClassLoader().getResource(GeneralConstants.UNAVAILABLE_IMAGE);
361
362 if (url == null) url = ClassLoader.getSystemResource(GeneralConstants.UNAVAILABLE_IMAGE);
363
364 if (url == null) throw new Exception("Can find neither image '" + imagePath + "' nor image '" + GeneralConstants.UNAVAILABLE_IMAGE + "'");
365
366 img = Toolkit.getDefaultToolkit().getImage(url);
367 MediaTracker tracker = new MediaTracker(component);
368 tracker.addImage(img, 0);
369 try
370 {
371 tracker.waitForID(0);
372 } catch (InterruptedException exc)
373 {} catch (Exception e)
374 {
375 ExceptionManagerFactory.getExceptionManager().manageException(e, "Unable to load image '" + imagePath + "'.");
376 }
377 } catch (Exception e)
378 {
379 log.debug("Exception while getting image " + imagePath + " for " + component + ". You should check that the image you are looking for is on the classpath.");
380 throw e;
381 }
382 return img;
383 }
384
385 /***
386 * The following method builds the file list of files to be processed
387 */
388 public static Vector getFileList(boolean recursive, String directory, String pattern, boolean caseSensitive) throws Exception
389 {
390 return getFileList(null, recursive, directory, pattern, caseSensitive);
391 }
392
393 /***
394 * The following method builds the file list of files to be processed
395 */
396 public static Vector getFileList(ProcessThread controller, boolean recursive, String directory, String pattern, boolean caseSensitive) throws Exception
397 {
398
399 String fileNamePattern = (pattern == null ? "" : pattern);
400 RegExpFileAndDirectoryFilter regExpAndDirectoryFilter;
401 RegExpFileNameFilter regExpFilter = new RegExpFileNameFilter(fileNamePattern, caseSensitive);
402 File sourceDirectory = new File(directory);
403 Vector fileVector = new Vector();
404 File[] fileList;
405
406
407 if (!sourceDirectory.exists()) throw new Exception("Unable to find path specified for creating a list of files: " + directory);
408
409 if (!sourceDirectory.isDirectory()) throw new Exception("Path specified for creating a list of files is not a directory : " + directory);
410
411 if (!recursive)
412 {
413
414 regExpAndDirectoryFilter = new RegExpFileAndDirectoryFilter(regExpFilter);
415
416
417
418
419
420 if (controller != null) controller.getProcess().setStatusText("Listing directory " + sourceDirectory.getAbsolutePath());
421
422 fileList = sourceDirectory.listFiles(regExpAndDirectoryFilter);
423 for (int i = 0; i < fileList.length; i++)
424 fileVector.addElement(fileList[i]);
425
426 } else
427 {
428 buildFileListRecursive(controller, sourceDirectory, regExpFilter, fileVector);
429 }
430
431 return fileVector;
432 }
433
434 /***
435 * The following recursive method assists in the building of the list of
436 * files to process. Adapted from code written by Michael Liu
437 */
438 private static void buildFileListRecursive(ProcessThread controller, File directory, RegExpFileNameFilter regExpFilter, Vector fileVector) throws Exception
439 {
440 if (controller != null)
441 {
442 if (controller.getStatus() == ProcessThread.THREAD_STOPPED) return;
443 }
444
445
446
447
448
449
450 if (directory.isFile())
451 {
452 if (regExpFilter.accept(directory.getParentFile(), directory.getName())) fileVector.addElement(directory);
453 } else
454 {
455 if (controller != null) controller.getProcess().setStatusText("Listing directory " + directory.getAbsolutePath());
456
457
458 File[] fileArray = directory.listFiles();
459 Vector directoryList = new Vector();
460
461 if (fileArray != null)
462 {
463
464
465
466
467 for (int i = 0; i < fileArray.length; i++)
468 {
469
470 if (controller != null)
471 {
472 if (controller.getStatus() == ProcessThread.THREAD_STOPPED) return;
473 }
474
475 if (fileArray[i].isFile())
476 {
477 if (regExpFilter.accept(fileArray[i].getParentFile(), fileArray[i].getName())) fileVector.addElement(fileArray[i]);
478 } else
479 directoryList.addElement(fileArray[i]);
480 }
481 }
482
483
484
485
486 for (int i = 0; i < directoryList.size(); i++)
487 buildFileListRecursive(controller, (File) directoryList.elementAt(i), regExpFilter, fileVector);
488 }
489 }
490
491 /***
492 * The following method obtains an input stream to a file in a Zip/Jar file
493 *
494 * @param jarFile
495 * @param pathOfFileToGet (format eg: com/explosion/utils/FileUtils.java
496 * @return InputStream or null if the file was not found
497 */
498 public static InputStream getInputStreamFromJarFile(JarFile jarFile, String pathOfFileToGet) throws Exception
499 {
500 if (jarFile != null)
501 {
502 JarEntry entry = jarFile.getJarEntry(pathOfFileToGet);
503 if (entry != null) return jarFile.getInputStream(entry);
504 }
505
506 return null;
507 }
508
509 /***
510 * Method checkGivenPathValid. Checks to see that the given path points to a
511 * valid filepath It may notbe null or point to a directory. An exception
512 * will bethrown if it doesn't
513 *
514 * @param filePath
515 * @return File
516 * @throws IllegalArgumentException if the filePath provided is not valid
517 */
518 public static File checkGivenPathValid(String filePath) throws IllegalArgumentException
519 {
520
521 if (filePath == null) throw new IllegalArgumentException("Path to file is null.");
522
523 File file = new File(filePath);
524 if (file.exists())
525 {
526 if (file.isDirectory()) throw new IllegalArgumentException("The path '" + filePath + "' supplied points to a directory and not a file.");
527 }
528
529 return file;
530 }
531
532 }
533