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: */package org.apache.geronimo.kernel.config;
017:
018: import java.io.File;
019: import java.io.FileInputStream;
020: import java.io.FileOutputStream;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.OutputStream;
024: import java.io.Reader;
025: import java.io.Writer;
026: import java.net.MalformedURLException;
027: import java.net.URL;
028: import java.util.Collections;
029: import java.util.Enumeration;
030: import java.util.HashMap;
031: import java.util.LinkedHashMap;
032: import java.util.LinkedHashSet;
033: import java.util.Map;
034: import java.util.Set;
035: import java.util.jar.JarFile;
036: import java.util.zip.ZipEntry;
037:
038: import org.apache.commons.logging.Log;
039: import org.apache.commons.logging.LogFactory;
040:
041: /**
042: * @version $Rev: 627659 $ $Date: 2008-02-13 20:23:33 -0800 (Wed, 13 Feb 2008) $
043: */
044: public class IOUtil {
045: private final static Log log = LogFactory.getLog(IOUtil.class);
046:
047: public static void recursiveCopy(File srcDir, File destDir)
048: throws IOException {
049: if (srcDir == null)
050: throw new NullPointerException("sourceDir is null");
051: if (destDir == null)
052: throw new NullPointerException("destDir is null");
053: if (!srcDir.isDirectory() || !srcDir.canRead()) {
054: throw new IllegalArgumentException(
055: "Source directory must be a readable directory "
056: + srcDir);
057: }
058: if (destDir.exists()) {
059: throw new IllegalArgumentException(
060: "Destination directory already exists " + destDir);
061: }
062: if (srcDir.equals(destDir)) {
063: throw new IllegalArgumentException(
064: "Source and destination directory are the same "
065: + srcDir);
066: }
067:
068: destDir.mkdirs();
069: if (!destDir.exists()) {
070: throw new IOException(
071: "Could not create destination directory " + destDir);
072: }
073:
074: File[] srcFiles = srcDir.listFiles();
075: if (srcFiles != null) {
076: for (int i = 0; i < srcFiles.length; i++) {
077: File srcFile = srcFiles[i];
078: File destFile = new File(destDir, srcFile.getName());
079: if (srcFile.isDirectory()) {
080: recursiveCopy(srcFile, destFile);
081: } else {
082: copyFile(srcFile, destFile);
083: }
084: }
085: }
086: }
087:
088: public static void copyFile(File source, File destination)
089: throws IOException {
090: File destinationDir = destination.getParentFile();
091: if (!destinationDir.exists() && !destinationDir.mkdirs()) {
092: throw new IOException("Cannot create directory : "
093: + destinationDir);
094: }
095:
096: InputStream in = null;
097: OutputStream out = null;
098: try {
099: in = new FileInputStream(source);
100: out = new FileOutputStream(destination);
101: writeAll(in, out);
102: } finally {
103: close(in);
104: close(out);
105: }
106: }
107:
108: public static void writeAll(InputStream in, OutputStream out)
109: throws IOException {
110: byte[] buffer = new byte[4096];
111: int count;
112: while ((count = in.read(buffer)) > 0) {
113: out.write(buffer, 0, count);
114: }
115: out.flush();
116: }
117:
118: private static void listFiles(File directory) {
119: if (!log.isDebugEnabled() || !directory.isDirectory()) {
120: return;
121: }
122: File[] files = directory.listFiles();
123: log.debug(directory.getPath() + " has " + files.length
124: + " files:");
125: for (File file : files) {
126: log.debug(file.getPath());
127: }
128: }
129:
130: private static boolean deleteFile(File file) {
131: boolean fileDeleted = file.delete();
132: if (fileDeleted) {
133: return true;
134: }
135:
136: // special retry code to handle occasional Windows JDK and Unix NFS timing failures
137: int retryLimit = 5;
138: int retries;
139: int interruptions = 0;
140: for (retries = 1; !fileDeleted && retries <= retryLimit; retries++) {
141: if (log.isDebugEnabled()) {
142: listFiles(file);
143: }
144: System.runFinalization();
145: try {
146: Thread.sleep(1000);
147: } catch (InterruptedException ie) {
148: interruptions++;
149: }
150: System.gc();
151: try {
152: Thread.sleep(1000);
153: } catch (InterruptedException ie) {
154: interruptions++;
155: }
156: fileDeleted = file.delete();
157: }
158: if (fileDeleted) {
159: if (log.isDebugEnabled()) {
160: log.debug(file.getPath() + " deleted after " + retries
161: + " retries, with " + interruptions
162: + " interruptions.");
163: }
164: } else {
165: log.warn(file.getPath() + " not deleted after "
166: + retryLimit + " retries, with " + interruptions
167: + " interruptions.");
168: }
169: return fileDeleted;
170: }
171:
172: public static boolean recursiveDelete(File root) {
173: if (root == null) {
174: return true;
175: }
176:
177: if (root.isDirectory()) {
178: File[] files = root.listFiles();
179: if (files != null) {
180: for (int i = 0; i < files.length; i++) {
181: File file = files[i];
182: if (file.isDirectory()) {
183: recursiveDelete(file);
184: } else {
185: deleteFile(file);
186: }
187: }
188: }
189: }
190: return deleteFile(root);
191: }
192:
193: public static void flush(OutputStream thing) {
194: if (thing != null) {
195: try {
196: thing.flush();
197: } catch (Exception ignored) {
198: }
199: }
200: }
201:
202: public static void flush(Writer thing) {
203: if (thing != null) {
204: try {
205: thing.flush();
206: } catch (Exception ignored) {
207: }
208: }
209: }
210:
211: public static void close(JarFile thing) {
212: if (thing != null) {
213: try {
214: thing.close();
215: } catch (Exception ignored) {
216: }
217: }
218: }
219:
220: public static void close(InputStream thing) {
221: if (thing != null) {
222: try {
223: thing.close();
224: } catch (Exception ignored) {
225: }
226: }
227: }
228:
229: public static void close(OutputStream thing) {
230: if (thing != null) {
231: try {
232: thing.close();
233: } catch (Exception ignored) {
234: }
235: }
236: }
237:
238: public static void close(Reader thing) {
239: if (thing != null) {
240: try {
241: thing.close();
242: } catch (Exception ignored) {
243: }
244: }
245: }
246:
247: public static void close(Writer thing) {
248: if (thing != null) {
249: try {
250: thing.close();
251: } catch (Exception ignored) {
252: }
253: }
254: }
255:
256: public static Map<String, File> find(File root, String pattern) {
257: Map<String, File> matches = new HashMap<String, File>();
258: find(root, pattern, matches);
259: return matches;
260: }
261:
262: public static void find(File root, String pattern,
263: Map<String, File> matches) {
264: if (!SelectorUtils.hasWildcards(pattern)) {
265: File match = new File(root, pattern);
266: if (match.exists() && match.canRead()) {
267: matches.put(pattern, match);
268: }
269: } else {
270: Map<String, File> files = IOUtil.listAllFileNames(root);
271: for (Map.Entry<String, File> entry : files.entrySet()) {
272: String fileName = entry.getKey();
273: if (SelectorUtils.matchPath(pattern, fileName)) {
274: matches.put(fileName, entry.getValue());
275: }
276: }
277: }
278: }
279:
280: public static Set<URL> search(File root, String pattern)
281: throws MalformedURLException {
282: if (root.isDirectory()) {
283: if (pattern == null || pattern.length() == 0) {
284: return Collections.singleton(new URL("file:"
285: + root.toURI().normalize().getPath()));
286: }
287: if (!SelectorUtils.hasWildcards(pattern)) {
288: File match = new File(root, pattern);
289: if (match.exists() && match.canRead()) {
290: return Collections.singleton(new URL("file:"
291: + match.toURI().normalize().getPath()));
292: } else {
293: return Collections.emptySet();
294: }
295: } else {
296: Set<URL> matches = new LinkedHashSet<URL>();
297: Map<String, File> files = listAllFileNames(root);
298: for (Map.Entry<String, File> entry : files.entrySet()) {
299: String fileName = entry.getKey();
300: if (SelectorUtils.matchPath(pattern, fileName)) {
301: File file = entry.getValue();
302: matches.add(new URL("file:"
303: + file.toURI().normalize().getPath()));
304: }
305: }
306: return matches;
307: }
308: } else {
309: JarFile jarFile = null;
310: try {
311: jarFile = new JarFile(root);
312: URL baseURL = new URL("jar:" + root.toURL().toString()
313: + "!/");
314: if (pattern == null || pattern.length() == 0) {
315: return Collections.singleton(baseURL);
316: }
317: if (!SelectorUtils.hasWildcards(pattern)) {
318: ZipEntry entry = jarFile.getEntry(pattern);
319: if (entry != null) {
320: URL match = new URL(baseURL, entry.getName());
321: return Collections.singleton(match);
322: } else {
323: return Collections.emptySet();
324: }
325: } else {
326: Set<URL> matches = new LinkedHashSet<URL>();
327: Enumeration entries = jarFile.entries();
328: while (entries.hasMoreElements()) {
329: ZipEntry entry = (ZipEntry) entries
330: .nextElement();
331: String fileName = entry.getName();
332: if (SelectorUtils.matchPath(pattern, fileName)) {
333: URL url = new URL(baseURL, fileName);
334: matches.add(url);
335: }
336: }
337: return matches;
338: }
339: } catch (MalformedURLException e) {
340: throw e;
341: } catch (IOException e) {
342: return Collections.emptySet();
343: } finally {
344: close(jarFile);
345: }
346: }
347: }
348:
349: public static Map<String, File> listAllFileNames(File base) {
350: return listAllFileNames(base, "");
351: }
352:
353: private static Map<String, File> listAllFileNames(File base,
354: String prefix) {
355: if (!base.canRead() || !base.isDirectory()) {
356: throw new IllegalArgumentException(base.getAbsolutePath());
357: }
358: Map<String, File> map = new LinkedHashMap<String, File>();
359: File[] hits = base.listFiles();
360: for (File hit : hits) {
361: if (hit.canRead()) {
362: if (hit.isDirectory()) {
363: map.putAll(listAllFileNames(hit,
364: prefix.equals("") ? hit.getName() : prefix
365: + "/" + hit.getName()));
366: } else {
367: map.put(prefix.equals("") ? hit.getName() : prefix
368: + "/" + hit.getName(), hit);
369: }
370: }
371: }
372: map.put(prefix, base);
373: return map;
374: }
375: }
|