KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > java > plugin > util > IoUtil


1 /*****************************************************************************
2  * Java Plug-in Framework (JPF)
3  * Copyright (C) 2004-2006 Dmitry Olshansky
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *****************************************************************************/

19 package org.java.plugin.util;
20
21 import java.io.BufferedInputStream JavaDoc;
22 import java.io.BufferedOutputStream JavaDoc;
23 import java.io.ByteArrayInputStream JavaDoc;
24 import java.io.ByteArrayOutputStream JavaDoc;
25 import java.io.File JavaDoc;
26 import java.io.FileFilter JavaDoc;
27 import java.io.FileInputStream JavaDoc;
28 import java.io.FileNotFoundException JavaDoc;
29 import java.io.FileOutputStream JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.io.InputStream JavaDoc;
32 import java.io.OutputStream JavaDoc;
33 import java.net.MalformedURLException JavaDoc;
34 import java.net.URL JavaDoc;
35 import java.util.Calendar JavaDoc;
36 import java.util.Date JavaDoc;
37 import java.util.Locale JavaDoc;
38 import java.util.jar.JarFile JavaDoc;
39 import java.util.zip.ZipEntry JavaDoc;
40
41 /**
42  * Input/Output, File and URL/URI related utilities.
43  *
44  * @version $Id: IoUtil.java,v 1.8 2006/10/19 18:41:19 ddimon Exp $
45  */

