Add .tox/ to .gitignore
[odlparent.git] / karaf / karaf-maven-plugin / src / main / java / org / apache / karaf / tooling / utils / IoUtils.java
1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  * <p/>
9  * http://www.apache.org/licenses/LICENSE-2.0
10  * <p/>
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package org.apache.karaf.tooling.utils;
18
19 import java.io.*;
20 import java.nio.channels.FileChannel;
21
22 public class IoUtils {
23
24     private static final long FILE_COPY_BUFFER_SIZE = 1024 * 30;
25
26     public static void deleteRecursive(File file) {
27         if (file != null) {
28             if (file.isDirectory()) {
29                 File[] children = file.listFiles();
30                 if (children != null) {
31                     for (File child : children) {
32                         deleteRecursive(child);
33                     }
34                 }
35             }
36             file.delete();
37         }
38     }
39
40     public static void copyDirectory(final File srcDir, final File destDir) throws IOException {
41         if (srcDir == null || !srcDir.exists())
42             return;
43         if (destDir == null || !destDir.exists())
44             destDir.mkdirs();
45         // recurse
46         final File[] srcFiles = srcDir.listFiles();
47         if (srcFiles == null) {  // null if abstract pathname does not denote a directory, or if an I/O error occurs
48             throw new IOException("Failed to list contents of " + srcDir);
49         }
50         if (destDir.exists()) {
51             if (destDir.isDirectory() == false) {
52                 throw new IOException("Destination '" + destDir + "' exists but is not a directory");
53             }
54         } else {
55             if (!destDir.mkdirs() && !destDir.isDirectory()) {
56                 throw new IOException("Destination '" + destDir + "' directory cannot be created");
57             }
58         }
59         if (destDir.canWrite() == false) {
60             throw new IOException("Destination '" + destDir + "' cannot be written to");
61         }
62         for (final File srcFile : srcFiles) {
63             final File dstFile = new File(destDir, srcFile.getName());
64             if (srcFile.isDirectory()) {
65                 copyDirectory(srcFile, dstFile);
66             } else {
67                 copyFile(srcFile, dstFile);
68             }
69         }
70     }
71
72     public static void copyFile(final File srcFile, final File destFile) throws IOException {
73         if (destFile.exists() && destFile.isDirectory()) {
74             throw new IOException("Destination '" + destFile + "' exists but is a directory");
75         }
76
77         FileInputStream fis = null;
78         FileOutputStream fos = null;
79         FileChannel input = null;
80         FileChannel output = null;
81         try {
82             fis = new FileInputStream(srcFile);
83             fos = new FileOutputStream(destFile);
84             input  = fis.getChannel();
85             output = fos.getChannel();
86             final long size = input.size(); // TODO See IO-386
87             long pos = 0;
88             long count = 0;
89             while (pos < size) {
90                 final long remain = size - pos;
91                 count = remain > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : remain;
92                 final long bytesCopied = output.transferFrom(input, pos, count);
93                 if (bytesCopied == 0) { // IO-385 - can happen if file is truncated after caching the size
94                     break; // ensure we don't loop forever
95                 }
96                 pos += bytesCopied;
97             }
98         } finally {
99             if (output != null) {
100                 try { output.close(); } catch (Exception e) { }
101             }
102             if (fos != null) {
103                 try { fos.close(); } catch (Exception e) { }
104             }
105             if (input != null) {
106                 try { input.close(); } catch (Exception e) { }
107             }
108             if (fis != null) {
109                 try { fis.close(); } catch (Exception e) { }
110             }
111         }
112
113         final long srcLen = srcFile.length(); // TODO See IO-386
114         final long dstLen = destFile.length(); // TODO See IO-386
115         if (srcLen != dstLen) {
116             throw new IOException("Failed to copy full contents from '" +
117                     srcFile + "' to '" + destFile + "' Expected length: " + srcLen +" Actual: " + dstLen);
118         }
119     }
120
121 }