001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 2005 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: FileUtils.java 7563 2005-10-21 15:35:39Z durieuxp $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas_lib.files;
025:
026: import java.io.File;
027: import java.io.FileInputStream;
028: import java.io.FileOutputStream;
029: import java.io.IOException;
030: import java.io.InputStream;
031: import java.nio.channels.FileChannel;
032: import java.util.Enumeration;
033: import java.util.jar.JarEntry;
034: import java.util.jar.JarFile;
035:
036: import org.objectweb.jonas.common.Log;
037:
038: import org.objectweb.util.monolog.api.BasicLevel;
039: import org.objectweb.util.monolog.api.Logger;
040:
041: /**
042: * This class manages operation done many times by JOnAS on files, like copying
043: * them.
044: * @author Florent Benoit
045: */
046: public class FileUtils {
047:
048: /**
049: * Size of the buffer.
050: */
051: private static final int BUFFER_SIZE = 2048;
052:
053: /**
054: * Logger
055: */
056: private static Logger logger = Log.getLogger(FileUtils.class
057: .getName());
058:
059: /**
060: * Utility class, no public constructor
061: */
062: private FileUtils() {
063:
064: }
065:
066: /**
067: * Unpack the source archive in a given directory and returns directory
068: * directory created.
069: * @param packedJar source JarFile to be unpacked
070: * @param dest the destination folder
071: * @throws FileUtilsException When unpack fails
072: */
073: public static void unpack(JarFile packedJar, File dest)
074: throws FileUtilsException {
075:
076: JarEntry entry = null;
077:
078: // get entries of the jar file
079: Enumeration entries = packedJar.entries();
080: while (entries.hasMoreElements()) {
081: entry = (JarEntry) entries.nextElement();
082:
083: // File entry
084: File entryFile = new File(dest, entry.getName());
085:
086: // Create directory
087: if (entry.isDirectory()) {
088: if (!entryFile.exists()) {
089: // create parent directories (with mkdirs)
090: if (!entryFile.mkdirs()) {
091: String err = "Can not create directory "
092: + entryFile
093: + ", Check the write access.";
094: throw new FileUtilsException(err);
095: }
096: }
097: continue;
098: }
099:
100: // If it's a file, we must extract the file
101: // Ensure that the directory exists.
102: entryFile.getParentFile().mkdirs();
103:
104: InputStream is = null;
105: // get the input stream
106: try {
107: is = packedJar.getInputStream(entry);
108: // Dump to the file
109: dump(is, entryFile);
110: } catch (IOException ioe) {
111: throw new FileUtilsException(
112: "Cannot get inputstream of entry '" + entry
113: + "' of file '" + packedJar + "'.");
114: } finally {
115: try {
116: is.close();
117: } catch (IOException ioe) {
118: if (logger.isLoggable(BasicLevel.DEBUG)) {
119: logger.log(BasicLevel.DEBUG,
120: "Cannot close input stream", ioe);
121: }
122: }
123: }
124:
125: }
126: }
127:
128: /**
129: * Write the given input stream in the given file.
130: * @param in the inputStream to copy.
131: * @param entryFile the file where the inputStream must be dumped.
132: * @throws FileUtilsException if the dump failed.
133: */
134: private static void dump(InputStream in, File entryFile)
135: throws FileUtilsException {
136:
137: try {
138: //File output
139: FileOutputStream out = new FileOutputStream(entryFile);
140: int n = 0;
141: try {
142: //buffer
143: byte[] buffer = new byte[BUFFER_SIZE];
144: n = in.read(buffer);
145: while (n > 0) {
146: out.write(buffer, 0, n);
147: n = in.read(buffer);
148: }
149: } finally {
150: out.close();
151: }
152: } catch (IOException e) {
153: String err = "Error while unpacking entry " + entryFile
154: + " : ";
155: throw new FileUtilsException(err, e);
156: }
157: }
158:
159: /**
160: * Copy a file
161: * @param src source file
162: * @param dest dest file
163: * @throws FileUtilsException if the copy of the file failed
164: */
165: public static void copyFile(String src, String dest)
166: throws FileUtilsException {
167: copyFile(new File(src), new File(dest));
168: }
169:
170: /**
171: * Copy a file
172: * @param src source file
173: * @param dest dest file
174: * @throws FileUtilsException if the copy of the file failed
175: */
176: public static void copyFile(File src, File dest)
177: throws FileUtilsException {
178:
179: if (dest.isDirectory()) {
180: if (logger.isLoggable(BasicLevel.DEBUG)) {
181: logger
182: .log(BasicLevel.DEBUG,
183: "Copy a file to a directory, append source filename to directory.");
184: }
185: dest = new File(dest, src.getName());
186: }
187:
188: FileInputStream fIn = null;
189: FileOutputStream fOut = null;
190: FileChannel fcIn = null;
191: FileChannel fcOut = null;
192: try {
193:
194: // InputStream
195: fIn = new FileInputStream(src);
196: fOut = new FileOutputStream(dest);
197:
198: // nio channel
199: FileChannel sourceFC = fIn.getChannel();
200: FileChannel targetFC = fOut.getChannel();
201:
202: targetFC.transferFrom(sourceFC, 0, sourceFC.size());
203: } catch (Exception e) {
204: throw new FileUtilsException("Error during copy file : "
205: + src + " -> " + dest, e);
206: } finally {
207: try {
208: fOut.close();
209: fIn.close();
210: fcOut.close();
211: fcIn.close();
212: } catch (Exception e) {
213: if (logger.isLoggable(BasicLevel.DEBUG)) {
214: logger.log(BasicLevel.DEBUG,
215: "Cannot close some i/o which are open.", e);
216: }
217: }
218:
219: }
220: }
221:
222: /**
223: * @param path file/directory to be deleted
224: * @return true if deletion was OK
225: */
226: public static boolean delete(String path) {
227: return delete(new File(path));
228: }
229:
230: /**
231: * @param f file/directory to be deleted
232: * @return true if deletion was OK
233: */
234: public static boolean delete(File f) {
235: if (f.isFile()) {
236: return f.delete();
237: } else {
238: File[] childs = f.listFiles();
239: if (childs == null) {
240: // no childs
241: return f.delete();
242: } else {
243: // childs
244: boolean result = true;
245: for (int i = 0; i < childs.length; i++) {
246: result &= delete(childs[i]);
247: }
248: return result && f.delete();
249: }
250: }
251:
252: }
253:
254: /**
255: * Copy a directory recursively
256: * @param src source directory
257: * @param dest dest directory
258: * @throws FileUtilsException if the copy of the directory failed
259: */
260: public static void copyDirectory(String src, String dest)
261: throws FileUtilsException {
262: copyDirectory(new File(src), new File(dest));
263: }
264:
265: /**
266: * Copy a directory recursively
267: * @param src source directory
268: * @param dest dest directory
269: * @throws FileUtilsException if the copy of the directory failed
270: */
271: public static void copyDirectory(File src, File dest)
272: throws FileUtilsException {
273:
274: if (!src.isDirectory()) {
275: // We don not accept file arguments !
276: throw new IllegalArgumentException("Source '" + src
277: + "' must be a directory");
278: }
279:
280: // create the destination directory if it is inexistant
281: if (!dest.exists()) {
282: dest.mkdirs();
283: }
284:
285: // copy the files of the source directory
286: File[] childs = src.listFiles();
287: if (childs != null) {
288: // childs
289: for (int i = 0; i < childs.length; i++) {
290: File child = childs[i];
291: if (child.isFile()) {
292: // file
293: copyFile(child, dest);
294: } else {
295: // directory
296: copyDirectory(child,
297: new File(dest, child.getName()));
298: }
299: }
300: }
301: }
302:
303: /**
304: * return a list of files with this suffix in directory dstr
305: */
306: public static String[] getFileList(File dir, String prefix,
307: String suffix) {
308: return dir.list(new DirFilter(prefix, suffix));
309: }
310:
311: }
|