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