001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.jbi.util;
018    
019    import java.io.BufferedInputStream;
020    import java.io.BufferedOutputStream;
021    import java.io.File;
022    import java.io.FileInputStream;
023    import java.io.FileOutputStream;
024    import java.io.IOException;
025    import java.io.InputStream;
026    import java.io.OutputStream;
027    import java.net.URL;
028    import java.util.Enumeration;
029    import java.util.zip.ZipEntry;
030    import java.util.zip.ZipFile;
031    import java.util.zip.ZipOutputStream;
032    
033    /**
034     * File utilities
035     * 
036     * @version $Revision: 691982 $
037     * @deprecated use {@link org.apache.servicemix.util.FileUtil} instead
038     */
039    public final class FileUtil {
040        
041        /**
042         * Buffer size used when copying the content of an input stream to
043         * an output stream. 
044         */
045        private static final int DEFAULT_BUFFER_SIZE = 4096;
046        
047        private FileUtil() {
048        }
049    
050        /**
051         * Move a File
052         * 
053         * @param src
054         * @param targetDirectory
055         * @throws IOException 
056         */
057        public static void moveFile(File src, File targetDirectory) throws IOException {
058            if (!src.renameTo(new File(targetDirectory, src.getName()))) {
059                throw new IOException("Failed to move " + src + " to " + targetDirectory);
060            }
061        }
062    
063        /**
064         * Build a path- but do not create it
065         * 
066         * @param parent
067         * @param subDirectory
068         * @return a File representing the path
069         */
070        public static File getDirectoryPath(File parent, String subDirectory) {
071            File result = null;
072            if (parent != null) {
073                result = new File(parent, subDirectory);
074            }
075            return result;
076        }
077    
078        /**
079         * Build a directory path - creating directories if neccesary
080         * 
081         * @param file
082         * @return true if the directory exists, or making it was successful
083         */
084        public static boolean buildDirectory(File file) {
085            return file.exists() || file.mkdirs();
086        }
087        
088        /**
089         * Count files in a directory (including files in all subdirectories)
090         * @param directory the directory to start in
091         * @return the total number of files
092         */
093        public static int countFilesInDirectory(File directory) {
094            int count = 0;
095            for (File file : directory.listFiles()) {
096                if (file.isFile()) {
097                    count++;
098                }
099                if (file.isDirectory()) {
100                    count += countFilesInDirectory(file);
101                }
102            }
103            return count;
104        }
105    
106        /**
107         * Copy in stream to an out stream
108         * 
109         * @param in
110         * @param out
111         * @throws IOException
112         */
113        public static void copyInputStream(InputStream in, OutputStream out) throws IOException {
114            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
115            int len = in.read(buffer);
116            while (len >= 0) {
117                out.write(buffer, 0, len);
118                len = in.read(buffer);
119            }
120            in.close();
121            out.close();
122        }
123    
124        /**
125         * Unpack a zip file
126         * 
127         * @param theFile
128         * @param targetDir
129         * @return the file
130         * @throws IOException
131         */
132        public static File unpackArchive(File theFile, File targetDir) throws IOException {
133            if (!theFile.exists()) {
134                throw new IOException(theFile.getAbsolutePath() + " does not exist");
135            }
136            if (!buildDirectory(targetDir)) {
137                throw new IOException("Could not create directory: " + targetDir);
138            }
139            ZipFile zipFile;
140            zipFile = new ZipFile(theFile);
141            for (Enumeration entries = zipFile.entries(); entries.hasMoreElements();) {
142                ZipEntry entry = (ZipEntry) entries.nextElement();
143                File file = new File(targetDir, File.separator + entry.getName());
144                // Take the sledgehammer approach to creating directories
145                // to work around ZIP's that incorrectly miss directories
146                if (!buildDirectory(file.getParentFile())) {
147                    throw new IOException("Could not create directory: " + file.getParentFile());
148                }
149                if (!entry.isDirectory()) {
150                    copyInputStream(zipFile.getInputStream(entry), new BufferedOutputStream(new FileOutputStream(file)));
151                } else {
152                    if (!buildDirectory(file)) {
153                        throw new IOException("Could not create directory: " + file);
154                    }
155                }
156            }
157            zipFile.close();
158            return theFile;
159        }
160    
161        /**
162         * Unpack an archive from a URL
163         * 
164         * @param url
165         * @param targetDir
166         * @return the file to the url
167         * @throws IOException
168         */
169        public static File unpackArchive(URL url, File targetDir) throws IOException {
170            if (!targetDir.exists()) {
171                targetDir.mkdirs();
172            }
173            InputStream in = new BufferedInputStream(url.openStream(), DEFAULT_BUFFER_SIZE);
174            // make sure we get the actual file
175            File zip = File.createTempFile("arc", ".zip", targetDir);
176            OutputStream out = new BufferedOutputStream(new FileOutputStream(zip));
177            copyInputStream(in, out);
178            out.close();
179            return unpackArchive(zip, targetDir);
180        }
181    
182        /**
183         * Validate that an archive contains a named entry
184         * 
185         * @param theFile
186         * @param name
187         * @return true if the entry exists
188         * @throws IOException
189         */
190        public static boolean archiveContainsEntry(File theFile, String name) throws IOException {
191            boolean result = false;
192            ZipFile zipFile;
193            zipFile = new ZipFile(theFile);
194            for (Enumeration entries = zipFile.entries(); entries.hasMoreElements();) {
195                ZipEntry entry = (ZipEntry) entries.nextElement();
196                if (entry.getName().equals(name)) {
197                    result = true;
198                    break;
199                }
200            }
201            zipFile.close();
202            return result;
203        }
204    
205        /**
206         * Create a unique directory within a directory 'root'
207         * 
208         * @param rootDir
209         * @param seed
210         * @return unique directory
211         * @throws IOException
212         */
213        public static synchronized File createUniqueDirectory(File rootDir, String seed) throws IOException {
214            int index = seed.lastIndexOf('.');
215            if (index > 0) {
216                seed = seed.substring(0, index);
217            }
218            File result = null;
219            int count = 0;
220            while (result == null) {
221                String name = seed + "." + count + ".tmp";
222                File file = new File(rootDir, name);
223                if (!file.exists()) {
224                    file.mkdirs();
225                    result = file;
226                }
227                count++;
228            }
229            return result;
230        }
231    
232        /**
233         * Delete a file
234         * 
235         * @param fileToDelete
236         * @return true if the File is deleted
237         */
238        public static boolean deleteFile(File fileToDelete) {
239            if (fileToDelete == null || !fileToDelete.exists()) {
240                return true;
241            }
242            boolean result = true;
243            if (fileToDelete.isDirectory()) {
244                File[] files = fileToDelete.listFiles();
245                if (files == null) {
246                    result = false;
247                } else {
248                    for (int i = 0; i < files.length; i++) {
249                        File file = files[i];
250                        if (file.getName().equals(".") || file.getName().equals("..")) {
251                            continue;
252                        }
253                        if (file.isDirectory()) {
254                            result &= deleteFile(file);
255                        } else {
256                            result &= file.delete();
257                        }
258                    }
259                }
260            }
261            result &= fileToDelete.delete();
262            return result;
263        }
264    
265        /**
266         * Zip up a directory
267         * 
268         * @param directory
269         * @param zipName
270         * @throws IOException
271         */
272        public static void zipDir(String directory, String zipName) throws IOException {
273            // create a ZipOutputStream to zip the data to
274            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipName));
275            String path = "";
276            zipDir(directory, zos, path);
277            // close the stream
278            zos.close();
279        }
280    
281        /**
282         * Zip up a directory path
283         * @param directory
284         * @param zos
285         * @param path
286         * @throws IOException
287         */
288        public static void zipDir(String directory, ZipOutputStream zos, String path) throws IOException {
289            File zipDir = new File(directory);
290            // get a listing of the directory content
291            String[] dirList = zipDir.list();
292            byte[] readBuffer = new byte[2156];
293            int bytesIn = 0;
294            // loop through dirList, and zip the files
295            for (int i = 0; i < dirList.length; i++) {
296                File f = new File(zipDir, dirList[i]);
297                if (f.isDirectory()) {
298                    String filePath = f.getPath();
299                    zipDir(filePath, zos, path + f.getName() + "/");
300                    continue;
301                }
302                FileInputStream fis = new FileInputStream(f);
303                try {
304                    ZipEntry anEntry = new ZipEntry(path + f.getName());
305                    zos.putNextEntry(anEntry);
306                    bytesIn = fis.read(readBuffer);
307                    while (bytesIn != -1) {
308                        zos.write(readBuffer, 0, bytesIn);
309                        bytesIn = fis.read(readBuffer);
310                    }
311                } finally {
312                    fis.close();
313                }
314            }
315        }
316        
317        
318    }