| /* |
| * Copyright (c) 2007-2013 Eike Stepper (Berlin, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Eike Stepper - initial API and implementation |
| * Christian W. Damus (CEA LIST) - bug 418454 |
| */ |
| package org.eclipse.net4j.util.io; |
| |
| import org.eclipse.net4j.internal.util.bundle.OM; |
| import org.eclipse.net4j.util.ReflectUtil; |
| import org.eclipse.net4j.util.StringUtil; |
| import org.eclipse.net4j.util.WrappedException; |
| |
| import java.io.BufferedInputStream; |
| import java.io.BufferedOutputStream; |
| import java.io.BufferedReader; |
| import java.io.BufferedWriter; |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.CharArrayReader; |
| import java.io.CharArrayWriter; |
| import java.io.Closeable; |
| import java.io.EOFException; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.FileReader; |
| import java.io.FileWriter; |
| import java.io.Flushable; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.OutputStream; |
| import java.io.PrintStream; |
| import java.io.Reader; |
| import java.io.Writer; |
| import java.lang.reflect.Method; |
| import java.net.ServerSocket; |
| import java.net.URI; |
| import java.net.URL; |
| import java.net.URLConnection; |
| import java.nio.charset.Charset; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.List; |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public final class IOUtil |
| { |
| /** |
| * @since 3.1 |
| */ |
| public static final int EOF = -1; |
| |
| /** |
| * @since 3.1 |
| */ |
| public static final long DEFAULT_TIMEOUT = 2500; |
| |
| public static final int DEFAULT_BUFFER_SIZE = 8192; |
| |
| /** |
| * @since 2.0 |
| */ |
| public static final String WILDCARD_SINGLE_CHAR = "?"; //$NON-NLS-1$ |
| |
| /** |
| * @since 2.0 |
| */ |
| public static final String WILDCARD_MULTI_CHARS = "*"; //$NON-NLS-1$ |
| |
| /** |
| * @since 2.0 |
| */ |
| public static final String WILDCARD_MULTI_DIRS = "**"; //$NON-NLS-1$ |
| |
| private static final char SEP = File.separatorChar; |
| |
| private static final char SEP_UNIX = '/'; |
| |
| private static final char SEP_WINDOWS = '\\'; |
| |
| private IOUtil() |
| { |
| } |
| |
| public static InputStream IN() |
| { |
| return System.in; |
| } |
| |
| public static PrintStream OUT() |
| { |
| return System.out; |
| } |
| |
| public static PrintStream ERR() |
| { |
| return System.err; |
| } |
| |
| /** |
| * @since 3.1 |
| */ |
| public static void print(StackTraceElement[] elements) |
| { |
| print(elements, System.err); |
| } |
| |
| /** |
| * @since 3.1 |
| */ |
| public static void print(StackTraceElement[] elements, PrintStream stream) |
| { |
| synchronized (stream) |
| { |
| for (int i = 0; i < elements.length; i++) |
| { |
| stream.println("\tat " + elements[i]); |
| } |
| } |
| } |
| |
| public static void print(Throwable t, PrintStream stream) |
| { |
| t.printStackTrace(stream); |
| } |
| |
| public static void print(Throwable t) |
| { |
| print(t, System.err); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static String toString(Throwable t) |
| { |
| try |
| { |
| ByteArrayOutputStream bytes = new ByteArrayOutputStream(); |
| String message = t.getMessage() + "\n"; //$NON-NLS-1$ |
| bytes.write(message.getBytes()); |
| print(t, new PrintStream(bytes)); |
| |
| return bytes.toString(); |
| } |
| catch (IOException ex) |
| { |
| throw WrappedException.wrap(ex); |
| } |
| } |
| |
| /** |
| * @since 3.5 |
| */ |
| public static boolean isFreePort(int port) |
| { |
| ServerSocket socket = null; |
| |
| try |
| { |
| socket = new ServerSocket(port); |
| return true; |
| } |
| catch (Throwable ex) |
| { |
| return false; |
| } |
| finally |
| { |
| IOUtil.closeSilent(socket); |
| } |
| } |
| |
| /** |
| * @since 3.5 |
| */ |
| public static int getFreePort() throws IOException |
| { |
| ServerSocket socket = null; |
| |
| try |
| { |
| socket = new ServerSocket(0); |
| socket.setReuseAddress(true); |
| return socket.getLocalPort(); |
| } |
| finally |
| { |
| IOUtil.closeSilent(socket); |
| } |
| } |
| |
| /** |
| * @since 3.5 |
| */ |
| public static boolean openSystemBrowser(String url) |
| { |
| try |
| { |
| ClassLoader classLoader = OM.BUNDLE.getClass().getClassLoader(); |
| |
| // java.awt.Desktop was introduced with Java 1.6! |
| Class<?> desktopClass = classLoader.loadClass("java.awt.Desktop"); |
| Method getDesktopMethod = ReflectUtil.getMethod(desktopClass, "getDesktop"); |
| Method browseMethod = ReflectUtil.getMethod(desktopClass, "browse", URI.class); |
| |
| Object desktop = getDesktopMethod.invoke(null); |
| browseMethod.invoke(desktop, new URI(url)); |
| return true; |
| } |
| catch (Throwable ex) |
| { |
| //$FALL-THROUGH$ |
| } |
| |
| return false; |
| } |
| |
| public static FileInputStream openInputStream(String fileName) throws IORuntimeException |
| { |
| return openInputStream(new File(fileName)); |
| } |
| |
| public static FileInputStream openInputStream(File file) throws IORuntimeException |
| { |
| try |
| { |
| return new FileInputStream(file); |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| public static FileOutputStream openOutputStream(String fileName) throws IORuntimeException |
| { |
| return openOutputStream(new File(fileName)); |
| } |
| |
| public static FileOutputStream openOutputStream(File file) throws IORuntimeException |
| { |
| try |
| { |
| return new FileOutputStream(file); |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| public static FileReader openReader(String fileName) throws IORuntimeException |
| { |
| return openReader(new File(fileName)); |
| } |
| |
| public static FileReader openReader(File file) throws IORuntimeException |
| { |
| try |
| { |
| return new FileReader(file); |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| public static FileWriter openWriter(String fileName) throws IORuntimeException |
| { |
| return openWriter(new File(fileName)); |
| } |
| |
| public static FileWriter openWriter(File file) throws IORuntimeException |
| { |
| try |
| { |
| return new FileWriter(file); |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| public static Exception closeSilent(Closeable closeable) |
| { |
| try |
| { |
| if (closeable != null) |
| { |
| closeable.close(); |
| } |
| |
| return null; |
| } |
| catch (Exception ex) |
| { |
| OM.LOG.error(ex); |
| return ex; |
| } |
| } |
| |
| public static void close(Closeable closeable) throws IORuntimeException |
| { |
| try |
| { |
| if (closeable != null) |
| { |
| closeable.close(); |
| } |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| public static Exception closeSilent(org.eclipse.net4j.util.collection.Closeable closeable) |
| { |
| try |
| { |
| if (closeable != null) |
| { |
| closeable.close(); |
| } |
| |
| return null; |
| } |
| catch (Exception ex) |
| { |
| OM.LOG.error(ex); |
| return ex; |
| } |
| } |
| |
| public static void close(org.eclipse.net4j.util.collection.Closeable closeable) throws IORuntimeException |
| { |
| if (closeable != null) |
| { |
| closeable.close(); |
| } |
| } |
| |
| /** |
| * @since 3.3 |
| */ |
| public static IOException flushSilent(Flushable flushable) |
| { |
| try |
| { |
| if (flushable != null) |
| { |
| flushable.flush(); |
| } |
| |
| return null; |
| } |
| catch (IOException ex) |
| { |
| OM.LOG.error(ex); |
| return ex; |
| } |
| } |
| |
| /** |
| * @since 3.3 |
| */ |
| public static void flush(Flushable flushable) throws IORuntimeException |
| { |
| try |
| { |
| if (flushable != null) |
| { |
| flushable.flush(); |
| } |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static String makeRelative(File file, File toFolder) |
| { |
| String fileName = normalizeSeparator(file.getAbsolutePath()); |
| String folderName = normalizeSeparator(toFolder.getAbsolutePath()); |
| if (fileName.startsWith(folderName)) |
| { |
| String relative = fileName.substring(folderName.length()); |
| if (relative.startsWith(File.separator)) |
| { |
| relative = relative.substring(1); |
| } |
| |
| return relative; |
| } |
| |
| throw new IllegalArgumentException("Different prefixes: " + fileName + " != " + folderName); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static String normalizeSeparator(String string) |
| { |
| if (SEP == SEP_UNIX) |
| { |
| return string.replace(SEP_WINDOWS, SEP_UNIX); |
| } |
| else if (SEP == SEP_WINDOWS) |
| { |
| return string.replace(SEP_UNIX, SEP_WINDOWS); |
| } |
| |
| return string; |
| } |
| |
| public static void mkdirs(File folder) |
| { |
| if (!folder.exists()) |
| { |
| if (!folder.mkdirs()) |
| { |
| throw new IORuntimeException("Unable to create directory " + folder.getAbsolutePath()); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| public static int delete(File file) |
| { |
| if (file == null) |
| { |
| return 0; |
| } |
| |
| int deleted = 0; |
| if (file.isDirectory()) |
| { |
| for (File child : file.listFiles()) |
| { |
| deleted += delete(child); |
| } |
| } |
| |
| if (file.delete()) |
| { |
| return deleted + 1; |
| } |
| |
| file.deleteOnExit(); |
| return deleted; |
| } |
| |
| public static void copyTree(File source, File target) throws IORuntimeException |
| { |
| if (source.isDirectory()) |
| { |
| mkdirs(target); |
| File[] files = source.listFiles(); |
| for (File file : files) |
| { |
| String name = file.getName(); |
| copyTree(new File(source, name), new File(target, name)); |
| } |
| } |
| else |
| { |
| copyFile(source, target); |
| } |
| } |
| |
| public static void copyTrees(Collection<File> sources, File target) throws IORuntimeException |
| { |
| for (File source : sources) |
| { |
| copyTree(source, target); |
| } |
| } |
| |
| public static void copyText(File source, File target, IOFilter<String>... lineFilters) throws IORuntimeException |
| { |
| BufferedReader reader = null; |
| BufferedWriter writer = null; |
| |
| try |
| { |
| reader = new BufferedReader(openReader(source)); |
| writer = new BufferedWriter(openWriter(target)); |
| copyText(reader, writer, lineFilters); |
| } |
| finally |
| { |
| closeSilent(reader); |
| closeSilent(writer); |
| } |
| } |
| |
| public static void copyText(BufferedReader reader, BufferedWriter writer, IOFilter<String>... lineFilters) |
| { |
| try |
| { |
| String line; |
| while ((line = reader.readLine()) != null) |
| { |
| for (IOFilter<String> lineFilter : lineFilters) |
| { |
| line = lineFilter.filter(line); |
| } |
| |
| writer.write(line); |
| writer.newLine(); |
| } |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| /** |
| * @since 3.1 |
| */ |
| public static long copyBinary(InputStream inputStream, OutputStream outputStream) throws IOException |
| { |
| if (!(inputStream instanceof BufferedInputStream) && !(inputStream instanceof ByteArrayInputStream)) |
| { |
| inputStream = new BufferedInputStream(inputStream); |
| } |
| |
| if (!(outputStream instanceof BufferedOutputStream) && !(outputStream instanceof ByteArrayOutputStream)) |
| { |
| outputStream = new BufferedOutputStream(outputStream); |
| } |
| |
| long size = 0; |
| int b; |
| while ((b = inputStream.read()) != EOF) |
| { |
| outputStream.write(b); |
| ++size; |
| } |
| |
| outputStream.flush(); |
| return size; |
| } |
| |
| /** |
| * @since 3.1 |
| */ |
| public static void copyBinary(InputStream inputStream, OutputStream outputStream, long size) throws IOException |
| { |
| byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; |
| long remaining = size; |
| |
| while (remaining > 0L) |
| { |
| int bytesToCopy = (int)Math.min(remaining, buffer.length); |
| |
| int bytesRead = inputStream.read(buffer, 0, bytesToCopy); |
| if (bytesRead < 1) |
| { |
| throw new EOFException("Read only " + (size - remaining) + "+" + bytesRead + "=" |
| + (size - remaining + bytesRead) + " but expected to read " + size); |
| } |
| |
| outputStream.write(buffer, 0, bytesRead); |
| remaining -= bytesRead; |
| } |
| |
| outputStream.flush(); |
| } |
| |
| /** |
| * @since 3.1 |
| */ |
| public static long copyCharacter(Reader reader, Writer writer) throws IOException |
| { |
| if (!(reader instanceof BufferedReader) && !(reader instanceof CharArrayReader)) |
| { |
| reader = new BufferedReader(reader); |
| } |
| |
| if (!(writer instanceof BufferedWriter) && !(writer instanceof CharArrayWriter)) |
| { |
| writer = new BufferedWriter(writer); |
| } |
| |
| long size = 0; |
| int c; |
| while ((c = reader.read()) != EOF) |
| { |
| writer.write(c); |
| ++size; |
| } |
| |
| writer.flush(); |
| return size; |
| } |
| |
| /** |
| * @since 3.1 |
| */ |
| public static void copyCharacter(Reader reader, Writer writer, long size) throws IOException |
| { |
| char[] buffer = new char[DEFAULT_BUFFER_SIZE]; |
| long remaining = size; |
| |
| while (remaining > 0L) |
| { |
| int charsToCopy = (int)Math.min(remaining, buffer.length); |
| |
| int charsRead = reader.read(buffer, 0, charsToCopy); |
| if (charsRead < 1) |
| { |
| throw new EOFException("Read only " + (size - remaining) + "+" + charsRead + "=" |
| + (size - remaining + charsRead) + " but expected to read " + size); |
| } |
| |
| writer.write(buffer, 0, charsRead); |
| remaining -= charsRead; |
| } |
| |
| writer.flush(); |
| } |
| |
| public static int copy(InputStream input, OutputStream output, int size, byte buffer[]) throws IORuntimeException |
| { |
| try |
| { |
| int written = 0; |
| int bufferSize = buffer.length; |
| int n = Math.min(size, bufferSize); |
| while (n > 0 && (n = input.read(buffer, 0, n)) != -1) |
| { |
| output.write(buffer, 0, n); |
| written += n; |
| size -= n; |
| n = Math.min(size, bufferSize); |
| } |
| |
| return written; |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| public static void copy(InputStream input, OutputStream output, byte buffer[]) throws IORuntimeException |
| { |
| try |
| { |
| int n; |
| while ((n = input.read(buffer)) != -1) |
| { |
| output.write(buffer, 0, n); |
| } |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| public static void copy(InputStream input, OutputStream output, int bufferSize) throws IORuntimeException |
| { |
| copy(input, output, new byte[bufferSize]); |
| } |
| |
| public static void copy(InputStream input, OutputStream output) throws IORuntimeException |
| { |
| copy(input, output, DEFAULT_BUFFER_SIZE); |
| } |
| |
| /** |
| * @see NIOUtil#copyFile(File, File) |
| */ |
| public static void copyFile(File source, File target) throws IORuntimeException |
| { |
| mkdirs(target.getParentFile()); |
| FileInputStream input = null; |
| FileOutputStream output = null; |
| |
| try |
| { |
| input = openInputStream(source); |
| output = openOutputStream(target); |
| copy(input, output); |
| } |
| finally |
| { |
| closeSilent(input); |
| closeSilent(output); |
| } |
| } |
| |
| /** |
| * @since 3.4 |
| */ |
| public static String readText(URL url) throws IORuntimeException |
| { |
| Reader input = null; |
| |
| try |
| { |
| URLConnection connection = url.openConnection(); |
| connection.setDoInput(true); |
| connection.setUseCaches(true); |
| connection.connect(); |
| |
| Charset charset; |
| String encoding = connection.getContentEncoding(); |
| if (encoding == null) |
| { |
| charset = Charset.defaultCharset(); |
| } |
| else |
| { |
| charset = Charset.forName(encoding); |
| } |
| |
| input = new InputStreamReader(connection.getInputStream(), charset); |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| |
| try |
| { |
| CharArrayWriter output = new CharArrayWriter(); |
| copyCharacter(input, output); |
| return output.toString(); |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| finally |
| { |
| closeSilent(input); |
| } |
| } |
| |
| /** |
| * @since 3.1 |
| */ |
| public static String readTextFile(File file) throws IORuntimeException |
| { |
| Reader input = openReader(file); |
| |
| try |
| { |
| CharArrayWriter output = new CharArrayWriter(); |
| copyCharacter(input, output); |
| return output.toString(); |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| finally |
| { |
| closeSilent(input); |
| } |
| } |
| |
| public static byte[] readFile(File file) throws IORuntimeException |
| { |
| if (file.length() > Integer.MAX_VALUE) |
| { |
| throw new IllegalArgumentException("File too long: " + file.length()); //$NON-NLS-1$ |
| } |
| |
| int size = (int)file.length(); |
| FileInputStream input = openInputStream(file); |
| |
| try |
| { |
| ByteArrayOutputStream output = new ByteArrayOutputStream(size); |
| copy(input, output); |
| return output.toByteArray(); |
| } |
| finally |
| { |
| closeSilent(input); |
| } |
| } |
| |
| public static void writeFile(File file, byte[] bytes) throws IORuntimeException |
| { |
| FileOutputStream output = openOutputStream(file); |
| |
| try |
| { |
| ByteArrayInputStream input = new ByteArrayInputStream(bytes); |
| copy(input, output); |
| } |
| finally |
| { |
| closeSilent(output); |
| } |
| } |
| |
| public static List<File> listDepthFirst(File file) |
| { |
| FileCollector collector = new FileCollector(); |
| visitDepthFirst(file, collector); |
| return collector.getFiles(); |
| } |
| |
| public static List<File> listBreadthFirst(File file) |
| { |
| FileCollector collector = new FileCollector(); |
| visitBreadthFirst(file, collector); |
| return collector.getFiles(); |
| } |
| |
| public static void visitDepthFirst(File file, IOVisitor visitor) throws IORuntimeException |
| { |
| try |
| { |
| boolean recurse = visitor.visit(file); |
| if (recurse && file.isDirectory()) |
| { |
| visitDepthFirst(file.listFiles(), visitor); |
| } |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| public static void visitDepthFirst(File[] files, IOVisitor visitor) |
| { |
| for (File file : files) |
| { |
| visitDepthFirst(file, visitor); |
| } |
| } |
| |
| public static void visitBreadthFirst(File file, IOVisitor visitor) throws IORuntimeException |
| { |
| File[] files = { file }; |
| visitBreadthFirst(files, visitor); |
| } |
| |
| public static void visitBreadthFirst(File[] files, IOVisitor visitor) throws IORuntimeException |
| { |
| try |
| { |
| boolean[] recurse = new boolean[files.length]; |
| for (int i = 0; i < files.length; i++) |
| { |
| File file = files[i]; |
| recurse[i] = visitor.visit(file); |
| } |
| |
| for (int i = 0; i < files.length; i++) |
| { |
| File file = files[i]; |
| if (file.isDirectory() && recurse[i]) |
| { |
| File[] children = file.listFiles(); |
| for (File child : children) |
| { |
| visitBreadthFirst(child, visitor); |
| } |
| } |
| } |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| public static <IO extends Closeable> void safeRun(IO io, IORunnable<IO> runnable) throws IORuntimeException |
| { |
| try |
| { |
| runnable.run(io); |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| finally |
| { |
| close(io); |
| } |
| } |
| |
| public static void safeInput(File file, IORunnable<FileInputStream> runnable) throws IORuntimeException |
| { |
| safeRun(openInputStream(file), runnable); |
| } |
| |
| public static void safeOutput(File file, IORunnable<FileOutputStream> runnable) throws IORuntimeException |
| { |
| safeRun(openOutputStream(file), runnable); |
| } |
| |
| public static void safeRead(File file, IORunnable<FileReader> runnable) throws IORuntimeException |
| { |
| safeRun(openReader(file), runnable); |
| } |
| |
| public static void safeWrite(File file, IORunnable<FileWriter> runnable) throws IORuntimeException |
| { |
| safeRun(openWriter(file), runnable); |
| } |
| |
| public static boolean equals(InputStream stream1, InputStream stream2) throws IORuntimeException |
| { |
| try |
| { |
| for (;;) |
| { |
| int byte1 = stream1.read(); |
| int byte2 = stream2.read(); |
| |
| if (byte1 != byte2) |
| { |
| return false; |
| } |
| |
| if (byte1 == -1) // Implies byte2 == -1 |
| { |
| return true; |
| } |
| } |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| /** |
| * @since 3.2 |
| */ |
| public static boolean equals(Reader reader1, Reader reader2) throws IORuntimeException |
| { |
| try |
| { |
| for (;;) |
| { |
| int char1 = reader1.read(); |
| int char2 = reader2.read(); |
| |
| if (char1 != char2) |
| { |
| return false; |
| } |
| |
| if (char1 == -1) // Implies char2 == -1 |
| { |
| return true; |
| } |
| } |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| } |
| |
| public static boolean equals(File file1, File file2) throws IORuntimeException |
| { |
| if (file1.length() != file2.length()) |
| { |
| return false; |
| } |
| |
| FileInputStream stream1 = null; |
| FileInputStream stream2 = null; |
| |
| try |
| { |
| stream1 = new FileInputStream(file1); |
| stream2 = new FileInputStream(file2); |
| return equals(stream1, stream2); |
| } |
| catch (IOException ex) |
| { |
| throw new IORuntimeException(ex); |
| } |
| finally |
| { |
| closeSilent(stream1); |
| closeSilent(stream2); |
| } |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static List<File> glob(String pattern, File folder) |
| { |
| List<File> result = new ArrayList<File>(); |
| pattern = normalizeSeparator(pattern); |
| if (pattern.endsWith(File.separator)) |
| { |
| pattern += WILDCARD_MULTI_DIRS; |
| } |
| |
| globRecurse(pattern, folder, result); |
| return result; |
| } |
| |
| private static void globRecurse(String pattern, File folder, List<File> result) |
| { |
| int sep = pattern.indexOf(SEP); |
| if (sep != -1) |
| { |
| globSegment(pattern.substring(0, sep), pattern.substring(sep + 1), folder, result); |
| } |
| else |
| { |
| globSegment(pattern, null, folder, result); |
| } |
| } |
| |
| private static void globSegment(String segment, String pattern, File folder, List<File> result) |
| { |
| boolean multiDirs = false; |
| if (segment.contains(WILDCARD_MULTI_DIRS)) |
| { |
| if (!segment.equals(WILDCARD_MULTI_DIRS)) |
| { |
| throw new IllegalArgumentException("Invalid pattern segment: " + segment); //$NON-NLS-1$ |
| } |
| |
| multiDirs = true; |
| } |
| |
| for (File file : folder.listFiles()) |
| { |
| String tmp = segment; |
| if (multiDirs && file.isDirectory()) |
| { |
| globRecurse(WILDCARD_MULTI_DIRS + File.separator + pattern, file, result); |
| tmp = WILDCARD_MULTI_CHARS; |
| } |
| |
| if (StringUtil.glob(tmp, file.getName())) |
| { |
| if (pattern == null) |
| { |
| // Match |
| result.add(file); |
| } |
| else if (file.isDirectory()) |
| { |
| // Recurse |
| globRecurse(pattern, file, result); |
| } |
| } |
| } |
| } |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public static class FileCollector implements IOVisitor |
| { |
| private List<File> files = new ArrayList<File>(); |
| |
| public FileCollector() |
| { |
| } |
| |
| public List<File> getFiles() |
| { |
| return files; |
| } |
| |
| public boolean visit(File file) throws IOException |
| { |
| files.add(file); |
| return true; |
| } |
| } |
| } |