46 public final class IoUtil {
47     private static final String JavaDoc PACKAGE_NAME = "org.java.plugin.util"; //$NON-NLS-1$
48

49     /**
50      * Copies one file, existing file will be overridden.
51      * @param src source file to copy FROM
52      * @param dest destination file to copy TO
53      * @throws IOException if any I/O error has occurred
54      */

55     public static void copyFile(final File JavaDoc src, final File JavaDoc dest)
56             throws IOException JavaDoc {
57         if (!src.isFile()) {
58             throw new IOException JavaDoc(
59                     ResourceManager.getMessage(PACKAGE_NAME, "notAFile", src)); //$NON-NLS-1$
60
}
61         if (dest.isDirectory()) {
62             throw new IOException JavaDoc(
63                     ResourceManager.getMessage(PACKAGE_NAME, "isFolder", dest)); //$NON-NLS-1$
64
}
65         BufferedInputStream JavaDoc in = new BufferedInputStream JavaDoc(
66                 new FileInputStream JavaDoc(src));
67         try {
68             BufferedOutputStream JavaDoc out = new BufferedOutputStream JavaDoc(
69                     new FileOutputStream JavaDoc(dest, false));
70             try {
71                 copyStream(in, out, 1024);
72             } finally {
73                 out.close();
74             }
75         } finally {
76             in.close();
77         }
78         dest.setLastModified(src.lastModified());
79     }
80
81     /**
82      * Copies folder recursively, existing files will be overridden
83      * @param src source folder
84      * @param dest target folder
85      * @throws IOException if any I/O error has occurred
86      */

87     public static void copyFolder(final File JavaDoc src, final File JavaDoc dest)
88             throws IOException JavaDoc {
89         copyFolder(src, dest, true, false, null);
90     }
91
92     /**
93      * Copies folder, existing files will be overridden
94      * @param src source folder
95      * @param dest target folder
96      * @param reqursive if <code>true</code>, processes folder recursively
97      * @throws IOException if any I/O error has occurred
98      */

99     public static void copyFolder(final File JavaDoc src, final File JavaDoc dest,
100             final boolean reqursive) throws IOException JavaDoc {
101         copyFolder(src, dest, reqursive, false, null);
102     }
103
104
105     /**
106      * Copies folder.
107      * @param src source folder
108      * @param dest target folder
109      * @param reqursive if <code>true</code>, processes folder recursively
110      * @param onlyNew if <code>true</code>, target file will be overridden if it
111      * is older than source file only
112      * @throws IOException if any I/O error has occurred
113      */

114     public static void copyFolder(final File JavaDoc src, final File JavaDoc dest,
115             final boolean reqursive, final boolean onlyNew) throws IOException JavaDoc {
116         copyFolder(src, dest, reqursive, onlyNew, null);
117     }
118     
119     /**
120      * Copies folder.
121      * @param src source folder
122      * @param dest target folder
123      * @param reqursive if <code>true</code>, processes folder recursively
124      * @param onlyNew if <code>true</code>, target file will be overridden if it
125      * is older than source file only
126      * @param filter file filter, optional, if <code>null</code> all files will
127      * be copied
128      * @throws IOException if any I/O error has occurred
129      */

130     public static void copyFolder(final File JavaDoc src, final File JavaDoc dest,
131             final boolean reqursive, final boolean onlyNew,
132             final FileFilter JavaDoc filter) throws IOException JavaDoc {
133         if (!src.isDirectory()) {
134             throw new IOException JavaDoc(
135                     ResourceManager.getMessage(PACKAGE_NAME,
136                             "notAFolder", src)); //$NON-NLS-1$
137
}
138         if (dest.isFile()) {
139             throw new IOException JavaDoc(
140                     ResourceManager.getMessage(PACKAGE_NAME, "isFile", dest)); //$NON-NLS-1$
141
}
142         if (!dest.exists() && !dest.mkdirs()) {
143             throw new IOException JavaDoc(
144                     ResourceManager.getMessage(PACKAGE_NAME,
145                             "cantMakeFolder", dest)); //$NON-NLS-1$
146
}
147         File JavaDoc[] srcFiles = src.listFiles();
148         for (int i = 0; i < srcFiles.length; i++) {
149             File JavaDoc file = srcFiles[i];
150             if ((filter != null) && !filter.accept(file)) {
151                 continue;
152             }
153             if (file.isDirectory()) {
154                 if (reqursive) {
155                     copyFolder(file, new File JavaDoc(dest, file.getName()), reqursive,
156                             onlyNew, filter);
157                 }
158                 continue;
159             }
160             File JavaDoc destFile = new File JavaDoc(dest, file.getName());
161             if (onlyNew && destFile.isFile()
162                     && (destFile.lastModified() > file.lastModified())) {
163                 continue;
164             }
165             copyFile(file, destFile);
166         }
167         dest.setLastModified(src.lastModified());
168     }
169     
170     /**
171      * Copies streams.
172      * @param in source stream
173      * @param out destination stream
174      * @param bufferSize buffer size to use
175      * @throws IOException if any I/O error has occurred
176      */

177     public static void copyStream(final InputStream JavaDoc in, final OutputStream JavaDoc out,
178             final int bufferSize) throws IOException JavaDoc {
179         byte[] buf = new byte[bufferSize];
180         int len;
181         while ((len = in.read(buf)) != -1) {
182             out.write(buf, 0, len);
183         }
184     }
185     
186     /**
187      * Recursively deletes whole content of the given folder.
188      * @param folder folder to be emptied
189      * @return <code>true</code> if given folder becomes empty or not exists
190      */

191     public static boolean emptyFolder(final File JavaDoc folder) {
192         if (!folder.isDirectory()) {
193             return true;
194         }
195         File JavaDoc[] files = folder.listFiles();
196         boolean result = true;
197         for (int i = 0; i < files.length; i++) {
198             File JavaDoc file = files[i];
199             if (file.isDirectory()) {
200                 if (emptyFolder(file)) {
201                     result &= file.delete();
202                 } else {
203                     result = false;
204                 }
205             } else {
206                 result &= file.delete();
207             }
208         }
209         return result;
210     }
211     
212     /**
213      * Compares two files for directories/files synchronization purposes.
214      * @param file1 one file to compare
215      * @param file2 another file to compare
216      * @return <code>true</code> if file names are equal (case sensitive), files
217      * have equal lengths and modification dates (milliseconds ignored)
218      *
219      * @see #synchronizeFolders(File, File)
220      * @see #compareFileDates(Date, Date)
221      */

222     public static boolean compareFiles(final File JavaDoc file1, final File JavaDoc file2) {
223         if (!file1.isFile() || !file2.isFile()) {
224             return false;
225         }
226         if (!file1.getName().equals(file2.getName())) {
227             return false;
228         }
229         if (file1.length() != file2.length()) {
230             return false;
231         }
232         return compareFileDates(new Date JavaDoc(file1.lastModified()),
233                 new Date JavaDoc(file2.lastModified()));
234     }
235     
236     /**
237      * For some reason modification milliseconds for some files are unstable,
238      * use this function to compare file dates ignoring milliseconds.
239      * @param date1 first file modification date
240      * @param date2 second file modification date
241      * @return <code>true</code> if files modification dates are equal ignoring
242      * milliseconds
243      */

244     public static boolean compareFileDates(final Date JavaDoc date1, final Date JavaDoc date2) {
245         if ((date1 == null) || (date2 == null)) {
246             return false;
247         }
248         Calendar JavaDoc cldr = Calendar.getInstance(Locale.ENGLISH);
249         cldr.setTime(date1);
250         cldr.set(Calendar.MILLISECOND, 0);
251         long dt1 = cldr.getTimeInMillis();
252         cldr.setTime(date2);
253         cldr.set(Calendar.MILLISECOND, 0);
254         long dt2 = cldr.getTimeInMillis();
255         return dt1 == dt2;
256     }
257     
258     /**
259      * Performs one-way directories synchronization comparing files only,
260      * not folders.
261      * @param src source folder
262      * @param dest target folder
263      * @throws IOException if any I/O error has occurred
264      *
265      * @see #synchronizeFolders(File, File, FileFilter)
266      * @see #compareFiles(File, File)
267      */

268     public static void synchronizeFolders(final File JavaDoc src, final File JavaDoc dest)
269             throws IOException JavaDoc {
270         synchronizeFolders(src, dest, null);
271     }
272     
273     /**
274      * Performs one-way directories synchronization comparing files only,
275      * not folders.
276      * @param src source folder
277      * @param dest target folder
278      * @param filter file filter, optional, if <code>null</code> all files will
279      * be included into synchronization process
280      * @throws IOException if any I/O error has occurred
281      *
282      * @see #compareFiles(File, File)
283      */

284     public static void synchronizeFolders(final File JavaDoc src, final File JavaDoc dest,
285             final FileFilter JavaDoc filter) throws IOException JavaDoc {
286         if (!src.isDirectory()) {
287             throw new IOException JavaDoc(
288                     ResourceManager.getMessage(PACKAGE_NAME,
289                             "notAFolder", src)); //$NON-NLS-1$
290
}
291         if (dest.isFile()) {
292             throw new IOException JavaDoc(
293                     ResourceManager.getMessage(PACKAGE_NAME, "isFile", dest)); //$NON-NLS-1$
294
}
295         if (!dest.exists() && !dest.mkdirs()) {
296             throw new IOException JavaDoc(
297                     ResourceManager.getMessage(PACKAGE_NAME,
298                             "cantMakeFolder", dest)); //$NON-NLS-1$
299
}
300         File JavaDoc[] srcFiles = src.listFiles();
301         for (int i = 0; i < srcFiles.length; i++) {
302             File JavaDoc srcFile = srcFiles[i];
303             if ((filter != null) && !filter.accept(srcFile)) {
304                 continue;
305             }
306             File JavaDoc destFile = new File JavaDoc(dest, srcFile.getName());
307             if (srcFile.isDirectory()) {
308                 if (destFile.isFile() && !destFile.delete()) {
309                     throw new IOException JavaDoc(
310                             ResourceManager.getMessage(PACKAGE_NAME,
311                                     "cantDeleteFile", destFile)); //$NON-NLS-1$
312
}
313                 synchronizeFolders(srcFile, destFile, filter);
314                 continue;
315             }
316             if (compareFiles(srcFile, destFile)) {
317                 continue;
318             }
319             copyFile(srcFile, destFile);
320         }
321         File JavaDoc[] destFiles = dest.listFiles();
322         for (int i = 0; i < destFiles.length; i++) {
323             File JavaDoc destFile = destFiles[i];
324             File JavaDoc srcFile = new File JavaDoc(src, destFile.getName());
325             if (((filter != null) && filter.accept(destFile) && srcFile.exists())
326                     || ((filter == null) && srcFile.exists())) {
327                 continue;
328             }
329             if (destFile.isDirectory() && !emptyFolder(destFile)) {
330                 throw new IOException JavaDoc(
331                         ResourceManager.getMessage(PACKAGE_NAME,
332                                 "cantEmptyFolder", destFile)); //$NON-NLS-1$
333
}
334             if (!destFile.delete()) {
335                 throw new IOException JavaDoc(
336                         ResourceManager.getMessage(PACKAGE_NAME,
337                                 "cantDeleteFile", destFile)); //$NON-NLS-1$
338
}
339         }
340         dest.setLastModified(src.lastModified());
341     }
342
343     /**
344      * Checks if resource exist and can be opened.
345      * @param url absolute URL which points to a resource to be checked
346      * @return <code>true</code> if given URL points to an existing resource
347      */

348     public static boolean isResourceExists(final URL JavaDoc url) {
349         File JavaDoc file = url2file(url);
350         if (file != null) {
351             return file.canRead();
352         }
353         if ("jar".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
354
return isJarResourceExists(url);
355         }
356         return isUrlResourceExists(url);
357     }
358     
359     private static boolean isUrlResourceExists(final URL JavaDoc url) {
360         try {
361             //url.openConnection().connect();
362
// Patch from Sebastian Kopsan
363
InputStream JavaDoc is = url.openStream();
364             try {
365                 is.close();
366             } catch (IOException JavaDoc ioe) {
367                 // ignore
368
}
369             return true;
370         } catch (IOException JavaDoc ioe) {
371             return false;
372         }
373     }
374     
375     private static boolean isJarResourceExists(final URL JavaDoc url) {
376         try {
377             String JavaDoc urlStr = url.toExternalForm();
378             int p = urlStr.indexOf("!/"); //$NON-NLS-1$
379
if (p == -1) {// this is invalid JAR file URL
380
return false;
381             }
382             URL JavaDoc fileUrl = new URL JavaDoc(urlStr.substring(4, p));
383             File JavaDoc file = url2file(fileUrl);
384             if (file == null) {// this is non-local JAR file URL
385
return isUrlResourceExists(url);
386             }
387             if (!file.canRead()) {
388                 return false;
389             }
390             if (p == urlStr.length() - 2) {// URL points to the root entry of JAR file
391
return true;
392             }
393             JarFile JavaDoc jarFile = new JarFile JavaDoc(file);
394             try {
395                 return jarFile.getEntry(urlStr.substring(p + 2)) != null;
396             } finally {
397                 jarFile.close();
398             }
399         } catch (IOException JavaDoc ioe) {
400             return false;
401         }
402     }
403     
404     /**
405      * Opens input stream for given resource. This method behaves differently
406      * for different URL types:
407      * <ul>
408      * <li>for <b>local files</b> it returns buffered file input stream;</li>
409      * <li>for <b>local JAR files</b> it reads resource content into memory
410      * buffer and returns byte array input stream that wraps those
411      * buffer (this prevents locking JAR file);</li>
412      * <li>for <b>common URL's</b> this method simply opens stream to that URL
413      * using standard URL API.</li>
414      * </ul>
415      * It is not recommended to use this method for big resources within JAR
416      * files.
417      * @param url resource URL
418      * @return input stream for given resource
419      * @throws IOException if any I/O error has occurred
420      */

421     public static InputStream JavaDoc getResourceInputStream(final URL JavaDoc url)
422             throws IOException JavaDoc {
423         File JavaDoc file = url2file(url);
424         if (file != null) {
425             return new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(file));
426         }
427         if (!"jar".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
428
return url.openStream();
429         }
430         String JavaDoc urlStr = url.toExternalForm();
431         if (urlStr.endsWith("!/")) { //$NON-NLS-1$
432
//JAR URL points to a root entry
433
throw new FileNotFoundException JavaDoc(url.toExternalForm());
434         }
435         int p = urlStr.indexOf("!/"); //$NON-NLS-1$
436
if (p == -1) {
437             throw new MalformedURLException JavaDoc(url.toExternalForm());
438         }
439         String JavaDoc path = urlStr.substring(p + 2);
440         file = url2file(new URL JavaDoc(urlStr.substring(4, p)));
441         if (file == null) {// non-local JAR file URL
442
return url.openStream();
443         }
444         JarFile JavaDoc jarFile = new JarFile JavaDoc(file);
445         try {
446             ZipEntry JavaDoc entry = jarFile.getEntry(path);
447             if (entry == null) {
448                 throw new FileNotFoundException JavaDoc(url.toExternalForm());
449             }
450             InputStream JavaDoc in = jarFile.getInputStream(entry);
451             try {
452                 ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
453                 copyStream(in, out, 1024);
454                 return new ByteArrayInputStream JavaDoc(out.toByteArray());
455             } finally {
456                 in.close();
457             }
458         } finally {
459             jarFile.close();
460         }
461     }
462
463     /**
464      * Utility method to convert local URL to a {@link File} object.
465      * @param url an URL
466      * @return file object for given URL or <code>null</code> if URL is not
467      * local
468      */

