1
2
3
4
5
6
7
8
9
10
11 package org.mule.util;
12
13 import org.mule.MuleServer;
14 import org.mule.api.MuleRuntimeException;
15 import org.mule.config.i18n.MessageFactory;
16
17 import java.io.BufferedOutputStream;
18 import java.io.BufferedWriter;
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.FileOutputStream;
22 import java.io.FileWriter;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.io.UnsupportedEncodingException;
27 import java.net.JarURLConnection;
28 import java.net.URI;
29 import java.net.URL;
30 import java.net.URLConnection;
31 import java.net.URLDecoder;
32 import java.nio.channels.FileChannel;
33 import java.util.Enumeration;
34 import java.util.jar.JarEntry;
35 import java.util.jar.JarFile;
36 import java.util.zip.ZipEntry;
37 import java.util.zip.ZipFile;
38
39 import org.apache.commons.lang.StringUtils;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42
43
44
45
46
47
48 public class FileUtils extends org.apache.commons.io.FileUtils
49 {
50 private static final Log logger = LogFactory.getLog(FileUtils.class);
51 public static final String DEFAULT_ENCODING = "UTF-8";
52
53 public static synchronized void copyStreamToFile(InputStream input, File destination) throws IOException
54 {
55 if (destination.exists() && !destination.canWrite())
56 {
57 throw new IOException("Destination file does not exist or is not writeable");
58 }
59
60 try
61 {
62 FileOutputStream output = new FileOutputStream(destination);
63 try
64 {
65 IOUtils.copy(input, output);
66 }
67 finally
68 {
69 IOUtils.closeQuietly(output);
70 }
71 }
72 finally
73 {
74 IOUtils.closeQuietly(input);
75 }
76 }
77
78
79 public static File createFile(String filename) throws IOException
80 {
81 File file = FileUtils.newFile(filename);
82 if (!file.canWrite())
83 {
84 String dirName = file.getPath();
85 int i = dirName.lastIndexOf(File.separator);
86 if (i > -1)
87 {
88 dirName = dirName.substring(0, i);
89 File dir = FileUtils.newFile(dirName);
90 dir.mkdirs();
91 }
92 file.createNewFile();
93 }
94 return file;
95 }
96
97
98 public static String prepareWinFilename(String filename)
99 {
100 filename = filename.replaceAll("<", "(");
101 filename = filename.replaceAll(">", ")");
102 filename = filename.replaceAll("[/\\*?|:;\\]\\[\"]", "-");
103 return filename;
104 }
105
106
107 public static File openDirectory(String directory) throws IOException
108 {
109 File dir = FileUtils.newFile(directory);
110 if (!dir.exists())
111 {
112 dir.mkdirs();
113 }
114 if (!dir.isDirectory() || !dir.canRead())
115 {
116 throw new IOException("Path: " + directory + " exists but isn't a directory");
117 }
118 return dir;
119 }
120
121
122
123
124
125
126
127
128
129 public static File stringToFile(String filename, String data) throws IOException
130 {
131 return stringToFile(filename, data, false);
132 }
133
134
135 public static synchronized File stringToFile(String filename, String data, boolean append)
136 throws IOException
137 {
138 return stringToFile(filename, data, append, false);
139 }
140
141
142 public static synchronized File stringToFile(String filename, String data, boolean append, boolean newLine)
143 throws IOException
144 {
145 File f = createFile(filename);
146 BufferedWriter writer = null;
147 try
148 {
149 writer = new BufferedWriter(new FileWriter(f, append));
150 writer.write(data);
151 if (newLine)
152 {
153 writer.newLine();
154 }
155 }
156 finally
157 {
158 if (writer != null)
159 {
160 writer.close();
161 }
162 }
163 return f;
164 }
165
166
167 public static String getResourcePath(String resourceName, Class callingClass) throws IOException
168 {
169 return getResourcePath(resourceName, callingClass, DEFAULT_ENCODING);
170 }
171
172
173 public static String getResourcePath(String resourceName, Class callingClass, String encoding)
174 throws IOException
175 {
176 if (resourceName == null)
177 {
178
179 return null;
180 }
181
182 URL url = IOUtils.getResourceAsUrl(resourceName, callingClass);
183 if (url == null)
184 {
185
186 return null;
187 }
188 return normalizeFilePath(url, encoding);
189 }
190
191
192
193
194
195
196
197
198
199
200 public static String normalizeFilePath(URL url, String encoding) throws UnsupportedEncodingException
201 {
202 String resource = URLDecoder.decode(url.toExternalForm(), encoding);
203 if (resource != null)
204 {
205 if (resource.startsWith("file:/"))
206 {
207 resource = resource.substring(6);
208 }
209 if (!resource.startsWith(File.separator))
210 {
211 resource = File.separator + resource;
212 }
213 }
214 return resource;
215 }
216
217
218
219
220
221
222
223 public static boolean deleteTree(File dir)
224 {
225 return deleteTree(dir, null);
226 }
227
228
229
230
231
232
233
234
235
236
237
238 public static boolean deleteTree(File dir, final String[] topLevelDirsToIgnore)
239 {
240 if (dir == null || !dir.exists())
241 {
242 return true;
243 }
244 File[] files = dir.listFiles();
245 if (files != null)
246 {
247 for (int i = 0; i < files.length; i++)
248 {
249 OUTER:
250 if (files[i].isDirectory())
251 {
252 if (topLevelDirsToIgnore != null)
253 {
254 for (int j = 0; j < topLevelDirsToIgnore.length; j++)
255 {
256 String ignored = topLevelDirsToIgnore[j];
257 if (ignored.equals(FilenameUtils.getBaseName(files[i].getName())))
258 {
259 break OUTER;
260 }
261 }
262 }
263 if (!deleteTree(files[i]))
264 {
265 return false;
266 }
267 }
268 else
269 {
270 if (!files[i].delete())
271 {
272 return false;
273 }
274 }
275 }
276 }
277 return dir.delete();
278 }
279
280
281
282
283 public static void unzip(File archive, File directory) throws IOException
284 {
285 ZipFile zip = null;
286
287 if (directory.exists())
288 {
289 if (!directory.isDirectory())
290 {
291 throw new IOException("Directory is not a directory: " + directory);
292 }
293 }
294 else
295 {
296 if (!directory.mkdirs())
297 {
298 throw new IOException("Could not create directory: " + directory);
299 }
300 }
301 try
302 {
303 zip = new ZipFile(archive);
304 for (Enumeration entries = zip.entries(); entries.hasMoreElements();)
305 {
306 ZipEntry entry = (ZipEntry) entries.nextElement();
307 File f = FileUtils.newFile(directory, entry.getName());
308 if (entry.isDirectory())
309 {
310 if (!f.mkdirs())
311 {
312 throw new IOException("Could not create directory: " + f);
313 }
314 }
315 else
316 {
317 InputStream is = zip.getInputStream(entry);
318 OutputStream os = new BufferedOutputStream(new FileOutputStream(f));
319 IOUtils.copy(is, os);
320 IOUtils.closeQuietly(is);
321 IOUtils.closeQuietly(os);
322 }
323 }
324 }
325 finally
326 {
327 if (zip != null)
328 {
329 zip.close();
330 }
331 }
332 }
333
334
335
336
337
338
339
340
341
342
343
344 public static File newFile(String pathName)
345 {
346 try
347 {
348 return new File(pathName).getCanonicalFile();
349 }
350 catch (IOException e)
351 {
352 throw new MuleRuntimeException(
353 MessageFactory.createStaticMessage("Unable to create a canonical file for " + pathName),
354 e);
355 }
356 }
357
358
359
360
361
362
363
364
365
366
367
368 public static File newFile(URI uri)
369 {
370 try
371 {
372 return new File(uri).getCanonicalFile();
373 }
374 catch (IOException e)
375 {
376 throw new MuleRuntimeException(
377 MessageFactory.createStaticMessage("Unable to create a canonical file for " + uri),
378 e);
379 }
380 }
381
382
383
384
385
386
387
388
389
390
391
392 public static File newFile(File parent, String child)
393 {
394 try
395 {
396 return new File(parent, child).getCanonicalFile();
397 }
398 catch (IOException e)
399 {
400 throw new MuleRuntimeException(
401 MessageFactory.createStaticMessage("Unable to create a canonical file for parent: "
402 + parent + " and child: " + child),
403 e);
404 }
405 }
406
407
408
409
410
411
412
413
414
415
416
417 public static File newFile(String parent, String child)
418 {
419 try
420 {
421 return new File(parent, child).getCanonicalFile();
422 }
423 catch (IOException e)
424 {
425 throw new MuleRuntimeException(
426 MessageFactory.createStaticMessage("Unable to create a canonical file for parent: "
427 + parent + " and child: " + child),
428 e);
429 }
430 }
431
432
433
434
435
436
437
438
439
440
441
442 public static void extractResources(String resourceName, Class callingClass, File outputDir, boolean keepParentDirectory) throws IOException
443 {
444 URL url = callingClass.getClassLoader().getResource(resourceName);
445 URLConnection connection = url.openConnection();
446 if (connection instanceof JarURLConnection)
447 {
448 extractJarResources((JarURLConnection) connection, outputDir, keepParentDirectory);
449 }
450 else
451 {
452 extractFileResources(normalizeFilePath(url,
453 MuleServer.getMuleContext().getConfiguration().getDefaultEncoding()),
454 outputDir, resourceName, keepParentDirectory);
455 }
456 }
457
458
459
460
461
462
463
464
465
466
467 private static void extractFileResources(String path, File outputDir, String resourceName, boolean keepParentDirectory) throws IOException
468 {
469 File file = FileUtils.newFile(path);
470 if (!file.exists())
471 {
472 throw new IOException("The resource by path " + path + " ");
473 }
474 if (file.isDirectory())
475 {
476 if (keepParentDirectory)
477 {
478 outputDir = FileUtils.newFile(outputDir.getPath() + File.separator + resourceName);
479 if (!outputDir.exists())
480 {
481 outputDir.mkdirs();
482 }
483 }
484 else
485 {
486 outputDir = FileUtils.newFile(outputDir.getPath());
487 }
488 copyDirectory(file, outputDir);
489 }
490 else
491 {
492
493 if (keepParentDirectory)
494 {
495 outputDir = FileUtils.newFile(outputDir.getPath() + File.separator + resourceName);
496 }
497 else
498 {
499 outputDir = FileUtils.newFile(outputDir.getPath() + File.separator + file.getName());
500 }
501 copyFile(file, outputDir);
502 }
503 }
504
505
506
507
508
509
510
511
512
513 private static void extractJarResources(JarURLConnection connection, File outputDir, boolean keepParentDirectory) throws IOException
514 {
515 JarFile jarFile = connection.getJarFile();
516 JarEntry jarResource = connection.getJarEntry();
517 Enumeration entries = jarFile.entries();
518 InputStream inputStream = null;
519 OutputStream outputStream = null;
520 int jarResourceNameLenght = jarResource.getName().length();
521 for (; entries.hasMoreElements();)
522 {
523 JarEntry entry = (JarEntry) entries.nextElement();
524 if (entry.getName().startsWith(jarResource.getName()))
525 {
526
527 String path = outputDir.getPath() + File.separator + entry.getName();
528
529
530 if (!keepParentDirectory)
531 {
532 if (entry.isDirectory())
533 {
534 if (entry.getName().equals(jarResource.getName()))
535 {
536 continue;
537 }
538 path = outputDir.getPath() + File.separator + entry.getName().substring(jarResourceNameLenght, entry.getName().length());
539 }
540 else
541 {
542 if (entry.getName().length() > jarResourceNameLenght)
543 {
544 path = outputDir.getPath() + File.separator + entry.getName().substring(jarResourceNameLenght, entry.getName().length());
545 }
546 else
547 {
548 path = outputDir.getPath() + File.separator + entry.getName().substring(entry.getName().lastIndexOf("/"), entry.getName().length());
549 }
550 }
551 }
552
553 File file = FileUtils.newFile(path);
554 if (!file.getParentFile().exists())
555 {
556 if (!file.getParentFile().mkdirs())
557 {
558 throw new IOException("Could not create directory: " + file.getParentFile());
559 }
560 }
561 if (entry.isDirectory())
562 {
563 if (!file.exists() && !file.mkdirs())
564 {
565 throw new IOException("Could not create directory: " + file);
566 }
567
568 }
569 else
570 {
571 try
572 {
573 inputStream = jarFile.getInputStream(entry);
574 outputStream = new BufferedOutputStream(new FileOutputStream(file));
575 IOUtils.copy(inputStream, outputStream);
576 }
577 finally
578 {
579 IOUtils.closeQuietly(inputStream);
580 IOUtils.closeQuietly(outputStream);
581 }
582 }
583
584 }
585 }
586 }
587
588 public static boolean renameFileHard(String srcFilePath, String destFilePath)
589 {
590 if (StringUtils.isNotBlank(srcFilePath) && StringUtils.isNotBlank(destFilePath))
591 {
592 return renameFileHard(new File(srcFilePath), new File(destFilePath));
593 }
594 else
595 {
596 return false;
597 }
598 }
599
600 public static boolean renameFileHard(File srcFile, File destFile)
601 {
602 boolean isRenamed = false;
603 if (srcFile != null && destFile != null)
604 {
605 logger.debug("Moving file " + srcFile.getAbsolutePath() + " to " + destFile.getAbsolutePath());
606 if (!destFile.exists())
607 {
608 try
609 {
610 if (srcFile.isFile())
611 {
612 logger.debug("Trying to rename file");
613 FileInputStream in = null;
614 FileOutputStream out = null;
615 try
616 {
617 in = new FileInputStream(srcFile);
618 out = new FileOutputStream(destFile);
619 out.getChannel().transferFrom(in.getChannel(), 0, srcFile.length());
620 isRenamed = true;
621 }
622 catch (Exception e)
623 {
624 logger.debug(e);
625 }
626 finally
627 {
628 if (in != null)
629 {
630 try
631 {
632 in.close();
633 }
634 catch (Exception inNotClosed)
635 {
636 logger.debug(inNotClosed);
637 }
638 }
639 if (out != null)
640 {
641 try
642 {
643 out.close();
644 }
645 catch (Exception outNotClosed)
646 {
647 logger.debug(outNotClosed);
648 }
649 }
650 }
651 logger.debug("File renamed: " + isRenamed);
652 if (isRenamed)
653 {
654 srcFile.delete();
655 }
656 else
657 {
658 destFile.delete();
659 }
660 }
661 else
662 {
663 logger.debug(srcFile.getAbsolutePath() + " is not a valid file.");
664 }
665 }
666 catch (Exception e)
667 {
668 logger.debug("Error renaming file from " + srcFile.getAbsolutePath() + " to " + destFile.getAbsolutePath());
669 }
670 }
671 else
672 {
673 logger.debug("Error renaming file " + srcFile.getAbsolutePath() + ". Destination file " + destFile.getAbsolutePath() + " already exists.");
674 }
675 }
676 return isRenamed;
677 }
678
679 public static boolean renameFile(String srcFilePath, String destFilePath)
680 {
681 if (StringUtils.isNotBlank(srcFilePath) && StringUtils.isNotBlank(destFilePath))
682 {
683 return renameFile(new File(srcFilePath), new File(destFilePath));
684 }
685 else
686 {
687 return false;
688 }
689 }
690
691 public static boolean renameFile(File srcFile, File destFile)
692 {
693 boolean isRenamed = false;
694 if (srcFile != null && destFile != null)
695 {
696 logger.debug("Moving file " + srcFile.getAbsolutePath() + " to " + destFile.getAbsolutePath());
697 if (!destFile.exists())
698 {
699 try
700 {
701 if (srcFile.isFile())
702 {
703 logger.debug("Trying to rename file");
704 isRenamed = srcFile.renameTo(destFile);
705 if (!isRenamed && srcFile.exists())
706 {
707 logger.debug("Trying hard copy, assuming partition crossing ...");
708 isRenamed = renameFileHard(srcFile, destFile);
709 }
710 logger.debug("File renamed: " + isRenamed);
711 }
712 else
713 {
714 logger.debug(srcFile.getAbsolutePath() + " is not a valid file");
715 }
716 }
717 catch (Exception e)
718 {
719 logger.debug("Error moving file from " + srcFile.getAbsolutePath() + " to " + destFile.getAbsolutePath(), e);
720 }
721 }
722 else
723 {
724 logger.debug("Error renaming file " + srcFile.getAbsolutePath() + ". Destination file " + destFile.getAbsolutePath() + " already exists.");
725 }
726 }
727 else
728 {
729 logger.debug("Error renaming file. Source or destination file is null.");
730 }
731
732 return isRenamed;
733 }
734
735
736 public static boolean moveFile(File sourceFile, File destinationFile)
737 {
738
739 boolean success = sourceFile.renameTo(destinationFile);
740
741 if (!success)
742 {
743
744 FileInputStream fis = null;
745 FileOutputStream fos = null;
746 try
747 {
748 fis = new FileInputStream(sourceFile);
749 fos = new FileOutputStream(destinationFile);
750 FileChannel srcChannel = fis.getChannel();
751 FileChannel dstChannel = fos.getChannel();
752 dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
753 srcChannel.close();
754 dstChannel.close();
755 success = sourceFile.delete();
756 }
757 catch (IOException ioex)
758 {
759
760 success = false;
761 }
762 finally
763 {
764 IOUtils.closeQuietly(fis);
765 IOUtils.closeQuietly(fos);
766 }
767 }
768
769 return success;
770 }
771
772 }