KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dbforms > util > external > FileUtil


1 /*
2  * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/util/external/FileUtil.java,v 1.9 2004/08/18 13:12:00 hkollmann Exp $
3  * $Revision: 1.9 $
4  * $Date: 2004/08/18 13:12:00 $
5  *
6  * DbForms - a Rapid Application Development Framework
7  * Copyright (C) 2001 Joachim Peer <joepeer@excite.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */

23
24 /*
25  * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/util/external/FileUtil.java,v 1.9 2004/08/18 13:12:00 hkollmann Exp $
26  * $Revision: 1.9 $
27  * $Date: 2004/08/18 13:12:00 $
28  *
29  * FileUtil class taken from jakarta-commons-sandbox project.
30  *
31 **/

32 package org.dbforms.util.external;
33
34
35 /* ====================================================================
36  * The Apache Software License, Version 1.1
37  *
38  * Copyright (c) 2001 The Apache Software Foundation. All rights
39  * reserved.
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  *
45  * 1. Redistributions of source code must retain the above copyright
46  * notice, this list of conditions and the following disclaimer.
47  *
48  * 2. Redistributions in binary form must reproduce the above copyright
49  * notice, this list of conditions and the following disclaimer in
50  * the documentation and/or other materials provided with the
51  * distribution.
52  *
53  * 3. The end-user documentation included with the redistribution,
54  * if any, must include the following acknowledgment:
55  * "This product includes software developed by the
56  * Apache Software Foundation (http://www.apache.org/)."
57  * Alternately, this acknowledgment may appear in the software itself,
58  * if and wherever such third-party acknowledgments normally appear.
59  *
60  * 4. The names "Apache" and "Apache Software Foundation" and
61  * "Apache Turbine" must not be used to endorse or promote products
62  * derived from this software without prior written permission. For
63  * written permission, please contact apache@apache.org.
64  *
65  * 5. Products derived from this software may not be called "Apache",
66  * "Apache Turbine", nor may "Apache" appear in their name, without
67  * prior written permission of the Apache Software Foundation.
68  *
69  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
70  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
71  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
73  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
74  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
75  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
76  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
78  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
79  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
80  * SUCH DAMAGE.
81  * ====================================================================
82  *
83  * This software consists of voluntary contributions made by many
84  * individuals on behalf of the Apache Software Foundation. For more
85  * information on the Apache Software Foundation, please see
86  * <http://www.apache.org/>.
87  *
88  */