469     public static File JavaDoc url2file(final URL JavaDoc url) {
470         if (!"file".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
471
return null;
472         }
473         //NB: this may not work correctly in all situations
474
//return new File(url.getPath());
475
// Patch from Wolfgang Ponikwar (po28808) and from Aaron Hamid (aaron)
476
//return new File(url.getPath().replaceAll("%20", " ")); //$NON-NLS-1$ //$NON-NLS-2$
477
return new File JavaDoc(url.getFile().replaceAll("%20", " ")); //$NON-NLS-1$ //$NON-NLS-2$
478
//return new java.io.File(URI.create(url.toExternalForm()));
479
}
480     
481     /**
482      * Utility method to convert a {@link File} object to a local URL.
483      * @param file a file object
484      * @return absolute URL that points to the given file
485      * @throws MalformedURLException if file can't be represented as URL for
486      * some reason
487      */

488     public static URL JavaDoc file2url(final File JavaDoc file) throws MalformedURLException JavaDoc {
489         try {
490             return file.getCanonicalFile().toURI().toURL();
491         } catch (MalformedURLException JavaDoc mue) {
492             throw mue;
493         } catch (IOException JavaDoc ioe) {
494             throw new MalformedURLException JavaDoc(
495                     ResourceManager.getMessage(PACKAGE_NAME, "file2urlFailed", //$NON-NLS-1$
496
new Object JavaDoc[] {file, ioe}));
497         } catch (NoSuchMethodError JavaDoc nsme) {
498             // ignore, seems the JDK version is less than 1.4,
499
// will try another way
500
}
501         try {
502             return new URL JavaDoc("file://" //$NON-NLS-1$
503
+ file.getCanonicalPath().replace('\\', '/')
504                         .replaceAll(" ", "%20")); //$NON-NLS-1$ //$NON-NLS-2$
505
} catch (MalformedURLException JavaDoc mue) {
506             throw mue;
507         } catch (IOException JavaDoc ioe) {
508             throw new MalformedURLException JavaDoc(
509                     ResourceManager.getMessage(PACKAGE_NAME, "file2urlFailed", //$NON-NLS-1$
510
new Object JavaDoc[] {file, ioe}));
511         }
512     }
513
514     private IoUtil() {
515         // no-op
516
}
517 }
518
Popular Tags