1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.dbforms.util.external;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 import java.io.File;
90 import java.io.FileInputStream;
91 import java.io.FileOutputStream;
92 import java.io.IOException;
93 import java.io.InputStream;
94
95 import java.net.URL;
96
97 import java.util.Vector;
98
99
100
101 /***
102 * DOCUMENT ME!
103 *
104 * @author $author$
105 * @version $Revision: 1.9 $
106 */
107 public class FileUtil {
108 /*** The number of bytes in a kilobyte. */
109 public static final int ONE_KB = 1024;
110
111 /*** The number of bytes in a megabyte. */
112 public static final int ONE_MB = ONE_KB * ONE_KB;
113
114 /*** The number of bytes in a gigabyte. */
115 public static final int ONE_GB = ONE_KB * ONE_MB;
116
117
118
119 /***
120 * Private constructor to prevent instantiation.
121 */
122 private FileUtil() {
123 }
124
125 /***
126 * Get extension from filename. ie
127 * <pre>
128 * foo.txt --> "txt"
129 * a\b\c.jpg --> "jpg"
130 * a\b\c --> ""
131 * </pre>
132 *
133 * @param filename the filename
134 *
135 * @return the extension of filename or "" if none
136 */
137 public static String getExtension(final String filename) {
138 final int index = filename.lastIndexOf('.');
139
140 if (-1 == index) {
141 return "";
142 } else {
143 return filename.substring(index + 1);
144 }
145 }
146
147
148 /***
149 * Creates a file handle.
150 *
151 * @param fileName The name of the file.
152 *
153 * @return A <code>File</code> instance.
154 */
155 public static File getFile(String fileName) {
156 return new File(fileName);
157 }
158
159
160 /***
161 * Given a directory and an array of extensions... return an array of
162 * compliant files. The given extensions should be like "java" and not like
163 * ".java"
164 *
165 * @param directory DOCUMENT ME!
166 * @param extensions DOCUMENT ME!
167 *
168 * @return DOCUMENT ME!
169 */
170 public static String[] getFilesFromExtension(String directory,
171 String[] extensions) {
172 Vector files = new Vector();
173
174 java.io.File currentDir = new java.io.File(directory);
175
176 String[] unknownFiles = currentDir.list();
177
178 if (unknownFiles == null) {
179 return new String[0];
180 }
181
182 for (int i = 0; i < unknownFiles.length; ++i) {
183 String currentFileName = directory
184 + System.getProperty("file.separator")
185 + unknownFiles[i];
186 java.io.File currentFile = new java.io.File(currentFileName);
187
188 if (currentFile.isDirectory()) {
189
190 if (currentFile.getName()
191 .equals("CVS")) {
192 continue;
193 }
194
195
196
197 String[] fetchFiles = getFilesFromExtension(currentFileName,
198 extensions);
199 files = blendFilesToVector(files, fetchFiles);
200 } else {
201
202 String add = currentFile.getAbsolutePath();
203
204 if (isValidFile(add, extensions)) {
205 files.addElement(add);
206 }
207 }
208 }
209
210
211 String[] foundFiles = new String[files.size()];
212 files.copyInto(foundFiles);
213
214 return foundFiles;
215 }
216
217
218 /***
219 * Get path from filename. Roughly equivalent to the unix command
220 * <code>dirname</code>. ie.
221 * <pre>
222 * a/b/c.txt --> a/b
223 * a.txt --> ""
224 * </pre>
225 *
226 * @param filepath the filepath
227 *
228 * @return the filename minus path
229 */
230 public static String getPath(final String filepath) {
231 return getPath(filepath, File.separatorChar);
232 }
233
234
235 /***
236 * Get path from filename. ie.
237 * <pre>
238 * a/b/c.txt --> a/b
239 * a.txt --> ""
240 * </pre>
241 *
242 * @param filepath the filepath
243 * @param fileSeparatorChar DOCUMENT ME!
244 *
245 * @return the filename minus path
246 */
247 public static String getPath(final String filepath,
248 final char fileSeparatorChar) {
249 final int index = filepath.lastIndexOf(fileSeparatorChar);
250
251 if (-1 == index) {
252 return "";
253 } else {
254 return filepath.substring(0, index);
255 }
256 }
257
258
259 /***
260 * Returns the filename portion of a file specification string. Matches the
261 * equally named unix command.
262 *
263 * @param filename DOCUMENT ME!
264 *
265 * @return The filename string without extension.
266 */
267 public static String basename(String filename) {
268 return basename(filename, extension(filename));
269 }
270
271
272 /***
273 * Returns the filename portion of a file specification string. Matches the
274 * equally named unix command.
275 *
276 * @param filename DOCUMENT ME!
277 * @param suffix DOCUMENT ME!
278 *
279 * @return DOCUMENT ME!
280 */
281 public static String basename(String filename,
282 String suffix) {
283 int i = filename.lastIndexOf(File.separator) + 1;
284 int lastDot = ((suffix != null) && (suffix.length() > 0))
285 ? filename.lastIndexOf(suffix)
286 : (-1);
287
288 if (lastDot >= 0) {
289 return filename.substring(i, lastDot);
290 } else if (i > 0) {
291 return filename.substring(i);
292 } else {
293 return filename;
294 }
295 }
296
297
298 /***
299 * Returns a human-readable version of the file size (original is in bytes).
300 *
301 * @param size The number of bytes.
302 *
303 * @return A human-readable display value (includes units).
304 */
305 public static String byteCountToDisplaySize(int size) {
306 String displaySize;
307
308 if ((size / ONE_GB) > 0) {
309 displaySize = String.valueOf(size / ONE_GB) + " GB";
310 } else if ((size / ONE_MB) > 0) {
311 displaySize = String.valueOf(size / ONE_MB) + " MB";
312 } else if ((size / ONE_KB) > 0) {
313 displaySize = String.valueOf(size / ONE_KB) + " KB";
314 } else {
315 displaySize = String.valueOf(size) + " bytes";
316 }
317
318 return displaySize;
319 }
320
321
322 /***
323 * Will concatenate 2 paths. Paths with <code>..</code> will be
324 * properly handled. <p>Eg.,<br />
325 * <code>/a/b/c</code> + <code>d</code> =
326 * <code>/a/b/d</code><br />
327 * <code>/a/b/c</code> + <code>../d</code> =
328 * <code>/a/d</code><br /> </p> Thieved from Tomcat
329 * sources...
330 *
331 * @param lookupPath DOCUMENT ME!
332 * @param path DOCUMENT ME!
333 *
334 * @return The concatenated paths, or null if error occurs
335 */
336 public static String catPath(final String lookupPath,
337 final String path) {
338
339 int index = lookupPath.lastIndexOf("/");
340 String lookup = lookupPath.substring(0, index);
341 String pth = path;
342
343
344 while (pth.startsWith("../")) {
345 if (lookup.length() > 0) {
346 index = lookup.lastIndexOf("/");
347 lookup = lookup.substring(0, index);
348 } else {
349
350 return null;
351 }
352
353 index = pth.indexOf("../") + 3;
354 pth = pth.substring(index);
355 }
356
357 return new StringBuffer(lookup).append("/")
358 .append(pth)
359 .toString();
360 }
361
362
363 /***
364 * Clean a directory without deleting it.
365 *
366 * @param directory DOCUMENT ME!
367 *
368 * @throws IOException DOCUMENT ME!
369 */
370 public static void cleanDirectory(final String directory)
371 throws IOException {
372 cleanDirectory(new File(directory));
373 }
374
375
376 /***
377 * Clean a directory without deleting it.
378 *
379 * @param directory DOCUMENT ME!
380 *
381 * @throws IOException DOCUMENT ME!
382 */
383 public static void cleanDirectory(final File directory)
384 throws IOException {
385 if (!directory.exists()) {
386 final String message = directory + " does not exist";
387 throw new IllegalArgumentException(message);
388 }
389
390 if (!directory.isDirectory()) {
391 final String message = directory + " is not a directory";
392 throw new IllegalArgumentException(message);
393 }
394
395 IOException exception = null;
396
397 final File[] files = directory.listFiles();
398
399 for (int i = 0; i < files.length; i++) {
400 final File file = files[i];
401
402 try {
403 forceDelete(file);
404 } catch (final IOException ioe) {
405 exception = ioe;
406 }
407 }
408
409 if (null != exception) {
410 throw exception;
411 }
412 }
413
414
415 /***
416 * Compare the contents of two files to determine if they are equal or not.
417 *
418 * @param file1 the first file
419 * @param file2 the second file
420 *
421 * @return true if the content of the files are equal or they both don't
422 * exist, false otherwise
423 *
424 * @throws IOException DOCUMENT ME!
425 */
426 public static boolean contentEquals(final File file1,
427 final File file2)
428 throws IOException {
429 final boolean file1Exists = file1.exists();
430
431 if (file1Exists != file2.exists()) {
432 return false;
433 }
434
435 if (!file1Exists) {
436
437 return true;
438 }
439
440 if (file1.isDirectory() || file2.isDirectory()) {
441
442 return false;
443 }
444
445 InputStream input1 = null;
446 InputStream input2 = null;
447
448 try {
449 input1 = new FileInputStream(file1);
450 input2 = new FileInputStream(file2);
451
452 return IOUtil.contentEquals(input1, input2);
453 } finally {
454 IOUtil.shutdownStream(input1);
455 IOUtil.shutdownStream(input2);
456 }
457 }
458
459
460 /***
461 * Copy file from source to destination. The directories up to
462 * <code>destination</code> will be created if they don't already exist.
463 * <code>destination</code> will be overwritten if it already exists.
464 *
465 * @param source An existing non-directory <code>File</code> to copy bytes
466 * from.
467 * @param destination A non-directory <code>File</code> to write bytes to
468 * (possibly overwriting).
469 *
470 * @throws IOException if <code>source</code> does not exist,
471 * <code>destination</code> cannot be written to, or an IO error
472 * occurs during copying.
473 */
474 public static void copyFile(final File source,
475 final File destination)
476 throws IOException {
477
478 if (!source.exists()) {
479 final String message = "File " + source + " does not exist";
480 throw new IOException(message);
481 }
482
483
484 if ((destination.getParentFile() != null)
485 && !destination.getParentFile()
486 .exists()) {
487 destination.getParentFile()
488 .mkdirs();
489 }
490
491
492 if (destination.exists() && !destination.canWrite()) {
493 final String message = "Unable to open file " + destination
494 + " for writing.";
495 throw new IOException(message);
496 }
497
498 final FileInputStream input = new FileInputStream(source);
499 final FileOutputStream output = new FileOutputStream(destination);
500 IOUtil.copy(input, output);
501 IOUtil.shutdownStream(input);
502 IOUtil.shutdownStream(output);
503
504 if (source.length() != destination.length()) {
505 final String message = "Failed to copy full contents from " + source
506 + " to " + destination;
507 throw new IOException(message);
508 }
509 }
510
511
512 /***
513 * Copy file from source to destination. If
514 * <code>destinationDirectory</code> does not exist, it (and any parent
515 * directories) will be created. If a file <code>source</code> in
516 * <code>destinationDirectory</code> exists, it will be overwritten.
517 *
518 * @param source An existing <code>File</code> to copy.
519 * @param destinationDirectory A directory to copy <code>source</code> into.
520 *
521 * @throws IOException if <code>source</code> does not exist, the file in
522 * <code>destinationDirectory</code> cannot be written to, or an IO
523 * error occurs during copying.
524 */
525 public static void copyFileToDirectory(final String source,
526 final String destinationDirectory)
527 throws IOException {
528 copyFileToDirectory(new File(source), new File(destinationDirectory));
529 }
530
531
532 /***
533 * Copy file from source to destination. If
534 * <code>destinationDirectory</code> does not exist, it (and any parent
535 * directories) will be created. If a file <code>source</code> in
536 * <code>destinationDirectory</code> exists, it will be overwritten.
537 *
538 * @param source An existing <code>File</code> to copy.
539 * @param destinationDirectory A directory to copy <code>source</code> into.
540 *
541 * @throws IOException if <code>source</code> does not exist, the file in
542 * <code>destinationDirectory</code> cannot be written to, or an IO
543 * error occurs during copying.
544 */
545 public static void copyFileToDirectory(final File source,
546 final File destinationDirectory)
547 throws IOException {
548 if (destinationDirectory.exists() && !destinationDirectory.isDirectory()) {
549 throw new IllegalArgumentException("Destination is not a directory");
550 }
551
552 copyFile(source, new File(destinationDirectory, source.getName()));
553 }
554
555
556 /***
557 * Copies bytes from the URL <code>source</code> to a file
558 * <code>destination</code>. The directories up to <code>destination</code>
559 * will be created if they don't already exist. <code>destination</code>
560 * will be overwritten if it already exists.
561 *
562 * @param source A <code>URL</code> to copy bytes from.
563 * @param destination A non-directory <code>File</code> to write bytes to
564 * (possibly overwriting).
565 *
566 * @throws IOException if <ul><li><code>source</code> URL cannot be
567 * opened</li> <li><code>destination</code> cannot be written
568 * to</li> <li>an IO error occurs during copying</li> </ul>
569 */
570 public static void copyURLToFile(final URL source,
571 final File destination)
572 throws IOException {
573
574 if ((destination.getParentFile() != null)
575 && !destination.getParentFile()
576 .exists()) {
577 destination.getParentFile()
578 .mkdirs();
579 }
580
581
582 if (destination.exists() && !destination.canWrite()) {
583 final String message = "Unable to open file " + destination
584 + " for writing.";
585 throw new IOException(message);
586 }
587
588 final InputStream input = source.openStream();
589 final FileOutputStream output = new FileOutputStream(destination);
590 IOUtil.copy(input, output);
591 IOUtil.shutdownStream(input);
592 IOUtil.shutdownStream(output);
593 }
594
595
596 /***
597 * Recursively delete a directory.
598 *
599 * @param directory DOCUMENT ME!
600 *
601 * @throws IOException DOCUMENT ME!
602 */
603 public static void deleteDirectory(final String directory)
604 throws IOException {
605 deleteDirectory(new File(directory));
606 }
607
608
609 /***
610 * Recursively delete a directory.
611 *
612 * @param directory DOCUMENT ME!
613 *
614 * @throws IOException DOCUMENT ME!
615 */
616 public static void deleteDirectory(final File directory)
617 throws IOException {
618 if (!directory.exists()) {
619 return;
620 }
621
622 cleanDirectory(directory);
623
624 if (!directory.delete()) {
625 final String message = "Directory " + directory
626 + " unable to be deleted.";
627 throw new IOException(message);
628 }
629 }
630
631
632 /***
633 * Returns the directory path portion of a file specification string.
634 * Matches the equally named unix command.
635 *
636 * @param filename DOCUMENT ME!
637 *
638 * @return The directory portion excluding the ending file separator.
639 */
640 public static String dirname(String filename) {
641 int i = filename.lastIndexOf(File.separator);
642
643 return ((i >= 0) ? filename.substring(0, i)
644 : "");
645 }
646
647
648 /***
649 * Returns the extension portion of a file specification string. This
650 * everything after the last dot '.' in the filename (NOT including the
651 * dot).
652 *
653 * @param filename DOCUMENT ME!
654 *
655 * @return DOCUMENT ME!
656 */
657 public static String extension(String filename) {
658 int lastDot = filename.lastIndexOf('.');
659
660 if (lastDot >= 0) {
661 return filename.substring(lastDot + 1);
662 } else {
663 return "";
664 }
665 }
666
667
668 /***
669 * Copy a file. The new file will be created if it does not exist. This is
670 * an inefficient method, which just calls {@link #fileRead(String)} and
671 * then {@link #fileWrite(String,String)}
672 *
673 * @param inFileName the file to copy
674 * @param outFileName the file to copy to
675 *
676 * @throws Exception if fileRead or fileWrite throw it
677 */
678 public static void fileCopy(String inFileName,
679 String outFileName) throws Exception {
680 String content = fileRead(inFileName);
681 fileWrite(outFileName, content);
682 }
683
684
685 /***
686 * Deletes a file.
687 *
688 * @param fileName The name of the file to delete.
689 */
690 public static void fileDelete(String fileName) {
691 File file = new File(fileName);
692 file.delete();
693 }
694
695
696 /***
697 * Check if a file exits.
698 *
699 * @param fileName The name of the file to check.
700 *
701 * @return true if file exists.
702 */
703 public static boolean fileExists(String fileName) {
704 File file = new File(fileName);
705
706 return file.exists();
707 }
708
709
710 /***
711 * Reads the contents of a file.
712 *
713 * @param fileName The name of the file to read.
714 *
715 * @return The file contents or null if read failed.
716 *
717 * @throws IOException DOCUMENT ME!
718 */
719 public static String fileRead(String fileName) throws IOException {
720 StringBuffer buf = new StringBuffer();
721
722 FileInputStream in = new FileInputStream(fileName);
723
724 try {
725 int count;
726 byte[] b = new byte[512];
727
728 while ((count = in.read(b)) > 0)
729 {
730 buf.append(new String(b, 0, count));
731 }
732 } finally {
733 in.close();
734 }
735
736 return buf.toString();
737 }
738
739
740 /***
741 * Writes data to a file. The file will be created if it does not exist.
742 *
743 * @param fileName The name of the file to write.
744 * @param data The content to write to the file.
745 *
746 * @throws Exception DOCUMENT ME!
747 */
748 public static void fileWrite(String fileName,
749 String data) throws Exception {
750 FileOutputStream out = new FileOutputStream(fileName);
751
752 try {
753 out.write(data.getBytes());
754 } finally {
755 out.close();
756 }
757 }
758
759
760 /***
761 * Returns the filename portion of a file specification string.
762 *
763 * @param filename DOCUMENT ME!
764 *
765 * @return The filename string with extension.
766 */
767 public static String filename(String filename) {
768 int i = filename.lastIndexOf(File.separator);
769
770 return ((i >= 0) ? filename.substring(i + 1)
771 : filename);
772 }
773
774
775 /***
776 * Delete a file. If file is directory delete it and all sub-directories.
777 *
778 * @param file DOCUMENT ME!
779 *
780 * @throws IOException DOCUMENT ME!
781 */
782 public static void forceDelete(final String file) throws IOException {
783 forceDelete(new File(file));
784 }
785
786
787 /***
788 * Delete a file. If file is directory delete it and all sub-directories.
789 *
790 * @param file DOCUMENT ME!
791 *
792 * @throws IOException DOCUMENT ME!
793 */
794 public static void forceDelete(final File file) throws IOException {
795 if (file.isDirectory()) {
796 deleteDirectory(file);
797 } else {
798 if (!file.delete()) {
799 final String message = "File " + file + " unable to be deleted.";
800 throw new IOException(message);
801 }
802 }
803 }
804
805
806 /***
807 * Schedule a file to be deleted when JVM exits. If file is directory delete
808 * it and all sub-directories.
809 *
810 * @param file DOCUMENT ME!
811 *
812 * @throws IOException DOCUMENT ME!
813 */
814 public static void forceDeleteOnExit(final File file)
815 throws IOException {
816 if (file.isDirectory()) {
817 deleteDirectoryOnExit(file);
818 } else {
819 file.deleteOnExit();
820 }
821 }
822
823
824 /***
825 * Make a directory. If there already exists a file with specified name or
826 * the directory is unable to be created then an exception is thrown.
827 *
828 * @param file DOCUMENT ME!
829 *
830 * @throws IOException DOCUMENT ME!
831 */
832 public static void forceMkdir(final File file) throws IOException {
833 if (file.exists()) {
834 if (file.isFile()) {
835 final String message = "File " + file + " exists and is "
836 + "not a directory. Unable to create directory.";
837 throw new IOException(message);
838 }
839 } else {
840 if (false == file.mkdirs()) {
841 final String message = "Unable to create directory " + file;
842 throw new IOException(message);
843 }
844 }
845 }
846
847
848 /***
849 * Simple way to make a directory
850 *
851 * @param dir DOCUMENT ME!
852 */
853 public static void mkdir(String dir) {
854 File file = new File(dir);
855
856 if (!file.exists()) {
857 file.mkdirs();
858 }
859 }
860
861
862 /***
863 * Normalize a path. Eliminates "/../" and "/./" in a string. Returns
864 * <code>null</code> if the ..'s went past the root. Eg:
865 * <pre>
866 * /foo// --> /foo/
867 * /foo/./ --> /foo/
868 * /foo/../bar --> /bar
869 * /foo/../bar/ --> /bar/
870 * /foo/../bar/../baz --> /baz
871 * //foo//./bar --> /foo/bar
872 * /../ --> null
873 * </pre>
874 *
875 * @param path the path to normalize
876 *
877 * @return the normalized String, or <code>null</code> if too many ..'s.
878 */
879 public static String normalize(final String path) {
880 String normalized = path;
881
882
883 while (true) {
884 int index = normalized.indexOf("//");
885
886 if (index < 0) {
887 break;
888 }
889
890 normalized = normalized.substring(0, index)
891 + normalized.substring(index + 1);
892 }
893
894
895 while (true) {
896 int index = normalized.indexOf("/./");
897
898 if (index < 0) {
899 break;
900 }
901
902 normalized = normalized.substring(0, index)
903 + normalized.substring(index + 2);
904 }
905
906
907 while (true) {
908 int index = normalized.indexOf("/../");
909
910 if (index < 0) {
911 break;
912 }
913
914 if (index == 0) {
915 return null;
916 }
917
918 int index2 = normalized.lastIndexOf('/', index - 1);
919 normalized = normalized.substring(0, index2)
920 + normalized.substring(index + 3);
921 }
922
923
924 return normalized;
925 }
926
927
928 /***
929 * Remove extension from filename. ie
930 * <pre>
931 * foo.txt --> foo
932 * a\b\c.jpg --> a\b\c
933 * a\b\c --> a\b\c
934 * </pre>
935 *
936 * @param filename the filename
937 *
938 * @return the filename minus extension
939 */
940 public static String removeExtension(final String filename) {
941 final int index = filename.lastIndexOf('.');
942
943 if (-1 == index) {
944 return filename;
945 } else {
946 return filename.substring(0, index);
947 }
948 }
949
950
951 /***
952 * Remove path from filename. Equivalent to the unix command
953 * <code>basename</code> ie.
954 * <pre>
955 * a/b/c.txt --> c.txt
956 * a.txt --> a.txt
957 * </pre>
958 *
959 * @param filepath the filepath
960 *
961 * @return the filename minus path
962 */
963 public static String removePath(final String filepath) {
964 return removePath(filepath, File.separatorChar);
965 }
966
967
968 /***
969 * Remove path from filename. ie.
970 * <pre>
971 * a/b/c.txt --> c.txt
972 * a.txt --> a.txt
973 * </pre>
974 *
975 * @param filepath the filepath
976 * @param fileSeparatorChar DOCUMENT ME!
977 *
978 * @return the filename minus path
979 */
980 public static String removePath(final String filepath,
981 final char fileSeparatorChar) {
982 final int index = filepath.lastIndexOf(fileSeparatorChar);
983
984 if (-1 == index) {
985 return filepath;
986 } else {
987 return filepath.substring(index + 1);
988 }
989 }
990
991
992 /***
993 * Resolve a file <code>filename</code> to it's canonical form. If
994 * <code>filename</code> is relative (doesn't start with <code>/</code>),
995 * it will be resolved relative to <code>baseFile</code>, otherwise it is
996 * treated as a normal root-relative path.
997 *
998 * @param baseFile Where to resolve <code>filename</code> from, if
999 * <code>filename</code> is relative.
1000 * @param filename Absolute or relative file path to resolve.
1001 *
1002 * @return The canonical <code>File</code> of <code>filename</code>.
1003 */
1004 public static File resolveFile(final File baseFile,
1005 String filename) {
1006 String filenm = filename;
1007
1008 if ('/' != File.separatorChar) {
1009 filenm = filename.replace('/', File.separatorChar);
1010 }
1011
1012 if ('//' != File.separatorChar) {
1013 filenm = filename.replace('//', File.separatorChar);
1014 }
1015
1016
1017 if (filenm.startsWith(File.separator)) {
1018 File file = new File(filenm);
1019
1020 try {
1021 file = file.getCanonicalFile();
1022 } catch (final IOException ioe) {
1023 ;
1024 }
1025
1026 return file;
1027 }
1028
1029
1030
1031 final char[] chars = filename.toCharArray();
1032 final StringBuffer sb = new StringBuffer();
1033
1034
1035
1036
1037 int start = 0;
1038
1039 if ('//' == File.separatorChar) {
1040 sb.append(filenm.charAt(0));
1041 start++;
1042 }
1043
1044 for (int i = start; i < chars.length; i++) {
1045 final boolean doubleSeparator = (File.separatorChar == chars[i])
1046 && (File.separatorChar == chars[i - 1]);
1047
1048 if (!doubleSeparator) {
1049 sb.append(chars[i]);
1050 }
1051 }
1052
1053 filenm = sb.toString();
1054
1055
1056 File file = (new File(baseFile, filenm)).getAbsoluteFile();
1057
1058 try {
1059 file = file.getCanonicalFile();
1060 } catch (final IOException ioe) {
1061 ;
1062 }
1063
1064 return file;
1065 }
1066
1067
1068 /***
1069 * Recursively count size of a directory.
1070 *
1071 * @param directory DOCUMENT ME!
1072 *
1073 * @return size of directory in bytes.
1074 */
1075 public static long sizeOfDirectory(final String directory) {
1076 return sizeOfDirectory(new File(directory));
1077 }
1078
1079
1080 /***
1081 * Recursively count size of a directory.
1082 *
1083 * @param directory DOCUMENT ME!
1084 *
1085 * @return size of directory in bytes.
1086 */
1087 public static long sizeOfDirectory(final File directory) {
1088 if (!directory.exists()) {
1089 final String message = directory + " does not exist";
1090 throw new IllegalArgumentException(message);
1091 }
1092
1093 if (!directory.isDirectory()) {
1094 final String message = directory + " is not a directory";
1095 throw new IllegalArgumentException(message);
1096 }
1097
1098 long size = 0;
1099
1100 final File[] files = directory.listFiles();
1101
1102 for (int i = 0; i < files.length; i++) {
1103 final File file = files[i];
1104
1105 if (file.isDirectory()) {
1106 size += sizeOfDirectory(file);
1107 } else {
1108 size += file.length();
1109 }
1110 }
1111
1112 return size;
1113 }
1114
1115
1116 /***
1117 * Convert from a <code>URL</code> to a <code>File</code>.
1118 *
1119 * @param url File URL.
1120 *
1121 * @return The equivalent <code>File</code> object, or <code>null</code> if
1122 * the URL's protocol is not <code>file</code>
1123 */
1124 public static File toFile(final URL url) {
1125 if (url.getProtocol()
1126 .equals("file") == false) {
1127 return null;
1128 } else {
1129 final String filename = url.getFile()
1130 .replace('/', File.separatorChar);
1131
1132 return new File(filename);
1133 }
1134 }
1135
1136
1137 /***
1138 * Convert the array of Files into a list of URLs.
1139 *
1140 * @param files the array of files
1141 *
1142 * @return the array of URLs
1143 *
1144 * @throws IOException if an error occurs
1145 */
1146 public static URL[] toURLs(final File[] files) throws IOException {
1147 final URL[] urls = new URL[files.length];
1148
1149 for (int i = 0; i < urls.length; i++) {
1150 urls[i] = files[i].toURL();
1151 }
1152
1153 return urls;
1154 }
1155
1156
1157 /***
1158 * Waits for NFS to propagate a file creation, imposing a timeout.
1159 *
1160 * @param fileName The name of the file.
1161 * @param seconds The maximum time in seconds to wait.
1162 *
1163 * @return True if file exists.
1164 */
1165 public static boolean waitFor(String fileName,
1166 int seconds) {
1167 File file = new File(fileName);
1168 int timeout = 0;
1169 int tick = 0;
1170
1171 while (!file.exists()) {
1172 if (tick++ >= 10) {
1173 tick = 0;
1174
1175 if (timeout++ > seconds) {
1176 return false;
1177 }
1178 }
1179
1180 try {
1181 Thread.sleep(100);
1182 } catch (InterruptedException ignore) {
1183 ;
1184 } catch (Exception ex) {
1185 break;
1186 }
1187 }
1188
1189 return true;
1190 }
1191
1192
1193 /***
1194 * Checks to see if a file is of a particular type(s). Note that if the file
1195 * does not have an extension, an empty string ("") is matched
1196 * for.
1197 *
1198 * @param file DOCUMENT ME!
1199 * @param extensions DOCUMENT ME!
1200 *
1201 * @return DOCUMENT ME!
1202 */
1203 private static boolean isValidFile(String file,
1204 String[] extensions) {
1205 String extension = extension(file);
1206
1207 if (extension == null) {
1208 extension = "";
1209 }
1210
1211
1212
1213 for (int i = 0; i < extensions.length; ++i) {
1214 if (extensions[i].equals(extension)) {
1215 return true;
1216 }
1217 }
1218
1219 return false;
1220 }
1221
1222
1223 /***
1224 * Private hepler method for getFilesFromExtension()
1225 *
1226 * @param v DOCUMENT ME!
1227 * @param files DOCUMENT ME!
1228 *
1229 * @return DOCUMENT ME!
1230 */
1231 private static Vector blendFilesToVector(Vector v,
1232 String[] files) {
1233 for (int i = 0; i < files.length; ++i) {
1234 v.addElement(files[i]);
1235 }
1236
1237 return v;
1238 }
1239
1240
1241 /***
1242 * Clean a directory without deleting it.
1243 *
1244 * @param directory DOCUMENT ME!
1245 *
1246 * @throws IOException DOCUMENT ME!
1247 * @throws IllegalArgumentException DOCUMENT ME!
1248 */
1249 private static void cleanDirectoryOnExit(final File directory)
1250 throws IOException {
1251 if (!directory.exists()) {
1252 final String message = directory + " does not exist";
1253 throw new IllegalArgumentException(message);
1254 }
1255
1256 if (!directory.isDirectory()) {
1257 final String message = directory + " is not a directory";
1258 throw new IllegalArgumentException(message);
1259 }
1260
1261 IOException exception = null;
1262
1263 final File[] files = directory.listFiles();
1264
1265 for (int i = 0; i < files.length; i++) {
1266 final File file = files[i];
1267
1268 try {
1269 forceDeleteOnExit(file);
1270 } catch (final IOException ioe) {
1271 exception = ioe;
1272 }
1273 }
1274
1275 if (null != exception) {
1276 throw exception;
1277 }
1278 }
1279
1280
1281 /***
1282 * Recursively schedule directory for deletion on JVM exit.
1283 *
1284 * @param directory DOCUMENT ME!
1285 *
1286 * @throws IOException DOCUMENT ME!
1287 */
1288 private static void deleteDirectoryOnExit(final File directory)
1289 throws IOException {
1290 if (!directory.exists()) {
1291 return;
1292 }
1293
1294 cleanDirectoryOnExit(directory);
1295 directory.deleteOnExit();
1296 }
1297 }