Coverage Report - org.mule.util.FileUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
FileUtils
0%
0/293
0%
0/168
5.172
 
 1  
 /*
 2  
  * $Id: FileUtils.java 19191 2010-08-25 21:05:23Z tcarlson $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.util;
 12  
 
 13  
 import org.mule.api.MuleRuntimeException;
 14  
 import org.mule.config.i18n.MessageFactory;
 15  
 
 16  
 import java.io.BufferedOutputStream;
 17  
 import java.io.BufferedWriter;
 18  
 import java.io.File;
 19  
 import java.io.FileInputStream;
 20  
 import java.io.FileNotFoundException;
 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.Channel;
 33  
 import java.nio.channels.FileChannel;
 34  
 import java.util.Enumeration;
 35  
 import java.util.jar.JarEntry;
 36  
 import java.util.jar.JarFile;
 37  
 import java.util.zip.ZipEntry;
 38  
 import java.util.zip.ZipFile;
 39  
 
 40  
 import org.apache.commons.lang.StringUtils;
 41  
 import org.apache.commons.logging.Log;
 42  
 import org.apache.commons.logging.LogFactory;
 43  
 
 44  
 /**
 45  
  * <code>FileUtils</code> contains useful methods for dealing with files &
 46  
  * directories.
 47  
  */
 48  
 // @ThreadSafe
 49  0
 public class FileUtils extends org.apache.commons.io.FileUtils
 50  
 {
 51  0
     private static final Log logger = LogFactory.getLog(FileUtils.class);
 52  0
     public static String DEFAULT_ENCODING = "UTF-8";
 53  
     
 54  
     public static synchronized void copyStreamToFile(InputStream input, File destination) throws IOException
 55  
     {
 56  0
         if (destination.exists() && !destination.canWrite())
 57  
         {
 58  0
             throw new IOException("Destination file does not exist or is not writeable");
 59  
         }
 60  
 
 61  
         try
 62  
         {
 63  0
             FileOutputStream output = new FileOutputStream(destination);
 64  
             try
 65  
             {
 66  0
                 IOUtils.copy(input, output);
 67  
             }
 68  
             finally
 69  
             {
 70  0
                 IOUtils.closeQuietly(output);
 71  0
             }
 72  
         }
 73  
         finally
 74  
         {
 75  0
             IOUtils.closeQuietly(input);
 76  0
         }
 77  0
     }
 78  
 
 79  
     // TODO Document me!
 80  
     public static File createFile(String filename) throws IOException
 81  
     {
 82  0
         File file = FileUtils.newFile(filename);
 83  0
         if (!file.canWrite())
 84  
         {
 85  0
             String dirName = file.getPath();
 86  0
             int i = dirName.lastIndexOf(File.separator);
 87  0
             if (i > -1)
 88  
             {
 89  0
                 dirName = dirName.substring(0, i);
 90  0
                 File dir = FileUtils.newFile(dirName);
 91  0
                 dir.mkdirs();
 92  
             }
 93  0
             file.createNewFile();
 94  
         }
 95  0
         return file;
 96  
     }
 97  
 
 98  
     // TODO Document me!
 99  
     public static String prepareWinFilename(String filename)
 100  
     {
 101  0
         filename = filename.replaceAll("<", "(");
 102  0
         filename = filename.replaceAll(">", ")");
 103  0
         filename = filename.replaceAll("[/\\*?|:;\\]\\[\"]", "-");
 104  0
         return filename;
 105  
     }
 106  
 
 107  
     // TODO Document me!
 108  
     public static File openDirectory(String directory) throws IOException
 109  
     {
 110  0
         File dir = FileUtils.newFile(directory);
 111  0
         if (!dir.exists())
 112  
         {
 113  0
             dir.mkdirs();
 114  
         }
 115  0
         if (!dir.isDirectory() || !dir.canRead())
 116  
         {
 117  0
             throw new IOException("Path: " + directory + " exists but isn't a directory");
 118  
         }
 119  0
         return dir;
 120  
     }
 121  
 
 122  
     /**
 123  
      * Reads the incoming String into a file at at the given destination.
 124  
      *
 125  
      * @param filename name and path of the file to create
 126  
      * @param data     the contents of the file
 127  
      * @return the new file.
 128  
      * @throws IOException If the creating or writing to the file stream fails
 129  
      */
 130  
     public static File stringToFile(String filename, String data) throws IOException
 131  
     {
 132  0
         return stringToFile(filename, data, false);
 133  
     }
 134  
 
 135  
     // TODO Document me!
 136  
     public static synchronized File stringToFile(String filename, String data, boolean append)
 137  
             throws IOException
 138  
     {
 139  0
         return stringToFile(filename, data, append, false);
 140  
     }
 141  
 
 142  
     // TODO Document me!
 143  
     public static synchronized File stringToFile(String filename, String data, boolean append, boolean newLine)
 144  
             throws IOException
 145  
     {
 146  0
         File f = createFile(filename);
 147  0
         BufferedWriter writer = null;
 148  
         try
 149  
         {
 150  0
             writer = new BufferedWriter(new FileWriter(f, append));
 151  0
             writer.write(data);
 152  0
             if (newLine)
 153  
             {
 154  0
                 writer.newLine();
 155  
             }
 156  
         }
 157  
         finally
 158  
         {
 159  0
             if (writer != null)
 160  
             {
 161  0
                 writer.close();
 162  
             }
 163  
         }
 164  0
         return f;
 165  
     }
 166  
 
 167  
     // TODO Document me!
 168  
     public static String getResourcePath(String resourceName, Class callingClass) throws IOException
 169  
     {
 170  0
         return getResourcePath(resourceName, callingClass, DEFAULT_ENCODING);
 171  
     }
 172  
 
 173  
     // TODO Document me!
 174  
     public static String getResourcePath(String resourceName, Class callingClass, String encoding)
 175  
             throws IOException
 176  
     {
 177  0
         if (resourceName == null)
 178  
         {
 179  
             // no name
 180  0
             return null;
 181  
         }
 182  
 
 183  0
         URL url = IOUtils.getResourceAsUrl(resourceName, callingClass);
 184  0
         if (url == null)
 185  
         {
 186  
             // not found
 187  0
             return null;
 188  
         }
 189  0
         return normalizeFilePath(url, encoding);
 190  
     }
 191  
 
 192  
     /**
 193  
      * Remove from uri to file prefix file:/
 194  
      * Add if need file separator to begin
 195  
      *
 196  
      * @param url      file uri to resource
 197  
      * @param encoding - Java encoding names
 198  
      * @return normalized file path
 199  
      * @throws UnsupportedEncodingException if encoding is unknown
 200  
      */
 201  
     public static String normalizeFilePath(URL url, String encoding) throws UnsupportedEncodingException
 202  
     {
 203  0
         String resource = URLDecoder.decode(url.toExternalForm(), encoding);
 204  0
         if (resource != null)
 205  
         {
 206  0
             if (resource.startsWith("file:/"))
 207  
             {
 208  0
                 resource = resource.substring(6);
 209  
 
 210  0
                 if (!resource.startsWith(File.separator))
 211  
                 {
 212  0
                     resource = File.separator + resource;
 213  
                 }
 214  
             }
 215  
         }
 216  0
         return resource;
 217  
     }
 218  
 
 219  
 
 220  
     /**
 221  
      * Delete a file tree recursively.
 222  
      * @param dir dir to wipe out
 223  
      * @return false when the first unsuccessful attempt encountered
 224  
      */
 225  
     public static boolean deleteTree(File dir)
 226  
     {
 227  0
         return deleteTree(dir, null);
 228  
     }
 229  
 
 230  
     /**
 231  
      * Delete a file tree recursively. This method additionally tries to be
 232  
      * gentle with specified top-level dirs. E.g. this is the case when a
 233  
      * transaction manager asynchronously handles the recovery log, and the test
 234  
      * wipes out everything, leaving the transaction manager puzzled.  
 235  
      * @param dir dir to wipe out
 236  
      * @param topLevelDirsToIgnore which top-level directories to ignore,
 237  
      *        if null or empty then ignored
 238  
      * @return false when the first unsuccessful attempt encountered
 239  
      */
 240  
     public static boolean deleteTree(File dir, final String[] topLevelDirsToIgnore)
 241  
     {
 242  0
         if (dir == null || !dir.exists())
 243  
         {
 244  0
             return true;
 245  
         }
 246  0
         File[] files = dir.listFiles();
 247  0
         if (files != null)
 248  
         {
 249  0
             for (int i = 0; i < files.length; i++)
 250  
             {
 251  
                 OUTER:
 252  0
                 if (files[i].isDirectory())
 253  
                 {
 254  0
                     if (topLevelDirsToIgnore != null)
 255  
                     {
 256  0
                         for (int j = 0; j < topLevelDirsToIgnore.length; j++)
 257  
                         {
 258  0
                             String ignored = topLevelDirsToIgnore[j];
 259  0
                             if (ignored.equals(FilenameUtils.getBaseName(files[i].getName())))
 260  
                             {
 261  0
                                 break OUTER;
 262  
                             }
 263  
                         }
 264  
                     }
 265  0
                     if (!deleteTree(files[i]))
 266  
                     {
 267  0
                         return false;
 268  
                     }
 269  
                 }
 270  
                 else
 271  
                 {
 272  0
                     if (!files[i].delete())
 273  
                     {
 274  0
                         return false;
 275  
                     }
 276  
                 }
 277  
             }
 278  
         }
 279  0
         return dir.delete();
 280  
     }
 281  
 
 282  
     /**
 283  
      * Unzip the specified archive to the given directory
 284  
      */
 285  
     public static void unzip(File archive, File directory) throws IOException
 286  
     {
 287  0
         ZipFile zip = null;
 288  
 
 289  0
         if (directory.exists())
 290  
         {
 291  0
             if (!directory.isDirectory())
 292  
             {
 293  0
                 throw new IOException("Directory is not a directory: " + directory);
 294  
             }
 295  
         }
 296  
         else
 297  
         {
 298  0
             if (!directory.mkdirs())
 299  
             {
 300  0
                 throw new IOException("Could not create directory: " + directory);
 301  
             }
 302  
         }
 303  
         try
 304  
         {
 305  0
             zip = new ZipFile(archive);
 306  0
             for (Enumeration entries = zip.entries(); entries.hasMoreElements();)
 307  
             {
 308  0
                 ZipEntry entry = (ZipEntry) entries.nextElement();
 309  0
                 File f = FileUtils.newFile(directory, entry.getName());
 310  0
                 if (entry.isDirectory())
 311  
                 {
 312  0
                     if (!f.mkdirs())
 313  
                     {
 314  0
                         throw new IOException("Could not create directory: " + f);
 315  
                     }
 316  
                 }
 317  
                 else
 318  
                 {
 319  0
                     InputStream is = zip.getInputStream(entry);
 320  0
                     OutputStream os = new BufferedOutputStream(new FileOutputStream(f));
 321  0
                     IOUtils.copy(is, os);
 322  0
                     IOUtils.closeQuietly(is);
 323  0
                     IOUtils.closeQuietly(os);
 324  
                 }
 325  0
             }
 326  
         }
 327  
         finally
 328  
         {
 329  0
             if (zip != null)
 330  
             {
 331  0
                 zip.close();
 332  
             }
 333  
         }
 334  0
     }
 335  
 
 336  
     /**
 337  
      * Workaround for JDK bug <a href="http://bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4117557">
 338  
      * 4117557</a>. More in-context information at
 339  
      * <a href="http://mule.mulesoft.org/jira/browse/MULE-1112">MULE-1112</a>
 340  
      * <p/>
 341  
      * Factory methods correspond to constructors of the <code>java.io.File class</code>.
 342  
      * No physical file created in this method.
 343  
      *
 344  
      * @see File
 345  
      */
 346  
     public static File newFile(String pathName)
 347  
     {
 348  
         try
 349  
         {
 350  0
             return new File(pathName).getCanonicalFile();
 351  
         }
 352  0
         catch (IOException e)
 353  
         {
 354  0
             throw new MuleRuntimeException(
 355  
                     MessageFactory.createStaticMessage("Unable to create a canonical file for " + pathName),
 356  
                     e);
 357  
         }
 358  
     }
 359  
 
 360  
     /**
 361  
      * Workaround for JDK bug <a href="http://bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4117557">
 362  
      * 4117557</a>. More in-context information at
 363  
      * <a href="http://mule.mulesoft.org/jira/browse/MULE-1112">MULE-1112</a>
 364  
      * <p/>
 365  
      * Factory methods correspond to constructors of the <code>java.io.File class</code>.
 366  
      * No physical file created in this method.
 367  
      *
 368  
      * @see File
 369  
      */
 370  
     public static File newFile(URI uri)
 371  
     {
 372  
         try
 373  
         {
 374  0
             return new File(uri).getCanonicalFile();
 375  
         }
 376  0
         catch (IOException e)
 377  
         {
 378  0
             throw new MuleRuntimeException(
 379  
                     MessageFactory.createStaticMessage("Unable to create a canonical file for " + uri),
 380  
                     e);
 381  
         }
 382  
     }
 383  
 
 384  
     /**
 385  
      * Workaround for JDK bug <a href="http://bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4117557">
 386  
      * 4117557</a>. More in-context information at
 387  
      * <a href="http://mule.mulesoft.org/jira/browse/MULE-1112">MULE-1112</a>
 388  
      * <p/>
 389  
      * Factory methods correspond to constructors of the <code>java.io.File class</code>.
 390  
      * No physical file created in this method.
 391  
      *
 392  
      * @see File
 393  
      */
 394  
     public static File newFile(File parent, String child)
 395  
     {
 396  
         try
 397  
         {
 398  0
             return new File(parent, child).getCanonicalFile();
 399  
         }
 400  0
         catch (IOException e)
 401  
         {
 402  0
             throw new MuleRuntimeException(
 403  
                     MessageFactory.createStaticMessage("Unable to create a canonical file for parent: "
 404  
                             + parent + " and child: " + child),
 405  
                     e);
 406  
         }
 407  
     }
 408  
 
 409  
     /**
 410  
      * Workaround for JDK bug <a href="http://bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4117557">
 411  
      * 4117557</a>. More in-context information at
 412  
      * <a href="http://mule.mulesoft.org/jira/browse/MULE-1112">MULE-1112</a>
 413  
      * <p/>
 414  
      * Factory methods correspond to constructors of the <code>java.io.File class</code>.
 415  
      * No physical file created in this method.
 416  
      *
 417  
      * @see File
 418  
      */
 419  
     public static File newFile(String parent, String child)
 420  
     {
 421  
         try
 422  
         {
 423  0
             return new File(parent, child).getCanonicalFile();
 424  
         }
 425  0
         catch (IOException e)
 426  
         {
 427  0
             throw new MuleRuntimeException(
 428  
                     MessageFactory.createStaticMessage("Unable to create a canonical file for parent: "
 429  
                             + parent + " and child: " + child),
 430  
                     e);
 431  
         }
 432  
     }
 433  
 
 434  
     /**
 435  
      * Extract the specified resource to the given directory for
 436  
      * remain all directory struct
 437  
      *
 438  
      * @param resourceName        - full resource name
 439  
      * @param callingClass        - classloader for this class is used
 440  
      * @param outputDir           - extract to this directory
 441  
      * @param keepParentDirectory true -  full structure of directories is kept; false - file - removed all directories, directory - started from resource point
 442  
      * @throws IOException if any errors
 443  
      */
 444  
     public static void extractResources(String resourceName, Class callingClass, File outputDir, boolean keepParentDirectory) throws IOException
 445  
     {
 446  0
         URL url = callingClass.getClassLoader().getResource(resourceName);
 447  0
         URLConnection connection = url.openConnection();
 448  0
         if (connection instanceof JarURLConnection)
 449  
         {
 450  0
             extractJarResources((JarURLConnection) connection, outputDir, keepParentDirectory);
 451  
         }
 452  
         else
 453  
         {
 454  0
             extractFileResources(normalizeFilePath(url, DEFAULT_ENCODING),
 455  
                                                    outputDir, resourceName, keepParentDirectory);
 456  
         }
 457  0
     }
 458  
 
 459  
     /**
 460  
      * Extract resources contain in file
 461  
      *
 462  
      * @param path                - path to file
 463  
      * @param outputDir           Directory for unpack recources
 464  
      * @param resourceName
 465  
      * @param keepParentDirectory true -  full structure of directories is kept; false - file - removed all directories, directory - started from resource point
 466  
      * @throws IOException if any error
 467  
      */
 468  
     private static void extractFileResources(String path, File outputDir, String resourceName, boolean keepParentDirectory) throws IOException
 469  
     {
 470  0
         File file = FileUtils.newFile(path);
 471  0
         if (!file.exists())
 472  
         {
 473  0
             throw new IOException("The resource by path " + path + " ");
 474  
         }
 475  0
         if (file.isDirectory())
 476  
         {
 477  0
             if (keepParentDirectory)
 478  
             {
 479  0
                 outputDir = FileUtils.newFile(outputDir.getPath() + File.separator + resourceName);
 480  0
                 if (!outputDir.exists())
 481  
                 {
 482  0
                     outputDir.mkdirs();
 483  
                 }
 484  
             }
 485  
             else
 486  
             {
 487  0
                 outputDir = FileUtils.newFile(outputDir.getPath());
 488  
             }
 489  0
             copyDirectory(file, outputDir);
 490  
         }
 491  
         else
 492  
         {
 493  
 
 494  0
             if (keepParentDirectory)
 495  
             {
 496  0
                 outputDir = FileUtils.newFile(outputDir.getPath() + File.separator + resourceName);
 497  
             }
 498  
             else
 499  
             {
 500  0
                 outputDir = FileUtils.newFile(outputDir.getPath() + File.separator + file.getName());
 501  
             }
 502  0
             copyFile(file, outputDir);
 503  
         }
 504  0
     }
 505  
 
 506  
     /**
 507  
      * Extract recources contain if jar (have to in classpath)
 508  
      *
 509  
      * @param connection          JarURLConnection to jar library
 510  
      * @param outputDir           Directory for unpack recources
 511  
      * @param keepParentDirectory true -  full structure of directories is kept; false - file - removed all directories, directory - started from resource point
 512  
      * @throws IOException if any error
 513  
      */
 514  
     private static void extractJarResources(JarURLConnection connection, File outputDir, boolean keepParentDirectory) throws IOException
 515  
     {
 516  0
         JarFile jarFile = connection.getJarFile();
 517  0
         JarEntry jarResource = connection.getJarEntry();
 518  0
         Enumeration entries = jarFile.entries();
 519  0
         InputStream inputStream = null;
 520  0
         OutputStream outputStream = null;
 521  0
         int jarResourceNameLenght = jarResource.getName().length();
 522  0
         for (; entries.hasMoreElements();)
 523  
         {
 524  0
             JarEntry entry = (JarEntry) entries.nextElement();
 525  0
             if (entry.getName().startsWith(jarResource.getName()))
 526  
             {
 527  
 
 528  0
                 String path = outputDir.getPath() + File.separator + entry.getName();
 529  
 
 530  
                 //remove directory struct for file and first dir for directory
 531  0
                 if (!keepParentDirectory)
 532  
                 {
 533  0
                     if (entry.isDirectory())
 534  
                     {
 535  0
                         if (entry.getName().equals(jarResource.getName()))
 536  
                         {
 537  0
                             continue;
 538  
                         }
 539  0
                         path = outputDir.getPath() + File.separator + entry.getName().substring(jarResourceNameLenght, entry.getName().length());
 540  
                     }
 541  
                     else
 542  
                     {
 543  0
                         if (entry.getName().length() > jarResourceNameLenght)
 544  
                         {
 545  0
                             path = outputDir.getPath() + File.separator + entry.getName().substring(jarResourceNameLenght, entry.getName().length());
 546  
                         }
 547  
                         else
 548  
                         {
 549  0
                             path = outputDir.getPath() + File.separator + entry.getName().substring(entry.getName().lastIndexOf("/"), entry.getName().length());
 550  
                         }
 551  
                     }
 552  
                 }
 553  
 
 554  0
                 File file = FileUtils.newFile(path);
 555  0
                 if (!file.getParentFile().exists())
 556  
                 {
 557  0
                     if (!file.getParentFile().mkdirs())
 558  
                     {
 559  0
                         throw new IOException("Could not create directory: " + file.getParentFile());
 560  
                     }
 561  
                 }
 562  0
                 if (entry.isDirectory())
 563  
                 {
 564  0
                     if (!file.exists() && !file.mkdirs())
 565  
                     {
 566  0
                         throw new IOException("Could not create directory: " + file);
 567  
                     }
 568  
 
 569  
                 }
 570  
                 else
 571  
                 {
 572  
                     try
 573  
                     {
 574  0
                         inputStream = jarFile.getInputStream(entry);
 575  0
                         outputStream = new BufferedOutputStream(new FileOutputStream(file));
 576  0
                         IOUtils.copy(inputStream, outputStream);
 577  
                     }
 578  
                     finally
 579  
                     {
 580  0
                         IOUtils.closeQuietly(inputStream);
 581  0
                         IOUtils.closeQuietly(outputStream);
 582  0
                     }
 583  
                 }
 584  
 
 585  
             }
 586  0
         }
 587  0
     }
 588  
 
 589  
     public static boolean renameFileHard(String srcFilePath, String destFilePath)
 590  
     {
 591  0
         if (StringUtils.isNotBlank(srcFilePath) && StringUtils.isNotBlank(destFilePath))
 592  
         {
 593  0
             return renameFileHard(new File(srcFilePath), new File(destFilePath));
 594  
         }
 595  
         else
 596  
         {
 597  0
             return false;
 598  
         }
 599  
     }
 600  
     
 601  
     public static boolean renameFileHard(File srcFile, File destFile)
 602  
     {
 603  0
         boolean isRenamed = false;
 604  0
         if (srcFile != null && destFile != null)
 605  
         {
 606  0
             logger.debug("Moving file " + srcFile.getAbsolutePath() + " to " + destFile.getAbsolutePath());
 607  0
             if (!destFile.exists())
 608  
             {
 609  
                 try
 610  
                 {
 611  0
                     if (srcFile.isFile())
 612  
                     {
 613  0
                         logger.debug("Trying to rename file");
 614  0
                         FileInputStream in = null;
 615  0
                         FileOutputStream out = null;
 616  
                         try
 617  
                         {
 618  0
                             in = new FileInputStream(srcFile);
 619  0
                             out = new FileOutputStream(destFile);
 620  0
                             out.getChannel().transferFrom(in.getChannel(), 0, srcFile.length());
 621  0
                             isRenamed = true;
 622  
                         }
 623  0
                         catch (Exception e)
 624  
                         {
 625  0
                             logger.debug(e);
 626  
                         }
 627  
                         finally
 628  
                         {
 629  0
                             if (in != null)
 630  
                             {
 631  
                                 try
 632  
                                 {
 633  0
                                     in.close();
 634  
                                 }
 635  0
                                 catch (Exception inNotClosed)
 636  
                                 {
 637  0
                                     logger.debug(inNotClosed);
 638  0
                                 }
 639  
                             }
 640  0
                             if (out != null)
 641  
                             {
 642  
                                 try
 643  
                                 {
 644  0
                                     out.close();
 645  
                                 }
 646  0
                                 catch (Exception outNotClosed)
 647  
                                 {
 648  0
                                     logger.debug(outNotClosed);
 649  0
                                 }
 650  
                             }
 651  
                         }
 652  0
                         logger.debug("File renamed: " + isRenamed);
 653  0
                         if (isRenamed)
 654  
                         {
 655  0
                             srcFile.delete();
 656  
                         }
 657  
                         else
 658  
                         {
 659  0
                             destFile.delete();
 660  
                         }
 661  0
                     }
 662  
                     else
 663  
                     {
 664  0
                         logger.debug(srcFile.getAbsolutePath() + " is not a valid file.");
 665  
                     }
 666  
                 }
 667  0
                 catch (Exception e)
 668  
                 {
 669  0
                     logger.debug("Error renaming file from " + srcFile.getAbsolutePath() + " to " + destFile.getAbsolutePath());
 670  0
                 }
 671  
             }
 672  
             else
 673  
             {
 674  0
                 logger.debug("Error renaming file " + srcFile.getAbsolutePath() + ". Destination file " + destFile.getAbsolutePath() + " already exists.");
 675  
             }
 676  
         }
 677  0
         return isRenamed;
 678  
     }
 679  
 
 680  
     public static boolean renameFile(String srcFilePath, String destFilePath)
 681  
     {
 682  0
         if (StringUtils.isNotBlank(srcFilePath) && StringUtils.isNotBlank(destFilePath))
 683  
         {
 684  0
             return renameFile(new File(srcFilePath), new File(destFilePath));
 685  
         }
 686  
         else
 687  
         {
 688  0
             return false;
 689  
         }
 690  
     }
 691  
     
 692  
     public static boolean renameFile(File srcFile, File destFile)
 693  
     {
 694  0
         boolean isRenamed = false;
 695  0
         if (srcFile != null && destFile != null)
 696  
         {
 697  0
             logger.debug("Moving file " + srcFile.getAbsolutePath() + " to " + destFile.getAbsolutePath());
 698  0
             if (!destFile.exists())
 699  
             {
 700  
                 try
 701  
                 {
 702  0
                     if (srcFile.isFile())
 703  
                     {
 704  0
                         logger.debug("Trying to rename file");
 705  0
                         isRenamed = srcFile.renameTo(destFile);
 706  0
                         if (!isRenamed && srcFile.exists())
 707  
                         {
 708  0
                             logger.debug("Trying hard copy, assuming partition crossing ...");
 709  0
                             isRenamed = renameFileHard(srcFile, destFile);
 710  
                         }
 711  0
                         logger.debug("File renamed: " + isRenamed);
 712  
                     }
 713  
                     else
 714  
                     {
 715  0
                         logger.debug(srcFile.getAbsolutePath() + " is not a valid file");
 716  
                     }
 717  
                 }
 718  0
                 catch (Exception e)
 719  
                 {
 720  0
                     logger.debug("Error moving file from " + srcFile.getAbsolutePath() + " to " + destFile.getAbsolutePath(), e);
 721  0
                 }
 722  
             }
 723  
             else
 724  
             {
 725  0
                 logger.debug("Error renaming file " + srcFile.getAbsolutePath() + ". Destination file " + destFile.getAbsolutePath() + " already exists.");
 726  
             }
 727  
         }
 728  
         else
 729  
         {
 730  0
             logger.debug("Error renaming file. Source or destination file is null.");
 731  
         }
 732  
     
 733  0
         return isRenamed;
 734  
     }
 735  
     
 736  
     /** 
 737  
      * Try to move a file by renaming with backup attempt by copying/deleting via NIO 
 738  
      */
 739  
     public static boolean moveFileWithCopyFallback(File sourceFile, File destinationFile)
 740  
     {
 741  
         // try fast file-system-level move/rename first
 742  0
         boolean success = sourceFile.renameTo(destinationFile);
 743  
 
 744  0
         if (!success)
 745  
         {
 746  
             // try again using NIO copy
 747  0
             FileInputStream fis = null;
 748  0
             FileOutputStream fos = null;
 749  
             try
 750  
             {
 751  0
                 fis = new FileInputStream(sourceFile);
 752  0
                 fos = new FileOutputStream(destinationFile);
 753  0
                 FileChannel srcChannel = fis.getChannel();
 754  0
                 FileChannel dstChannel = fos.getChannel();
 755  0
                 dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
 756  0
                 srcChannel.close();
 757  0
                 dstChannel.close();
 758  0
                 success = sourceFile.delete();
 759  
             }
 760  0
             catch (IOException ioex)
 761  
             {
 762  
                 // grr!
 763  0
                 success = false;
 764  
             }
 765  
             finally
 766  
             {
 767  0
                 IOUtils.closeQuietly(fis);
 768  0
                 IOUtils.closeQuietly(fos);
 769  0
             }
 770  
         }
 771  
 
 772  0
         return success;
 773  
     }
 774  
 
 775  
     
 776  
     /**
 777  
      * Copy in file to out file
 778  
      * 
 779  
      * Don't use java.nio as READ_ONLY memory mapped files cannot be deleted
 780  
      * 
 781  
      * @param in
 782  
      * @param out
 783  
      */
 784  
     public static void safeCopyFile(File in, File out) throws IOException
 785  
     {
 786  
         try
 787  
         {
 788  0
             FileInputStream fis = new FileInputStream(in);
 789  0
             FileOutputStream fos = new FileOutputStream(out);
 790  
             try
 791  
             {
 792  0
                 byte[] buf = new byte[1024];
 793  0
                 int i = 0;
 794  0
                 while ((i = fis.read(buf)) != -1)
 795  
                 {
 796  0
                     fos.write(buf, 0, i);
 797  
                 }
 798  
             }
 799  0
             catch (IOException e)
 800  
             {
 801  0
                 throw e;
 802  
             }
 803  
             finally
 804  
             {
 805  0
                 try
 806  
                 {
 807  0
                     if (fis != null) fis.close();
 808  0
                     if (fos != null) fos.close();
 809  
                 }
 810  0
                 catch (IOException e)
 811  
                 {
 812  0
                     throw e;
 813  0
                 }
 814  
 
 815  
             }
 816  
         }
 817  0
         catch (FileNotFoundException e)
 818  
         {
 819  0
             throw e;
 820  0
         }
 821  0
     }
 822  
     
 823  
     // Override the following methods to use a new version of doCopyFile(File
 824  
     // srcFile, File destFile, boolean preserveFileDate) that uses nio to copy file
 825  
 
 826  
     /**
 827  
      * Copies a file to a new location.
 828  
      * <p>
 829  
      * This method copies the contents of the specified source file to the specified
 830  
      * destination file. The directory holding the destination file is created if it
 831  
      * does not exist. If the destination file exists, then this method will
 832  
      * overwrite it.
 833  
      * 
 834  
      * @param srcFile an existing file to copy, must not be <code>null</code>
 835  
      * @param destFile the new file, must not be <code>null</code>
 836  
      * @param preserveFileDate true if the file date of the copy should be the same
 837  
      *            as the original
 838  
      * @throws NullPointerException if source or destination is <code>null</code>
 839  
      * @throws IOException if source or destination is invalid
 840  
      * @throws IOException if an IO error occurs during copying
 841  
      * @see #copyFileToDirectory(File, File, boolean)
 842  
      */
 843  
     public static void copyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException
 844  
     {
 845  0
         if (srcFile == null)
 846  
         {
 847  0
             throw new NullPointerException("Source must not be null");
 848  
         }
 849  0
         if (destFile == null)
 850  
         {
 851  0
             throw new NullPointerException("Destination must not be null");
 852  
         }
 853  0
         if (srcFile.exists() == false)
 854  
         {
 855  0
             throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
 856  
         }
 857  0
         if (srcFile.isDirectory())
 858  
         {
 859  0
             throw new IOException("Source '" + srcFile + "' exists but is a directory");
 860  
         }
 861  0
         if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath()))
 862  
         {
 863  0
             throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same");
 864  
         }
 865  0
         if (destFile.getParentFile() != null && destFile.getParentFile().exists() == false)
 866  
         {
 867  0
             if (destFile.getParentFile().mkdirs() == false)
 868  
             {
 869  0
                 throw new IOException("Destination '" + destFile + "' directory cannot be created");
 870  
             }
 871  
         }
 872  0
         if (destFile.exists() && destFile.canWrite() == false)
 873  
         {
 874  0
             throw new IOException("Destination '" + destFile + "' exists but is read-only");
 875  
         }
 876  0
         doCopyFile(srcFile, destFile, preserveFileDate);
 877  0
     }
 878  
 
 879  
     /**
 880  
      * Internal copy file method.
 881  
      * 
 882  
      * @param srcFile the validated source file, must not be <code>null</code>
 883  
      * @param destFile the validated destination file, must not be <code>null</code>
 884  
      * @param preserveFileDate whether to preserve the file date
 885  
      * @throws IOException if an error occurs
 886  
      */
 887  
     private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException
 888  
     {
 889  0
         if (destFile.exists() && destFile.isDirectory())
 890  
         {
 891  0
             throw new IOException("Destination '" + destFile + "' exists but is a directory");
 892  
         }
 893  
 
 894  0
         FileChannel input = new FileInputStream(srcFile).getChannel();
 895  
         try
 896  
         {
 897  0
             FileChannel output = new FileOutputStream(destFile).getChannel();
 898  
             try
 899  
             {
 900  0
                 output.transferFrom(input, 0, input.size());
 901  
             }
 902  
             finally
 903  
             {
 904  0
                 closeQuietly(output);
 905  0
             }
 906  
         }
 907  
         finally
 908  
         {
 909  0
             closeQuietly(input);
 910  0
         }
 911  
 
 912  0
         if (srcFile.length() != destFile.length())
 913  
         {
 914  0
             throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + "'");
 915  
         }
 916  0
         if (preserveFileDate)
 917  
         {
 918  0
             destFile.setLastModified(srcFile.lastModified());
 919  
         }
 920  0
     }
 921  
 
 922  
     /**
 923  
      * Unconditionally close a <code>Channel</code>.
 924  
      * <p>
 925  
      * Equivalent to {@link Channel#close()}, except any exceptions will be ignored.
 926  
      * This is typically used in finally blocks.
 927  
      * 
 928  
      * @param channel the Channel to close, may be null or already closed
 929  
      */
 930  
     public static void closeQuietly(Channel channel)
 931  
     {
 932  
         try
 933  
         {
 934  0
             if (channel != null)
 935  
             {
 936  0
                 channel.close();
 937  
             }
 938  
         }
 939  0
         catch (IOException ioe)
 940  
         {
 941  
             // ignore
 942  0
         }
 943  0
     }
 944  
 }