89 import java.io.File JavaDoc;
90 import java.io.FileInputStream JavaDoc;
91 import java.io.FileOutputStream JavaDoc;
92 import java.io.IOException JavaDoc;
93 import java.io.InputStream JavaDoc;
94
95 import java.net.URL JavaDoc;
96
97 import java.util.Vector JavaDoc;
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    /* *** AVALON CODE *** */
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 JavaDoc getExtension(final String JavaDoc 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 JavaDoc getFile(String JavaDoc fileName) {
156       return new File JavaDoc(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 JavaDoc[] getFilesFromExtension(String JavaDoc directory,
171                                                 String JavaDoc[] extensions) {
172       Vector JavaDoc files = new Vector JavaDoc();
173
174       java.io.File JavaDoc currentDir = new java.io.File JavaDoc(directory);
175
176       String JavaDoc[] unknownFiles = currentDir.list();
177
178       if (unknownFiles == null) {
179          return new String JavaDoc[0];
180       }
181
182       for (int i = 0; i < unknownFiles.length; ++i) {
183          String JavaDoc currentFileName = directory
184                                   + System.getProperty("file.separator")
185                                   + unknownFiles[i];
186          java.io.File JavaDoc currentFile = new java.io.File JavaDoc(currentFileName);
187
188          if (currentFile.isDirectory()) {
189             //ignore all CVS directories...
190
if (currentFile.getName()
191                                  .equals("CVS")) {
192                continue;
193             }
194
195             //ok... transverse into this directory and get all the files... then combine
196
//them with the current list.
197
String JavaDoc[] fetchFiles = getFilesFromExtension(currentFileName,
198                                                         extensions);
199             files = blendFilesToVector(files, fetchFiles);
200          } else {
201             //ok... add the file
202
String JavaDoc add = currentFile.getAbsolutePath();
203
204             if (isValidFile(add, extensions)) {
205                files.addElement(add);
206             }
207          }
208       }
209
210       //ok... move the Vector into the files list...
211
String JavaDoc[] foundFiles = new String JavaDoc[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 JavaDoc getPath(final String JavaDoc 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 JavaDoc getPath(final String JavaDoc 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 JavaDoc basename(String JavaDoc 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 JavaDoc basename(String JavaDoc filename,
282                                  String JavaDoc 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; // else returns all (no path and no extension)
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 JavaDoc byteCountToDisplaySize(int size) {
306       String JavaDoc 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 &lt;code>..&lt;/code&gt; will be
324     * properly handled. &lt;p&gt;Eg.,&lt;br /&gt;
325     * &lt;code&gt;/a/b/c&lt;/code&gt; + &lt;code&gt;d&lt;/code&gt; =
326     * &lt;code&gt;/a/b/d&lt;/code&gt;&lt;br /&gt;
327     * &lt;code&gt;/a/b/c&lt;/code&gt; + &lt;code&gt;../d&lt;/code&gt; =
328     * &lt;code&gt;/a/d&lt;/code&gt;&lt;br /&gt; &lt;/p&gt; 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 JavaDoc catPath(final String JavaDoc lookupPath,
337                                 final String JavaDoc path) {
338       // Cut off the last slash and everything beyond
339
int index = lookupPath.lastIndexOf("/");
340       String JavaDoc lookup = lookupPath.substring(0, index);
341       String JavaDoc pth = path;
342
343       // Deal with .. by chopping dirs off the lookup path
344
while (pth.startsWith("../")) {
345          if (lookup.length() > 0) {
346             index = lookup.lastIndexOf("/");
347             lookup = lookup.substring(0, index);
348          } else {
349             // More ..'s than dirs, return null
350
return null;
351          }
352
353          index = pth.indexOf("../") + 3;
354          pth = pth.substring(index);
355       }
356
357       return new StringBuffer JavaDoc(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 JavaDoc directory)
371                               throws IOException JavaDoc {
372       cleanDirectory(new File JavaDoc(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 JavaDoc directory)
384                               throws IOException JavaDoc {
385       if (!directory.exists()) {
386          final String JavaDoc message = directory + " does not exist";
387          throw new IllegalArgumentException JavaDoc(message);
388       }
389
390       if (!directory.isDirectory()) {
391          final String JavaDoc message = directory + " is not a directory";
392          throw new IllegalArgumentException JavaDoc(message);
393       }
394
395       IOException JavaDoc exception = null;
396
397       final File JavaDoc[] files = directory.listFiles();
398
399       for (int i = 0; i < files.length; i++) {
400          final File JavaDoc file = files[i];
401
402          try {
403             forceDelete(file);
404          } catch (final IOException JavaDoc 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 JavaDoc file1,
427                                        final File JavaDoc file2)
428                                 throws IOException JavaDoc {
429       final boolean file1Exists = file1.exists();
430
431       if (file1Exists != file2.exists()) {
432          return false;
433       }
434
435       if (!file1Exists) {
436          // two not existing files are equal
437
return true;
438       }
439
440       if (file1.isDirectory() || file2.isDirectory()) {
441          // don't want to compare directory contents
442
return false;
443       }
444
445       InputStream JavaDoc input1 = null;
446       InputStream JavaDoc input2 = null;
447
448       try {
449          input1 = new FileInputStream JavaDoc(file1);
450          input2 = new FileInputStream JavaDoc(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 JavaDoc source,
475                                final File JavaDoc destination)
476                         throws IOException JavaDoc {
477       //check source exists
478
if (!source.exists()) {
479          final String JavaDoc message = "File " + source + " does not exist";
480          throw new IOException JavaDoc(message);
481       }
482
483       //does destinations directory exist ?
484
if ((destination.getParentFile() != null)
485                 && !destination.getParentFile()
486                                      .exists()) {
487          destination.getParentFile()
488                     .mkdirs();
489       }
490
491       //make sure we can write to destination
492
if (destination.exists() && !destination.canWrite()) {
493          final String JavaDoc message = "Unable to open file " + destination
494                                 + " for writing.";
495          throw new IOException JavaDoc(message);
496       }
497
498       final FileInputStream JavaDoc input = new FileInputStream JavaDoc(source);
499       final FileOutputStream JavaDoc output = new FileOutputStream JavaDoc(destination);
500       IOUtil.copy(input, output);
501       IOUtil.shutdownStream(input);
502       IOUtil.shutdownStream(output);
503
504       if (source.length() != destination.length()) {
505          final String JavaDoc message = "Failed to copy full contents from " + source
506                                 + " to " + destination;
507          throw new IOException JavaDoc(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 JavaDoc source,
526                                           final String JavaDoc destinationDirectory)
527                                    throws IOException JavaDoc {
528       copyFileToDirectory(new File JavaDoc(source), new File JavaDoc(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 JavaDoc source,
546                                           final File JavaDoc destinationDirectory)
547                                    throws IOException JavaDoc {
548       if (destinationDirectory.exists() && !destinationDirectory.isDirectory()) {
549          throw new IllegalArgumentException JavaDoc("Destination is not a directory");
550       }
551
552       copyFile(source, new File JavaDoc(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 JavaDoc source,
571                                     final File JavaDoc destination)
572                              throws IOException JavaDoc {
573       //does destination directory exist ?
574
if ((destination.getParentFile() != null)
575                 && !destination.getParentFile()
576                                      .exists()) {
577          destination.getParentFile()
578                     .mkdirs();
579       }
580
581       //make sure we can write to destination
582
if (destination.exists() && !destination.canWrite()) {
583          final String JavaDoc message = "Unable to open file " + destination
584                                 + " for writing.";
585          throw new IOException JavaDoc(message);
586       }
587
588       final InputStream JavaDoc input = source.openStream();
589       final FileOutputStream JavaDoc output = new FileOutputStream JavaDoc(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 JavaDoc directory)
604                                throws IOException JavaDoc {
605       deleteDirectory(new File JavaDoc(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 JavaDoc directory)
617                                throws IOException JavaDoc {
618       if (!directory.exists()) {
619          return;
620       }
621
622       cleanDirectory(directory);
623
624       if (!directory.delete()) {
625          final String JavaDoc message = "Directory " + directory
626                                 + " unable to be deleted.";
627          throw new IOException JavaDoc(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 JavaDoc dirname(String JavaDoc 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 JavaDoc extension(String JavaDoc 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 JavaDoc inFileName,
679                                String JavaDoc outFileName) throws Exception JavaDoc {
680       String JavaDoc 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 JavaDoc fileName) {
691       File JavaDoc file = new File JavaDoc(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 JavaDoc fileName) {
704       File JavaDoc file = new File JavaDoc(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 JavaDoc fileRead(String JavaDoc fileName) throws IOException JavaDoc {
720       StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
721
722       FileInputStream JavaDoc in = new FileInputStream JavaDoc(fileName);
723
724       try {
725          int count;
726          byte[] b = new byte[512];
727
728          while ((count = in.read(b)) > 0) // blocking read
729
{
730             buf.append(new String JavaDoc(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 JavaDoc fileName,
749                                 String JavaDoc data) throws Exception JavaDoc {
750       FileOutputStream JavaDoc out = new FileOutputStream JavaDoc(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 JavaDoc filename(String JavaDoc 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 JavaDoc file) throws IOException JavaDoc {
783       forceDelete(new File JavaDoc(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 JavaDoc file) throws IOException JavaDoc {
795       if (file.isDirectory()) {
796          deleteDirectory(file);
797       } else {
798          if (!file.delete()) {
799             final String JavaDoc message = "File " + file + " unable to be deleted.";
800             throw new IOException JavaDoc(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 JavaDoc file)
815                                  throws IOException JavaDoc {
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 JavaDoc file) throws IOException JavaDoc {
833       if (file.exists()) {
834          if (file.isFile()) {
835             final String JavaDoc message = "File " + file + " exists and is "
836                                    + "not a directory. Unable to create directory.";
837             throw new IOException JavaDoc(message);
838          }
839       } else {
840          if (false == file.mkdirs()) {
841             final String JavaDoc message = "Unable to create directory " + file;
842             throw new IOException JavaDoc(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 JavaDoc dir) {
854       File JavaDoc file = new File JavaDoc(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 JavaDoc normalize(final String JavaDoc path) {
880       String JavaDoc normalized = path;
881
882       // Resolve occurrences of "//" in the normalized path
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       // Resolve occurrences of "/./" in the normalized path
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       // Resolve occurrences of "/../" in the normalized path
907
while (true) {
908          int index = normalized.indexOf("/../");
909
910          if (index < 0) {
911             break;
912          }
913
914          if (index == 0) {
915             return null; // Trying to go outside our context
916
}
917
918          int index2 = normalized.lastIndexOf('/', index - 1);
919          normalized = normalized.substring(0, index2)
920                       + normalized.substring(index + 3);
921       }
922
923       // Return the normalized path that we have completed
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 JavaDoc removeExtension(final String JavaDoc 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 JavaDoc removePath(final String JavaDoc 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 JavaDoc removePath(final String JavaDoc 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 JavaDoc resolveFile(final File JavaDoc baseFile,
1005                                  String JavaDoc filename) {
1006      String JavaDoc 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      // deal with absolute files
1017
if (filenm.startsWith(File.separator)) {
1018         File JavaDoc file = new File JavaDoc(filenm);
1019
1020         try {
1021            file = file.getCanonicalFile();
1022         } catch (final IOException JavaDoc ioe) {
1023            ;
1024         }
1025
1026         return file;
1027      }
1028
1029      // FIXME: I'm almost certain this // removal is unnecessary, as getAbsoluteFile() strips
1030
// them. However, I'm not sure about this UNC stuff. (JT)
1031
final char[] chars = filename.toCharArray();
1032      final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1033
1034      //remove duplicate file separators in succession - except
1035
//on win32 at start of filename as UNC filenames can
1036
//be \\AComputer\AShare\myfile.txt
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      //must be relative
1056
File JavaDoc file = (new File JavaDoc(baseFile, filenm)).getAbsoluteFile();
1057
1058      try {
1059         file = file.getCanonicalFile();
1060      } catch (final IOException JavaDoc 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 JavaDoc directory) {
1076      return sizeOfDirectory(new File JavaDoc(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 JavaDoc directory) {
1088      if (!directory.exists()) {
1089         final String JavaDoc message = directory + " does not exist";
1090         throw new IllegalArgumentException JavaDoc(message);
1091      }
1092
1093      if (!directory.isDirectory()) {
1094         final String JavaDoc message = directory + " is not a directory";
1095         throw new IllegalArgumentException JavaDoc(message);
1096      }
1097
1098      long size = 0;
1099
1100      final File JavaDoc[] files = directory.listFiles();
1101
1102      for (int i = 0; i < files.length; i++) {
1103         final File JavaDoc 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 JavaDoc toFile(final URL JavaDoc url) {
1125      if (url.getProtocol()
1126                   .equals("file") == false) {
1127         return null;
1128      } else {
1129         final String JavaDoc filename = url.getFile()
1130                                    .replace('/', File.separatorChar);
1131
1132         return new File JavaDoc(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 JavaDoc[] toURLs(final File JavaDoc[] files) throws IOException JavaDoc {
1147      final URL JavaDoc[] urls = new URL JavaDoc[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 JavaDoc fileName,
1166                                 int seconds) {
1167      File JavaDoc file = new File JavaDoc(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 JavaDoc ignore) {
1183            ;
1184         } catch (Exception JavaDoc 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 (&quot;&quot;) 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 JavaDoc file,
1204                                      String JavaDoc[] extensions) {
1205      String JavaDoc extension = extension(file);
1206
1207      if (extension == null) {
1208         extension = "";
1209      }
1210
1211      //ok.. now that we have the "extension" go through the current know
1212
//excepted extensions and determine if this one is OK.
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 JavaDoc blendFilesToVector(Vector JavaDoc v,
1232                                            String JavaDoc[] 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 JavaDoc directory)
1250                                     throws IOException JavaDoc {
1251      if (!directory.exists()) {
1252         final String JavaDoc message = directory + " does not exist";
1253         throw new IllegalArgumentException JavaDoc(message);
1254      }
1255
1256      if (!directory.isDirectory()) {
1257         final String JavaDoc message = directory + " is not a directory";
1258         throw new IllegalArgumentException JavaDoc(message);
1259      }
1260
1261      IOException JavaDoc exception = null;
1262
1263      final File JavaDoc[] files = directory.listFiles();
1264
1265      for (int i = 0; i < files.length; i++) {
1266         final File JavaDoc file = files[i];
1267
1268         try {
1269            forceDeleteOnExit(file);
1270         } catch (final IOException JavaDoc 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 JavaDoc directory)
1289                                      throws IOException JavaDoc {
1290      if (!directory.exists()) {
1291         return;
1292      }
1293
1294      cleanDirectoryOnExit(directory);
1295      directory.deleteOnExit();
1296   }
1297}
1298
Popular Tags