Index: 3rdParty_sources/versions.txt =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/versions.txt,v diff -u -r1.4 -r1.5 --- 3rdParty_sources/versions.txt 10 Sep 2012 19:03:07 -0000 1.4 +++ 3rdParty_sources/versions.txt 1 Oct 2012 13:03:03 -0000 1.5 @@ -13,6 +13,8 @@ Commons Lang 2.0 +Commons IO 2.1 + Hibernate Core 3.3.1 GA jbosscache 3.1.0.CR1 Index: 3rdParty_sources/commons-io/org/apache/commons/io/ByteOrderMark.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/ByteOrderMark.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/ByteOrderMark.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.Serializable; + +/** + * Byte Order Mark (BOM) representation - + * see {@link org.apache.commons.io.input.BOMInputStream}. + * + * @see org.apache.commons.io.input.BOMInputStream + * @see Wikipedia - Byte Order Mark + * @version $Id: ByteOrderMark.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + * @since Commons IO 2.0 + */ +public class ByteOrderMark implements Serializable { + + private static final long serialVersionUID = 1L; + + /** UTF-8 BOM */ + public static final ByteOrderMark UTF_8 = new ByteOrderMark("UTF-8", 0xEF, 0xBB, 0xBF); + /** UTF-16BE BOM (Big Endian) */ + public static final ByteOrderMark UTF_16BE = new ByteOrderMark("UTF-16BE", 0xFE, 0xFF); + /** UTF-16LE BOM (Little Endian) */ + public static final ByteOrderMark UTF_16LE = new ByteOrderMark("UTF-16LE", 0xFF, 0xFE); + + private final String charsetName; + private final int[] bytes; + + /** + * Construct a new BOM. + * + * @param charsetName The name of the charset the BOM represents + * @param bytes The BOM's bytes + * @throws IllegalArgumentException if the charsetName is null or + * zero length + * @throws IllegalArgumentException if the bytes are null or zero + * length + */ + public ByteOrderMark(String charsetName, int... bytes) { + if (charsetName == null || charsetName.length() == 0) { + throw new IllegalArgumentException("No charsetName specified"); + } + if (bytes == null || bytes.length == 0) { + throw new IllegalArgumentException("No bytes specified"); + } + this.charsetName = charsetName; + this.bytes = new int[bytes.length]; + System.arraycopy(bytes, 0, this.bytes, 0, bytes.length); + } + + /** + * Return the name of the {@link java.nio.charset.Charset} the BOM represents. + * + * @return the character set name + */ + public String getCharsetName() { + return charsetName; + } + + /** + * Return the length of the BOM's bytes. + * + * @return the length of the BOM's bytes + */ + public int length() { + return bytes.length; + } + + /** + * The byte at the specified position. + * + * @param pos The position + * @return The specified byte + */ + public int get(int pos) { + return bytes[pos]; + } + + /** + * Return a copy of the BOM's bytes. + * + * @return a copy of the BOM's bytes + */ + public byte[] getBytes() { + byte[] copy = new byte[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + copy[i] = (byte)bytes[i]; + } + return copy; + } + + /** + * Indicates if this BOM's bytes equals another. + * + * @param obj The object to compare to + * @return true if the bom's bytes are equal, otherwise + * false + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ByteOrderMark)) { + return false; + } + ByteOrderMark bom = (ByteOrderMark)obj; + if (bytes.length != bom.length()) { + return false; + } + for (int i = 0; i < bytes.length; i++) { + if (bytes[i] != bom.get(i)) { + return false; + } + } + return true; + } + + /** + * Return the hashcode for this BOM. + * + * @return the hashcode for this BOM. + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + int hashCode = getClass().hashCode(); + for (int b : bytes) { + hashCode += b; + } + return hashCode; + } + + /** + * Provide a String representation of the BOM. + * + * @return the length of the BOM's bytes + */ + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(getClass().getSimpleName()); + builder.append('['); + builder.append(charsetName); + builder.append(": "); + for (int i = 0; i < bytes.length; i++) { + if (i > 0) { + builder.append(","); + } + builder.append("0x"); + builder.append(Integer.toHexString(0xFF & bytes[i]).toUpperCase()); + } + builder.append(']'); + return builder.toString(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/CopyUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/CopyUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/CopyUtils.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,333 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.StringReader; +import java.io.Writer; + +/** + * This class provides static utility methods for buffered + * copying between sources (InputStream, Reader, + * String and byte[]) and destinations + * (OutputStream, Writer, String and + * byte[]). + *

+ * Unless otherwise noted, these copy methods do not + * flush or close the streams. Often doing so would require making non-portable + * assumptions about the streams' origin and further use. This means that both + * streams' close() methods must be called after copying. if one + * omits this step, then the stream resources (sockets, file descriptors) are + * released when the associated Stream is garbage-collected. It is not a good + * idea to rely on this mechanism. For a good overview of the distinction + * between "memory management" and "resource management", see + * this + * UnixReview article. + *

+ * For byte-to-char methods, a copy variant allows the encoding + * to be selected (otherwise the platform default is used). We would like to + * encourage you to always specify the encoding because relying on the platform + * default can lead to unexpected results. + *

copy methods that + * let you specify the buffer size because in modern VMs the impact on speed + * seems to be minimal. We're using a default buffer size of 4 KB. + *

+ * The copy methods use an internal buffer when copying. It is + * therefore advisable not to deliberately wrap the stream arguments + * to the copy methods in Buffered* streams. For + * example, don't do the following: + *

+ *  copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) );
+ *  
+ * The rationale is as follows: + *

+ * Imagine that an InputStream's read() is a very expensive operation, which + * would usually suggest wrapping in a BufferedInputStream. The + * BufferedInputStream works by issuing infrequent + * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the + * underlying InputStream, to fill an internal buffer, from which further + * read requests can inexpensively get their data (until the buffer + * runs out). + *

+ * However, the copy methods do the same thing, keeping an + * internal buffer, populated by + * {@link InputStream#read(byte[] b, int off, int len)} requests. Having two + * buffers (or three if the destination stream is also buffered) is pointless, + * and the unnecessary buffer management hurts performance slightly (about 3%, + * according to some simple experiments). + *

+ * Behold, intrepid explorers; a map of this class: + *

+ *       Method      Input               Output          Dependency
+ *       ------      -----               ------          -------
+ * 1     copy        InputStream         OutputStream    (primitive)
+ * 2     copy        Reader              Writer          (primitive)
+ *
+ * 3     copy        InputStream         Writer          2
+ *
+ * 4     copy        Reader              OutputStream    2
+ *
+ * 5     copy        String              OutputStream    2
+ * 6     copy        String              Writer          (trivial)
+ *
+ * 7     copy        byte[]              Writer          3
+ * 8     copy        byte[]              OutputStream    (trivial)
+ * 
+ *

+ * Note that only the first two methods shuffle bytes; the rest use these + * two, or (if possible) copy using native Java copy methods. As there are + * method variants to specify the encoding, each row may + * correspond to up to 2 methods. + *

+ * Origin of code: Excalibur. + * + * @author Peter Donald + * @author Jeff Turner + * @author Matthew Hawthorne + * @version $Id: CopyUtils.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + * @deprecated Use IOUtils. Will be removed in 2.0. + * Methods renamed to IOUtils.write() or IOUtils.copy(). + * Null handling behaviour changed in IOUtils (null data does not + * throw NullPointerException). + */ +@Deprecated +public class CopyUtils { + + /** + * The default size of the buffer. + */ + private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; + + /** + * Instances should NOT be constructed in standard programming. + */ + public CopyUtils() { } + + // ---------------------------------------------------------------- + // byte[] -> OutputStream + // ---------------------------------------------------------------- + + /** + * Copy bytes from a byte[] to an OutputStream. + * @param input the byte array to read from + * @param output the OutputStream to write to + * @throws IOException In case of an I/O problem + */ + public static void copy(byte[] input, OutputStream output) + throws IOException { + output.write(input); + } + + // ---------------------------------------------------------------- + // byte[] -> Writer + // ---------------------------------------------------------------- + + /** + * Copy and convert bytes from a byte[] to chars on a + * Writer. + * The platform's default encoding is used for the byte-to-char conversion. + * @param input the byte array to read from + * @param output the Writer to write to + * @throws IOException In case of an I/O problem + */ + public static void copy(byte[] input, Writer output) + throws IOException { + ByteArrayInputStream in = new ByteArrayInputStream(input); + copy(in, output); + } + + + /** + * Copy and convert bytes from a byte[] to chars on a + * Writer, using the specified encoding. + * @param input the byte array to read from + * @param output the Writer to write to + * @param encoding The name of a supported character encoding. See the + * IANA + * Charset Registry for a list of valid encoding types. + * @throws IOException In case of an I/O problem + */ + public static void copy( + byte[] input, + Writer output, + String encoding) + throws IOException { + ByteArrayInputStream in = new ByteArrayInputStream(input); + copy(in, output, encoding); + } + + + // ---------------------------------------------------------------- + // Core copy methods + // ---------------------------------------------------------------- + + /** + * Copy bytes from an InputStream to an + * OutputStream. + * @param input the InputStream to read from + * @param output the OutputStream to write to + * @return the number of bytes copied + * @throws IOException In case of an I/O problem + */ + public static int copy( + InputStream input, + OutputStream output) + throws IOException { + byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; + int count = 0; + int n = 0; + while (-1 != (n = input.read(buffer))) { + output.write(buffer, 0, n); + count += n; + } + return count; + } + + // ---------------------------------------------------------------- + // Reader -> Writer + // ---------------------------------------------------------------- + + /** + * Copy chars from a Reader to a Writer. + * @param input the Reader to read from + * @param output the Writer to write to + * @return the number of characters copied + * @throws IOException In case of an I/O problem + */ + public static int copy( + Reader input, + Writer output) + throws IOException { + char[] buffer = new char[DEFAULT_BUFFER_SIZE]; + int count = 0; + int n = 0; + while (-1 != (n = input.read(buffer))) { + output.write(buffer, 0, n); + count += n; + } + return count; + } + + // ---------------------------------------------------------------- + // InputStream -> Writer + // ---------------------------------------------------------------- + + /** + * Copy and convert bytes from an InputStream to chars on a + * Writer. + * The platform's default encoding is used for the byte-to-char conversion. + * @param input the InputStream to read from + * @param output the Writer to write to + * @throws IOException In case of an I/O problem + */ + public static void copy( + InputStream input, + Writer output) + throws IOException { + InputStreamReader in = new InputStreamReader(input); + copy(in, output); + } + + /** + * Copy and convert bytes from an InputStream to chars on a + * Writer, using the specified encoding. + * @param input the InputStream to read from + * @param output the Writer to write to + * @param encoding The name of a supported character encoding. See the + * IANA + * Charset Registry for a list of valid encoding types. + * @throws IOException In case of an I/O problem + */ + public static void copy( + InputStream input, + Writer output, + String encoding) + throws IOException { + InputStreamReader in = new InputStreamReader(input, encoding); + copy(in, output); + } + + + // ---------------------------------------------------------------- + // Reader -> OutputStream + // ---------------------------------------------------------------- + + /** + * Serialize chars from a Reader to bytes on an + * OutputStream, and flush the OutputStream. + * @param input the Reader to read from + * @param output the OutputStream to write to + * @throws IOException In case of an I/O problem + */ + public static void copy( + Reader input, + OutputStream output) + throws IOException { + OutputStreamWriter out = new OutputStreamWriter(output); + copy(input, out); + // XXX Unless anyone is planning on rewriting OutputStreamWriter, we + // have to flush here. + out.flush(); + } + + // ---------------------------------------------------------------- + // String -> OutputStream + // ---------------------------------------------------------------- + + /** + * Serialize chars from a String to bytes on an + * OutputStream, and + * flush the OutputStream. + * @param input the String to read from + * @param output the OutputStream to write to + * @throws IOException In case of an I/O problem + */ + public static void copy( + String input, + OutputStream output) + throws IOException { + StringReader in = new StringReader(input); + OutputStreamWriter out = new OutputStreamWriter(output); + copy(in, out); + // XXX Unless anyone is planning on rewriting OutputStreamWriter, we + // have to flush here. + out.flush(); + } + + // ---------------------------------------------------------------- + // String -> Writer + // ---------------------------------------------------------------- + + /** + * Copy chars from a String to a Writer. + * @param input the String to read from + * @param output the Writer to write to + * @throws IOException In case of an I/O problem + */ + public static void copy(String input, Writer output) + throws IOException { + output.write(input); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/DirectoryWalker.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/DirectoryWalker.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/DirectoryWalker.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,636 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.util.Collection; + +import org.apache.commons.io.filefilter.FileFilterUtils; +import org.apache.commons.io.filefilter.IOFileFilter; +import org.apache.commons.io.filefilter.TrueFileFilter; + +/** + * Abstract class that walks through a directory hierarchy and provides + * subclasses with convenient hooks to add specific behaviour. + *

+ * This class operates with a {@link FileFilter} and maximum depth to + * limit the files and direcories visited. + * Commons IO supplies many common filter implementations in the + * filefilter package. + *

+ * The following sections describe: + *

+ * + * + *

1. Example Implementation

+ * + * There are many possible extensions, for example, to delete all + * files and '.svn' directories, and return a list of deleted files: + *
+ *  public class FileCleaner extends DirectoryWalker {
+ *
+ *    public FileCleaner() {
+ *      super();
+ *    }
+ *
+ *    public List clean(File startDirectory) {
+ *      List results = new ArrayList();
+ *      walk(startDirectory, results);
+ *      return results;
+ *    }
+ *
+ *    protected boolean handleDirectory(File directory, int depth, Collection results) {
+ *      // delete svn directories and then skip
+ *      if (".svn".equals(directory.getName())) {
+ *        directory.delete();
+ *        return false;
+ *      } else {
+ *        return true;
+ *      }
+ *
+ *    }
+ *
+ *    protected void handleFile(File file, int depth, Collection results) {
+ *      // delete file and add to list of deleted
+ *      file.delete();
+ *      results.add(file);
+ *    }
+ *  }
+ * 
+ * + * + *

2. Filter Example

+ * + * Choosing which directories and files to process can be a key aspect + * of using this class. This information can be setup in three ways, + * via three different constructors. + *

+ * The first option is to visit all directories and files. + * This is achieved via the no-args constructor. + *

+ * The second constructor option is to supply a single {@link FileFilter} + * that describes the files and directories to visit. Care must be taken + * with this option as the same filter is used for both directories + * and files. + *

+ * For example, if you wanted all directories which are not hidden + * and files which end in ".txt": + *

+ *  public class FooDirectoryWalker extends DirectoryWalker {
+ *    public FooDirectoryWalker(FileFilter filter) {
+ *      super(filter, -1);
+ *    }
+ *  }
+ *  
+ *  // Build up the filters and create the walker
+ *    // Create a filter for Non-hidden directories
+ *    IOFileFilter fooDirFilter = 
+ *        FileFilterUtils.andFileFilter(FileFilterUtils.directoryFileFilter,
+ *                                      HiddenFileFilter.VISIBLE);
+ *
+ *    // Create a filter for Files ending in ".txt"
+ *    IOFileFilter fooFileFilter = 
+ *        FileFilterUtils.andFileFilter(FileFilterUtils.fileFileFilter,
+ *                                      FileFilterUtils.suffixFileFilter(".txt"));
+ *
+ *    // Combine the directory and file filters using an OR condition
+ *    java.io.FileFilter fooFilter = 
+ *        FileFilterUtils.orFileFilter(fooDirFilter, fooFileFilter);
+ *
+ *    // Use the filter to construct a DirectoryWalker implementation
+ *    FooDirectoryWalker walker = new FooDirectoryWalker(fooFilter);
+ * 
+ *

+ * The third constructor option is to specify separate filters, one for + * directories and one for files. These are combined internally to form + * the correct FileFilter, something which is very easy to + * get wrong when attempted manually, particularly when trying to + * express constructs like 'any file in directories named docs'. + *

+ * For example, if you wanted all directories which are not hidden + * and files which end in ".txt": + *

+ *  public class FooDirectoryWalker extends DirectoryWalker {
+ *    public FooDirectoryWalker(IOFileFilter dirFilter, IOFileFilter fileFilter) {
+ *      super(dirFilter, fileFilter, -1);
+ *    }
+ *  }
+ *  
+ *  // Use the filters to construct the walker
+ *  FooDirectoryWalker walker = new FooDirectoryWalker(
+ *    HiddenFileFilter.VISIBLE,
+ *    FileFilterUtils.suffixFileFilter(".txt"),
+ *  );
+ * 
+ * This is much simpler than the previous example, and is why it is the preferred + * option for filtering. + * + * + *

3. Cancellation

+ * + * The DirectoryWalker contains some of the logic required for cancel processing. + * Subclasses must complete the implementation. + *

+ * What DirectoryWalker does provide for cancellation is: + *

+ *

+ * Implementations need to provide: + *

+ *

+ * Two possible scenarios are envisaged for cancellation: + *

+ *

+ * The following sections provide example implementations for these two different + * scenarios. + * + * + *

3.1 External / Multi-threaded

+ * + * This example provides a public cancel() method that can be + * called by another thread to stop the processing. A typical example use-case + * would be a cancel button on a GUI. Calling this method sets a + * + * volatile flag to ensure it will work properly in a multi-threaded environment. + * The flag is returned by the handleIsCancelled() method, which + * will cause the walk to stop immediately. The handleCancelled() + * method will be the next, and last, callback method received once cancellation + * has occurred. + * + *
+ *  public class FooDirectoryWalker extends DirectoryWalker {
+ *
+ *    private volatile boolean cancelled = false;
+ *
+ *    public void cancel() {
+ *        cancelled = true;
+ *    }
+ *
+ *    private void handleIsCancelled(File file, int depth, Collection results) {
+ *        return cancelled;
+ *    }
+ *
+ *    protected void handleCancelled(File startDirectory, Collection results, CancelException cancel) {
+ *        // implement processing required when a cancellation occurs
+ *    }
+ *  }
+ * 
+ * + * + *

3.2 Internal

+ * + * This shows an example of how internal cancellation processing could be implemented. + * Note the decision logic and throwing a {@link CancelException} could be implemented + * in any of the lifecycle methods. + * + *
+ *  public class BarDirectoryWalker extends DirectoryWalker {
+ *
+ *    protected boolean handleDirectory(File directory, int depth, Collection results) throws IOException {
+ *        // cancel if hidden directory
+ *        if (directory.isHidden()) {
+ *            throw new CancelException(file, depth);
+ *        }
+ *        return true;
+ *    }
+ *
+ *    protected void handleFile(File file, int depth, Collection results) throws IOException {
+ *        // cancel if read-only file
+ *        if (!file.canWrite()) {
+ *            throw new CancelException(file, depth);
+ *        }
+ *        results.add(file);
+ *    }
+ *
+ *    protected void handleCancelled(File startDirectory, Collection results, CancelException cancel) {
+ *        // implement processing required when a cancellation occurs
+ *    }
+ *  }
+ * 
+ * + * @since Commons IO 1.3 + * @version $Revision: 1.1 $ + */ +public abstract class DirectoryWalker { + + /** + * The file filter to use to filter files and directories. + */ + private final FileFilter filter; + /** + * The limit on the directory depth to walk. + */ + private final int depthLimit; + + /** + * Construct an instance with no filtering and unlimited depth. + */ + protected DirectoryWalker() { + this(null, -1); + } + + /** + * Construct an instance with a filter and limit the depth navigated to. + *

+ * The filter controls which files and directories will be navigated to as + * part of the walk. The {@link FileFilterUtils} class is useful for combining + * various filters together. A null filter means that no + * filtering should occur and all files and directories will be visited. + * + * @param filter the filter to apply, null means visit all files + * @param depthLimit controls how deep the hierarchy is + * navigated to (less than 0 means unlimited) + */ + protected DirectoryWalker(FileFilter filter, int depthLimit) { + this.filter = filter; + this.depthLimit = depthLimit; + } + + /** + * Construct an instance with a directory and a file filter and an optional + * limit on the depth navigated to. + *

+ * The filters control which files and directories will be navigated to as part + * of the walk. This constructor uses {@link FileFilterUtils#makeDirectoryOnly(IOFileFilter)} + * and {@link FileFilterUtils#makeFileOnly(IOFileFilter)} internally to combine the filters. + * A null filter means that no filtering should occur. + * + * @param directoryFilter the filter to apply to directories, null means visit all directories + * @param fileFilter the filter to apply to files, null means visit all files + * @param depthLimit controls how deep the hierarchy is + * navigated to (less than 0 means unlimited) + */ + protected DirectoryWalker(IOFileFilter directoryFilter, IOFileFilter fileFilter, int depthLimit) { + if (directoryFilter == null && fileFilter == null) { + this.filter = null; + } else { + directoryFilter = (directoryFilter != null ? directoryFilter : TrueFileFilter.TRUE); + fileFilter = (fileFilter != null ? fileFilter : TrueFileFilter.TRUE); + directoryFilter = FileFilterUtils.makeDirectoryOnly(directoryFilter); + fileFilter = FileFilterUtils.makeFileOnly(fileFilter); + this.filter = FileFilterUtils.or(directoryFilter, fileFilter); + } + this.depthLimit = depthLimit; + } + + //----------------------------------------------------------------------- + /** + * Internal method that walks the directory hierarchy in a depth-first manner. + *

+ * Users of this class do not need to call this method. This method will + * be called automatically by another (public) method on the specific subclass. + *

+ * Writers of subclasses should call this method to start the directory walk. + * Once called, this method will emit events as it walks the hierarchy. + * The event methods have the prefix handle. + * + * @param startDirectory the directory to start from, not null + * @param results the collection of result objects, may be updated + * @throws NullPointerException if the start directory is null + * @throws IOException if an I/O Error occurs + */ + protected final void walk(File startDirectory, Collection results) throws IOException { + if (startDirectory == null) { + throw new NullPointerException("Start Directory is null"); + } + try { + handleStart(startDirectory, results); + walk(startDirectory, 0, results); + handleEnd(results); + } catch(CancelException cancel) { + handleCancelled(startDirectory, results, cancel); + } + } + + /** + * Main recursive method to examine the directory hierarchy. + * + * @param directory the directory to examine, not null + * @param depth the directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + private void walk(File directory, int depth, Collection results) throws IOException { + checkIfCancelled(directory, depth, results); + if (handleDirectory(directory, depth, results)) { + handleDirectoryStart(directory, depth, results); + int childDepth = depth + 1; + if (depthLimit < 0 || childDepth <= depthLimit) { + checkIfCancelled(directory, depth, results); + File[] childFiles = (filter == null ? directory.listFiles() : directory.listFiles(filter)); + childFiles = filterDirectoryContents(directory, depth, childFiles); + if (childFiles == null) { + handleRestricted(directory, childDepth, results); + } else { + for (File childFile : childFiles) { + if (childFile.isDirectory()) { + walk(childFile, childDepth, results); + } else { + checkIfCancelled(childFile, childDepth, results); + handleFile(childFile, childDepth, results); + checkIfCancelled(childFile, childDepth, results); + } + } + } + } + handleDirectoryEnd(directory, depth, results); + } + checkIfCancelled(directory, depth, results); + } + + //----------------------------------------------------------------------- + /** + * Checks whether the walk has been cancelled by calling {@link #handleIsCancelled}, + * throwing a CancelException if it has. + *

+ * Writers of subclasses should not normally call this method as it is called + * automatically by the walk of the tree. However, sometimes a single method, + * typically {@link #handleFile}, may take a long time to run. In that case, + * you may wish to check for cancellation by calling this method. + * + * @param file the current file being processed + * @param depth the current file level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected final void checkIfCancelled(File file, int depth, Collection results) throws IOException { + if (handleIsCancelled(file, depth, results)) { + throw new CancelException(file, depth); + } + } + + /** + * Overridable callback method invoked to determine if the entire walk + * operation should be immediately cancelled. + *

+ * This method should be implemented by those subclasses that want to + * provide a public cancel() method available from another + * thread. The design pattern for the subclass should be as follows: + *

+     *  public class FooDirectoryWalker extends DirectoryWalker {
+     *    private volatile boolean cancelled = false;
+     *
+     *    public void cancel() {
+     *        cancelled = true;
+     *    }
+     *    private void handleIsCancelled(File file, int depth, Collection results) {
+     *        return cancelled;
+     *    }
+     *    protected void handleCancelled(File startDirectory,
+     *              Collection results, CancelException cancel) {
+     *        // implement processing required when a cancellation occurs
+     *    }
+     *  }
+     * 
+ *

+ * If this method returns true, then the directory walk is immediately + * cancelled. The next callback method will be {@link #handleCancelled}. + *

+ * This implementation returns false. + * + * @param file the file or directory being processed + * @param depth the current directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @return true if the walk has been cancelled + * @throws IOException if an I/O Error occurs + */ + protected boolean handleIsCancelled( + File file, int depth, Collection results) throws IOException { + // do nothing - overridable by subclass + return false; // not cancelled + } + + /** + * Overridable callback method invoked when the operation is cancelled. + * The file being processed when the cancellation occurred can be + * obtained from the exception. + *

+ * This implementation just re-throws the {@link CancelException}. + * + * @param startDirectory the directory that the walk started from + * @param results the collection of result objects, may be updated + * @param cancel the exception throw to cancel further processing + * containing details at the point of cancellation. + * @throws IOException if an I/O Error occurs + */ + protected void handleCancelled(File startDirectory, Collection results, + CancelException cancel) throws IOException { + // re-throw exception - overridable by subclass + throw cancel; + } + + //----------------------------------------------------------------------- + /** + * Overridable callback method invoked at the start of processing. + *

+ * This implementation does nothing. + * + * @param startDirectory the directory to start from + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected void handleStart(File startDirectory, Collection results) throws IOException { + // do nothing - overridable by subclass + } + + /** + * Overridable callback method invoked to determine if a directory should be processed. + *

+ * This method returns a boolean to indicate if the directory should be examined or not. + * If you return false, the entire directory and any subdirectories will be skipped. + * Note that this functionality is in addition to the filtering by file filter. + *

+ * This implementation does nothing and returns true. + * + * @param directory the current directory being processed + * @param depth the current directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @return true to process this directory, false to skip this directory + * @throws IOException if an I/O Error occurs + */ + protected boolean handleDirectory(File directory, int depth, Collection results) throws IOException { + // do nothing - overridable by subclass + return true; // process directory + } + + /** + * Overridable callback method invoked at the start of processing each directory. + *

+ * This implementation does nothing. + * + * @param directory the current directory being processed + * @param depth the current directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected void handleDirectoryStart(File directory, int depth, Collection results) throws IOException { + // do nothing - overridable by subclass + } + + /** + * Overridable callback method invoked with the contents of each directory. + *

+ * This implementation returns the files unchanged + * + * @param directory the current directory being processed + * @param depth the current directory level (starting directory = 0) + * @param files the files (possibly filtered) in the directory + * @return the filtered list of files + * @throws IOException if an I/O Error occurs + * @since Commons IO 2.0 + */ + protected File[] filterDirectoryContents(File directory, int depth, File[] files) throws IOException { + return files; + } + + /** + * Overridable callback method invoked for each (non-directory) file. + *

+ * This implementation does nothing. + * + * @param file the current file being processed + * @param depth the current directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected void handleFile(File file, int depth, Collection results) throws IOException { + // do nothing - overridable by subclass + } + + /** + * Overridable callback method invoked for each restricted directory. + *

+ * This implementation does nothing. + * + * @param directory the restricted directory + * @param depth the current directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected void handleRestricted(File directory, int depth, Collection results) throws IOException { + // do nothing - overridable by subclass + } + + /** + * Overridable callback method invoked at the end of processing each directory. + *

+ * This implementation does nothing. + * + * @param directory the directory being processed + * @param depth the current directory level (starting directory = 0) + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected void handleDirectoryEnd(File directory, int depth, Collection results) throws IOException { + // do nothing - overridable by subclass + } + + /** + * Overridable callback method invoked at the end of processing. + *

+ * This implementation does nothing. + * + * @param results the collection of result objects, may be updated + * @throws IOException if an I/O Error occurs + */ + protected void handleEnd(Collection results) throws IOException { + // do nothing - overridable by subclass + } + + //----------------------------------------------------------------------- + /** + * CancelException is thrown in DirectoryWalker to cancel the current + * processing. + */ + public static class CancelException extends IOException { + + /** Serialization id. */ + private static final long serialVersionUID = 1347339620135041008L; + + /** The file being processed when the exception was thrown. */ + private final File file; + /** The file depth when the exception was thrown. */ + private final int depth; + + /** + * Constructs a CancelException with + * the file and depth when cancellation occurred. + * + * @param file the file when the operation was cancelled, may be null + * @param depth the depth when the operation was cancelled, may be null + */ + public CancelException(File file, int depth) { + this("Operation Cancelled", file, depth); + } + + /** + * Constructs a CancelException with + * an appropriate message and the file and depth when + * cancellation occurred. + * + * @param message the detail message + * @param file the file when the operation was cancelled + * @param depth the depth when the operation was cancelled + */ + public CancelException(String message, File file, int depth) { + super(message); + this.file = file; + this.depth = depth; + } + + /** + * Return the file when the operation was cancelled. + * + * @return the file when the operation was cancelled + */ + public File getFile() { + return file; + } + + /** + * Return the depth when the operation was cancelled. + * + * @return the depth when the operation was cancelled + */ + public int getDepth() { + return depth; + } + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/EndianUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/EndianUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/EndianUtils.java 1 Oct 2012 13:03:03 -0000 1.1 @@ -0,0 +1,489 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Utility code for dealing with different endian systems. + *

+ * Different computer architectures adopt different conventions for + * byte ordering. In so-called "Little Endian" architectures (eg Intel), + * the low-order byte is stored in memory at the lowest address, and + * subsequent bytes at higher addresses. For "Big Endian" architectures + * (eg Motorola), the situation is reversed. + * This class helps you solve this incompatability. + *

+ * Origin of code: Excalibur + * + * @author Peter Donald + * @version $Id: EndianUtils.java,v 1.1 2012/10/01 13:03:03 marcin Exp $ + * @see org.apache.commons.io.input.SwappedDataInputStream + */ +public class EndianUtils { + + /** + * Instances should NOT be constructed in standard programming. + */ + public EndianUtils() { + super(); + } + + // ========================================== Swapping routines + + /** + * Converts a "short" value between endian systems. + * @param value value to convert + * @return the converted value + */ + public static short swapShort(short value) { + return (short) ( ( ( ( value >> 0 ) & 0xff ) << 8 ) + + ( ( ( value >> 8 ) & 0xff ) << 0 ) ); + } + + /** + * Converts a "int" value between endian systems. + * @param value value to convert + * @return the converted value + */ + public static int swapInteger(int value) { + return + ( ( ( value >> 0 ) & 0xff ) << 24 ) + + ( ( ( value >> 8 ) & 0xff ) << 16 ) + + ( ( ( value >> 16 ) & 0xff ) << 8 ) + + ( ( ( value >> 24 ) & 0xff ) << 0 ); + } + + /** + * Converts a "long" value between endian systems. + * @param value value to convert + * @return the converted value + */ + public static long swapLong(long value) { + return + ( ( ( value >> 0 ) & 0xff ) << 56 ) + + ( ( ( value >> 8 ) & 0xff ) << 48 ) + + ( ( ( value >> 16 ) & 0xff ) << 40 ) + + ( ( ( value >> 24 ) & 0xff ) << 32 ) + + ( ( ( value >> 32 ) & 0xff ) << 24 ) + + ( ( ( value >> 40 ) & 0xff ) << 16 ) + + ( ( ( value >> 48 ) & 0xff ) << 8 ) + + ( ( ( value >> 56 ) & 0xff ) << 0 ); + } + + /** + * Converts a "float" value between endian systems. + * @param value value to convert + * @return the converted value + */ + public static float swapFloat(float value) { + return Float.intBitsToFloat( swapInteger( Float.floatToIntBits( value ) ) ); + } + + /** + * Converts a "double" value between endian systems. + * @param value value to convert + * @return the converted value + */ + public static double swapDouble(double value) { + return Double.longBitsToDouble( swapLong( Double.doubleToLongBits( value ) ) ); + } + + // ========================================== Swapping read/write routines + + /** + * Writes a "short" value to a byte array at a given offset. The value is + * converted to the opposed endian system while writing. + * @param data target byte array + * @param offset starting offset in the byte array + * @param value value to write + */ + public static void writeSwappedShort(byte[] data, int offset, short value) { + data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff ); + data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff ); + } + + /** + * Reads a "short" value from a byte array at a given offset. The value is + * converted to the opposed endian system while reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static short readSwappedShort(byte[] data, int offset) { + return (short)( ( ( data[ offset + 0 ] & 0xff ) << 0 ) + + ( ( data[ offset + 1 ] & 0xff ) << 8 ) ); + } + + /** + * Reads an unsigned short (16-bit) value from a byte array at a given + * offset. The value is converted to the opposed endian system while + * reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static int readSwappedUnsignedShort(byte[] data, int offset) { + return ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) + + ( ( data[ offset + 1 ] & 0xff ) << 8 ) ); + } + + /** + * Writes a "int" value to a byte array at a given offset. The value is + * converted to the opposed endian system while writing. + * @param data target byte array + * @param offset starting offset in the byte array + * @param value value to write + */ + public static void writeSwappedInteger(byte[] data, int offset, int value) { + data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff ); + data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff ); + data[ offset + 2 ] = (byte)( ( value >> 16 ) & 0xff ); + data[ offset + 3 ] = (byte)( ( value >> 24 ) & 0xff ); + } + + /** + * Reads a "int" value from a byte array at a given offset. The value is + * converted to the opposed endian system while reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static int readSwappedInteger(byte[] data, int offset) { + return ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) + + ( ( data[ offset + 1 ] & 0xff ) << 8 ) + + ( ( data[ offset + 2 ] & 0xff ) << 16 ) + + ( ( data[ offset + 3 ] & 0xff ) << 24 ) ); + } + + /** + * Reads an unsigned integer (32-bit) value from a byte array at a given + * offset. The value is converted to the opposed endian system while + * reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static long readSwappedUnsignedInteger(byte[] data, int offset) { + long low = ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) + + ( ( data[ offset + 1 ] & 0xff ) << 8 ) + + ( ( data[ offset + 2 ] & 0xff ) << 16 ) ); + + long high = data[ offset + 3 ] & 0xff; + + return (high << 24) + (0xffffffffL & low); + } + + /** + * Writes a "long" value to a byte array at a given offset. The value is + * converted to the opposed endian system while writing. + * @param data target byte array + * @param offset starting offset in the byte array + * @param value value to write + */ + public static void writeSwappedLong(byte[] data, int offset, long value) { + data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff ); + data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff ); + data[ offset + 2 ] = (byte)( ( value >> 16 ) & 0xff ); + data[ offset + 3 ] = (byte)( ( value >> 24 ) & 0xff ); + data[ offset + 4 ] = (byte)( ( value >> 32 ) & 0xff ); + data[ offset + 5 ] = (byte)( ( value >> 40 ) & 0xff ); + data[ offset + 6 ] = (byte)( ( value >> 48 ) & 0xff ); + data[ offset + 7 ] = (byte)( ( value >> 56 ) & 0xff ); + } + + /** + * Reads a "long" value from a byte array at a given offset. The value is + * converted to the opposed endian system while reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static long readSwappedLong(byte[] data, int offset) { + long low = + ( ( data[ offset + 0 ] & 0xff ) << 0 ) + + ( ( data[ offset + 1 ] & 0xff ) << 8 ) + + ( ( data[ offset + 2 ] & 0xff ) << 16 ) + + ( ( data[ offset + 3 ] & 0xff ) << 24 ); + long high = + ( ( data[ offset + 4 ] & 0xff ) << 0 ) + + ( ( data[ offset + 5 ] & 0xff ) << 8 ) + + ( ( data[ offset + 6 ] & 0xff ) << 16 ) + + ( ( data[ offset + 7 ] & 0xff ) << 24 ); + return (high << 32) + (0xffffffffL & low); + } + + /** + * Writes a "float" value to a byte array at a given offset. The value is + * converted to the opposed endian system while writing. + * @param data target byte array + * @param offset starting offset in the byte array + * @param value value to write + */ + public static void writeSwappedFloat(byte[] data, int offset, float value) { + writeSwappedInteger( data, offset, Float.floatToIntBits( value ) ); + } + + /** + * Reads a "float" value from a byte array at a given offset. The value is + * converted to the opposed endian system while reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static float readSwappedFloat(byte[] data, int offset) { + return Float.intBitsToFloat( readSwappedInteger( data, offset ) ); + } + + /** + * Writes a "double" value to a byte array at a given offset. The value is + * converted to the opposed endian system while writing. + * @param data target byte array + * @param offset starting offset in the byte array + * @param value value to write + */ + public static void writeSwappedDouble(byte[] data, int offset, double value) { + writeSwappedLong( data, offset, Double.doubleToLongBits( value ) ); + } + + /** + * Reads a "double" value from a byte array at a given offset. The value is + * converted to the opposed endian system while reading. + * @param data source byte array + * @param offset starting offset in the byte array + * @return the value read + */ + public static double readSwappedDouble(byte[] data, int offset) { + return Double.longBitsToDouble( readSwappedLong( data, offset ) ); + } + + /** + * Writes a "short" value to an OutputStream. The value is + * converted to the opposed endian system while writing. + * @param output target OutputStream + * @param value value to write + * @throws IOException in case of an I/O problem + */ + public static void writeSwappedShort(OutputStream output, short value) + throws IOException + { + output.write( (byte)( ( value >> 0 ) & 0xff ) ); + output.write( (byte)( ( value >> 8 ) & 0xff ) ); + } + + /** + * Reads a "short" value from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static short readSwappedShort(InputStream input) + throws IOException + { + return (short)( ( ( read( input ) & 0xff ) << 0 ) + + ( ( read( input ) & 0xff ) << 8 ) ); + } + + /** + * Reads a unsigned short (16-bit) from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static int readSwappedUnsignedShort(InputStream input) + throws IOException + { + int value1 = read( input ); + int value2 = read( input ); + + return ( ( ( value1 & 0xff ) << 0 ) + + ( ( value2 & 0xff ) << 8 ) ); + } + + /** + * Writes a "int" value to an OutputStream. The value is + * converted to the opposed endian system while writing. + * @param output target OutputStream + * @param value value to write + * @throws IOException in case of an I/O problem + */ + public static void writeSwappedInteger(OutputStream output, int value) + throws IOException + { + output.write( (byte)( ( value >> 0 ) & 0xff ) ); + output.write( (byte)( ( value >> 8 ) & 0xff ) ); + output.write( (byte)( ( value >> 16 ) & 0xff ) ); + output.write( (byte)( ( value >> 24 ) & 0xff ) ); + } + + /** + * Reads a "int" value from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static int readSwappedInteger(InputStream input) + throws IOException + { + int value1 = read( input ); + int value2 = read( input ); + int value3 = read( input ); + int value4 = read( input ); + + return ( ( value1 & 0xff ) << 0 ) + + ( ( value2 & 0xff ) << 8 ) + + ( ( value3 & 0xff ) << 16 ) + + ( ( value4 & 0xff ) << 24 ); + } + + /** + * Reads a unsigned integer (32-bit) from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static long readSwappedUnsignedInteger(InputStream input) + throws IOException + { + int value1 = read( input ); + int value2 = read( input ); + int value3 = read( input ); + int value4 = read( input ); + + long low = ( ( ( value1 & 0xff ) << 0 ) + + ( ( value2 & 0xff ) << 8 ) + + ( ( value3 & 0xff ) << 16 ) ); + + long high = value4 & 0xff; + + return (high << 24) + (0xffffffffL & low); + } + + /** + * Writes a "long" value to an OutputStream. The value is + * converted to the opposed endian system while writing. + * @param output target OutputStream + * @param value value to write + * @throws IOException in case of an I/O problem + */ + public static void writeSwappedLong(OutputStream output, long value) + throws IOException + { + output.write( (byte)( ( value >> 0 ) & 0xff ) ); + output.write( (byte)( ( value >> 8 ) & 0xff ) ); + output.write( (byte)( ( value >> 16 ) & 0xff ) ); + output.write( (byte)( ( value >> 24 ) & 0xff ) ); + output.write( (byte)( ( value >> 32 ) & 0xff ) ); + output.write( (byte)( ( value >> 40 ) & 0xff ) ); + output.write( (byte)( ( value >> 48 ) & 0xff ) ); + output.write( (byte)( ( value >> 56 ) & 0xff ) ); + } + + /** + * Reads a "long" value from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static long readSwappedLong(InputStream input) + throws IOException + { + byte[] bytes = new byte[8]; + for ( int i=0; i<8; i++ ) { + bytes[i] = (byte) read( input ); + } + return readSwappedLong( bytes, 0 ); + } + + /** + * Writes a "float" value to an OutputStream. The value is + * converted to the opposed endian system while writing. + * @param output target OutputStream + * @param value value to write + * @throws IOException in case of an I/O problem + */ + public static void writeSwappedFloat(OutputStream output, float value) + throws IOException + { + writeSwappedInteger( output, Float.floatToIntBits( value ) ); + } + + /** + * Reads a "float" value from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static float readSwappedFloat(InputStream input) + throws IOException + { + return Float.intBitsToFloat( readSwappedInteger( input ) ); + } + + /** + * Writes a "double" value to an OutputStream. The value is + * converted to the opposed endian system while writing. + * @param output target OutputStream + * @param value value to write + * @throws IOException in case of an I/O problem + */ + public static void writeSwappedDouble(OutputStream output, double value) + throws IOException + { + writeSwappedLong( output, Double.doubleToLongBits( value ) ); + } + + /** + * Reads a "double" value from an InputStream. The value is + * converted to the opposed endian system while reading. + * @param input source InputStream + * @return the value just read + * @throws IOException in case of an I/O problem + */ + public static double readSwappedDouble(InputStream input) + throws IOException + { + return Double.longBitsToDouble( readSwappedLong( input ) ); + } + + /** + * Reads the next byte from the input stream. + * @param input the stream + * @return the byte + * @throws IOException if the end of file is reached + */ + private static int read(InputStream input) + throws IOException + { + int value = input.read(); + + if( -1 == value ) { + throw new EOFException( "Unexpected EOF reached" ); + } + + return value; + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/FileCleaner.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/FileCleaner.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/FileCleaner.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.File; + +/** + * Keeps track of files awaiting deletion, and deletes them when an associated + * marker object is reclaimed by the garbage collector. + *

+ * This utility creates a background thread to handle file deletion. + * Each file to be deleted is registered with a handler object. + * When the handler object is garbage collected, the file is deleted. + *

+ * In an environment with multiple class loaders (a servlet container, for + * example), you should consider stopping the background thread if it is no + * longer needed. This is done by invoking the method + * {@link #exitWhenFinished}, typically in + * {@link javax.servlet.ServletContextListener#contextDestroyed} or similar. + * + * @author Noel Bergman + * @author Martin Cooper + * @version $Id: FileCleaner.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + * @deprecated Use {@link FileCleaningTracker} + */ +@Deprecated +public class FileCleaner { + /** + * The instance to use for the deprecated, static methods. + */ + static final FileCleaningTracker theInstance = new FileCleaningTracker(); + + //----------------------------------------------------------------------- + /** + * Track the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. + * + * @param file the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @throws NullPointerException if the file is null + * @deprecated Use {@link FileCleaningTracker#track(File, Object)}. + */ + @Deprecated + public static void track(File file, Object marker) { + theInstance.track(file, marker); + } + + /** + * Track the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The speified deletion strategy is used. + * + * @param file the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @param deleteStrategy the strategy to delete the file, null means normal + * @throws NullPointerException if the file is null + * @deprecated Use {@link FileCleaningTracker#track(File, Object, FileDeleteStrategy)}. + */ + @Deprecated + public static void track(File file, Object marker, FileDeleteStrategy deleteStrategy) { + theInstance.track(file, marker, deleteStrategy); + } + + /** + * Track the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. + * + * @param path the full path to the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @throws NullPointerException if the path is null + * @deprecated Use {@link FileCleaningTracker#track(String, Object)}. + */ + @Deprecated + public static void track(String path, Object marker) { + theInstance.track(path, marker); + } + + /** + * Track the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The speified deletion strategy is used. + * + * @param path the full path to the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @param deleteStrategy the strategy to delete the file, null means normal + * @throws NullPointerException if the path is null + * @deprecated Use {@link FileCleaningTracker#track(String, Object, FileDeleteStrategy)}. + */ + @Deprecated + public static void track(String path, Object marker, FileDeleteStrategy deleteStrategy) { + theInstance.track(path, marker, deleteStrategy); + } + + //----------------------------------------------------------------------- + /** + * Retrieve the number of files currently being tracked, and therefore + * awaiting deletion. + * + * @return the number of files being tracked + * @deprecated Use {@link FileCleaningTracker#getTrackCount()}. + */ + @Deprecated + public static int getTrackCount() { + return theInstance.getTrackCount(); + } + + /** + * Call this method to cause the file cleaner thread to terminate when + * there are no more objects being tracked for deletion. + *

+ * In a simple environment, you don't need this method as the file cleaner + * thread will simply exit when the JVM exits. In a more complex environment, + * with multiple class loaders (such as an application server), you should be + * aware that the file cleaner thread will continue running even if the class + * loader it was started from terminates. This can consitute a memory leak. + *

+ * For example, suppose that you have developed a web application, which + * contains the commons-io jar file in your WEB-INF/lib directory. In other + * words, the FileCleaner class is loaded through the class loader of your + * web application. If the web application is terminated, but the servlet + * container is still running, then the file cleaner thread will still exist, + * posing a memory leak. + *

+ * This method allows the thread to be terminated. Simply call this method + * in the resource cleanup code, such as {@link javax.servlet.ServletContextListener#contextDestroyed}. + * One called, no new objects can be tracked by the file cleaner. + * @deprecated Use {@link FileCleaningTracker#exitWhenFinished()}. + */ + @Deprecated + public static synchronized void exitWhenFinished() { + theInstance.exitWhenFinished(); + } + + /** + * Returns the singleton instance, which is used by the deprecated, static methods. + * This is mainly useful for code, which wants to support the new + * {@link FileCleaningTracker} class while maintain compatibility with the + * deprecated {@link FileCleaner}. + * + * @return the singleton instance + */ + public static FileCleaningTracker getInstance() { + return theInstance; + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/FileCleaningTracker.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/FileCleaningTracker.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/FileCleaningTracker.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,284 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.File; +import java.lang.ref.PhantomReference; +import java.lang.ref.ReferenceQueue; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; + +/** + * Keeps track of files awaiting deletion, and deletes them when an associated + * marker object is reclaimed by the garbage collector. + *

+ * This utility creates a background thread to handle file deletion. + * Each file to be deleted is registered with a handler object. + * When the handler object is garbage collected, the file is deleted. + *

+ * In an environment with multiple class loaders (a servlet container, for + * example), you should consider stopping the background thread if it is no + * longer needed. This is done by invoking the method + * {@link #exitWhenFinished}, typically in + * {@link javax.servlet.ServletContextListener#contextDestroyed} or similar. + * + * @author Noel Bergman + * @author Martin Cooper + * @version $Id: FileCleaningTracker.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + */ +public class FileCleaningTracker { + /** + * Queue of Tracker instances being watched. + */ + ReferenceQueue q = new ReferenceQueue(); + /** + * Collection of Tracker instances in existence. + */ + final Collection trackers = Collections.synchronizedSet(new HashSet()); // synchronized + /** + * Collection of File paths that failed to delete. + */ + final List deleteFailures = Collections.synchronizedList(new ArrayList()); + /** + * Whether to terminate the thread when the tracking is complete. + */ + volatile boolean exitWhenFinished = false; + /** + * The thread that will clean up registered files. + */ + Thread reaper; + + //----------------------------------------------------------------------- + /** + * Track the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. + * + * @param file the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @throws NullPointerException if the file is null + */ + public void track(File file, Object marker) { + track(file, marker, (FileDeleteStrategy) null); + } + + /** + * Track the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The speified deletion strategy is used. + * + * @param file the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @param deleteStrategy the strategy to delete the file, null means normal + * @throws NullPointerException if the file is null + */ + public void track(File file, Object marker, FileDeleteStrategy deleteStrategy) { + if (file == null) { + throw new NullPointerException("The file must not be null"); + } + addTracker(file.getPath(), marker, deleteStrategy); + } + + /** + * Track the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. + * + * @param path the full path to the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @throws NullPointerException if the path is null + */ + public void track(String path, Object marker) { + track(path, marker, (FileDeleteStrategy) null); + } + + /** + * Track the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The speified deletion strategy is used. + * + * @param path the full path to the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @param deleteStrategy the strategy to delete the file, null means normal + * @throws NullPointerException if the path is null + */ + public void track(String path, Object marker, FileDeleteStrategy deleteStrategy) { + if (path == null) { + throw new NullPointerException("The path must not be null"); + } + addTracker(path, marker, deleteStrategy); + } + + /** + * Adds a tracker to the list of trackers. + * + * @param path the full path to the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @param deleteStrategy the strategy to delete the file, null means normal + */ + private synchronized void addTracker(String path, Object marker, FileDeleteStrategy deleteStrategy) { + // synchronized block protects reaper + if (exitWhenFinished) { + throw new IllegalStateException("No new trackers can be added once exitWhenFinished() is called"); + } + if (reaper == null) { + reaper = new Reaper(); + reaper.start(); + } + trackers.add(new Tracker(path, deleteStrategy, marker, q)); + } + + //----------------------------------------------------------------------- + /** + * Retrieve the number of files currently being tracked, and therefore + * awaiting deletion. + * + * @return the number of files being tracked + */ + public int getTrackCount() { + return trackers.size(); + } + + /** + * Return the file paths that failed to delete. + * + * @return the file paths that failed to delete + * @since Commons IO 2.0 + */ + public List getDeleteFailures() { + return deleteFailures; + } + + /** + * Call this method to cause the file cleaner thread to terminate when + * there are no more objects being tracked for deletion. + *

+ * In a simple environment, you don't need this method as the file cleaner + * thread will simply exit when the JVM exits. In a more complex environment, + * with multiple class loaders (such as an application server), you should be + * aware that the file cleaner thread will continue running even if the class + * loader it was started from terminates. This can consitute a memory leak. + *

+ * For example, suppose that you have developed a web application, which + * contains the commons-io jar file in your WEB-INF/lib directory. In other + * words, the FileCleaner class is loaded through the class loader of your + * web application. If the web application is terminated, but the servlet + * container is still running, then the file cleaner thread will still exist, + * posing a memory leak. + *

+ * This method allows the thread to be terminated. Simply call this method + * in the resource cleanup code, such as {@link javax.servlet.ServletContextListener#contextDestroyed}. + * Once called, no new objects can be tracked by the file cleaner. + */ + public synchronized void exitWhenFinished() { + // synchronized block protects reaper + exitWhenFinished = true; + if (reaper != null) { + synchronized (reaper) { + reaper.interrupt(); + } + } + } + + //----------------------------------------------------------------------- + /** + * The reaper thread. + */ + private final class Reaper extends Thread { + /** Construct a new Reaper */ + Reaper() { + super("File Reaper"); + setPriority(Thread.MAX_PRIORITY); + setDaemon(true); + } + + /** + * Run the reaper thread that will delete files as their associated + * marker objects are reclaimed by the garbage collector. + */ + @Override + public void run() { + // thread exits when exitWhenFinished is true and there are no more tracked objects + while (exitWhenFinished == false || trackers.size() > 0) { + try { + // Wait for a tracker to remove. + Tracker tracker = (Tracker) q.remove(); // cannot return null + trackers.remove(tracker); + if (!tracker.delete()) { + deleteFailures.add(tracker.getPath()); + } + tracker.clear(); + } catch (InterruptedException e) { + continue; + } + } + } + } + + //----------------------------------------------------------------------- + /** + * Inner class which acts as the reference for a file pending deletion. + */ + private static final class Tracker extends PhantomReference { + + /** + * The full path to the file being tracked. + */ + private final String path; + /** + * The strategy for deleting files. + */ + private final FileDeleteStrategy deleteStrategy; + + /** + * Constructs an instance of this class from the supplied parameters. + * + * @param path the full path to the file to be tracked, not null + * @param deleteStrategy the strategy to delete the file, null means normal + * @param marker the marker object used to track the file, not null + * @param queue the queue on to which the tracker will be pushed, not null + */ + Tracker(String path, FileDeleteStrategy deleteStrategy, Object marker, ReferenceQueue queue) { + super(marker, queue); + this.path = path; + this.deleteStrategy = (deleteStrategy == null ? FileDeleteStrategy.NORMAL : deleteStrategy); + } + + /** + * Return the path. + * + * @return the path + */ + public String getPath() { + return path; + } + + /** + * Deletes the file associated with this tracker instance. + * + * @return true if the file was deleted successfully; + * false otherwise. + */ + public boolean delete() { + return deleteStrategy.deleteQuietly(new File(path)); + } + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/FileDeleteStrategy.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/FileDeleteStrategy.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/FileDeleteStrategy.java 1 Oct 2012 13:03:03 -0000 1.1 @@ -0,0 +1,158 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.File; +import java.io.IOException; + +/** + * Strategy for deleting files. + *

+ * There is more than one way to delete a file. + * You may want to limit access to certain directories, to only delete + * directories if they are empty, or maybe to force deletion. + *

+ * This class captures the strategy to use and is designed for user subclassing. + * + * @author Stephen Colebourne + * @version $Id: FileDeleteStrategy.java,v 1.1 2012/10/01 13:03:03 marcin Exp $ + * @since Commons IO 1.3 + */ +public class FileDeleteStrategy { + + /** + * The singleton instance for normal file deletion, which does not permit + * the deletion of directories that are not empty. + */ + public static final FileDeleteStrategy NORMAL = new FileDeleteStrategy("Normal"); + /** + * The singleton instance for forced file deletion, which always deletes, + * even if the file represents a non-empty directory. + */ + public static final FileDeleteStrategy FORCE = new ForceFileDeleteStrategy(); + + /** The name of the strategy. */ + private final String name; + + //----------------------------------------------------------------------- + /** + * Restricted constructor. + * + * @param name the name by which the strategy is known + */ + protected FileDeleteStrategy(String name) { + this.name = name; + } + + //----------------------------------------------------------------------- + /** + * Deletes the file object, which may be a file or a directory. + * All IOExceptions are caught and false returned instead. + * If the file does not exist or is null, true is returned. + *

+ * Subclass writers should override {@link #doDelete(File)}, not this method. + * + * @param fileToDelete the file to delete, null returns true + * @return true if the file was deleted, or there was no such file + */ + public boolean deleteQuietly(File fileToDelete) { + if (fileToDelete == null || fileToDelete.exists() == false) { + return true; + } + try { + return doDelete(fileToDelete); + } catch (IOException ex) { + return false; + } + } + + /** + * Deletes the file object, which may be a file or a directory. + * If the file does not exist, the method just returns. + *

+ * Subclass writers should override {@link #doDelete(File)}, not this method. + * + * @param fileToDelete the file to delete, not null + * @throws NullPointerException if the file is null + * @throws IOException if an error occurs during file deletion + */ + public void delete(File fileToDelete) throws IOException { + if (fileToDelete.exists() && doDelete(fileToDelete) == false) { + throw new IOException("Deletion failed: " + fileToDelete); + } + } + + /** + * Actually deletes the file object, which may be a file or a directory. + *

+ * This method is designed for subclasses to override. + * The implementation may return either false or an IOException + * when deletion fails. The {@link #delete(File)} and {@link #deleteQuietly(File)} + * methods will handle either response appropriately. + * A check has been made to ensure that the file will exist. + *

+ * This implementation uses {@link File#delete()}. + * + * @param fileToDelete the file to delete, exists, not null + * @return true if the file was deleteds + * @throws NullPointerException if the file is null + * @throws IOException if an error occurs during file deletion + */ + protected boolean doDelete(File fileToDelete) throws IOException { + return fileToDelete.delete(); + } + + //----------------------------------------------------------------------- + /** + * Gets a string describing the delete strategy. + * + * @return a string describing the delete strategy + */ + @Override + public String toString() { + return "FileDeleteStrategy[" + name + "]"; + } + + //----------------------------------------------------------------------- + /** + * Force file deletion strategy. + */ + static class ForceFileDeleteStrategy extends FileDeleteStrategy { + /** Default Constructor */ + ForceFileDeleteStrategy() { + super("Force"); + } + + /** + * Deletes the file object. + *

+ * This implementation uses FileUtils.forceDelete() + * if the file exists. + * + * @param fileToDelete the file to delete, not null + * @return Always returns true + * @throws NullPointerException if the file is null + * @throws IOException if an error occurs during file deletion + */ + @Override + protected boolean doDelete(File fileToDelete) throws IOException { + FileUtils.forceDelete(fileToDelete); + return true; + } + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/FileExistsException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/FileExistsException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/FileExistsException.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.File; +import java.io.IOException; + +/** + * Indicates that a file already exists. + * + * @version $Id: FileExistsException.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + * @since Commons IO 2.0 + */ +public class FileExistsException extends IOException { + + /** + * Defines the serial version UID. + */ + private static final long serialVersionUID = 1L; + + /** + * Default Constructor. + */ + public FileExistsException() { + super(); + } + + /** + * Construct an instance with the specified message. + * + * @param message The error message + */ + public FileExistsException(String message) { + super(message); + } + + /** + * Construct an instance with the specified file. + * + * @param file The file that exists + */ + public FileExistsException(File file) { + super("File " + file + " exists"); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/FileSystemUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/FileSystemUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/FileSystemUtils.java 1 Oct 2012 13:03:03 -0000 1.1 @@ -0,0 +1,544 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.StringTokenizer; + +/** + * General File System utilities. + *

+ * This class provides static utility methods for general file system + * functions not provided via the JDK {@link java.io.File File} class. + *

+ * The current functions provided are: + *

    + *
  • Get the free space on a drive + *
+ * + * @author Frank W. Zammetti + * @author Stephen Colebourne + * @author Thomas Ledoux + * @author James Urie + * @author Magnus Grimsell + * @author Thomas Ledoux + * @version $Id: FileSystemUtils.java,v 1.1 2012/10/01 13:03:03 marcin Exp $ + * @since Commons IO 1.1 + */ +public class FileSystemUtils { + + /** Singleton instance, used mainly for testing. */ + private static final FileSystemUtils INSTANCE = new FileSystemUtils(); + + /** Operating system state flag for error. */ + private static final int INIT_PROBLEM = -1; + /** Operating system state flag for neither Unix nor Windows. */ + private static final int OTHER = 0; + /** Operating system state flag for Windows. */ + private static final int WINDOWS = 1; + /** Operating system state flag for Unix. */ + private static final int UNIX = 2; + /** Operating system state flag for Posix flavour Unix. */ + private static final int POSIX_UNIX = 3; + + /** The operating system flag. */ + private static final int OS; + + /** The path to df */ + private static final String DF; + + static { + int os = OTHER; + String dfPath = "df"; + try { + String osName = System.getProperty("os.name"); + if (osName == null) { + throw new IOException("os.name not found"); + } + osName = osName.toLowerCase(Locale.ENGLISH); + // match + if (osName.indexOf("windows") != -1) { + os = WINDOWS; + } else if (osName.indexOf("linux") != -1 || + osName.indexOf("mpe/ix") != -1 || + osName.indexOf("freebsd") != -1 || + osName.indexOf("irix") != -1 || + osName.indexOf("digital unix") != -1 || + osName.indexOf("unix") != -1 || + osName.indexOf("mac os x") != -1) { + os = UNIX; + } else if (osName.indexOf("sun os") != -1 || + osName.indexOf("sunos") != -1 || + osName.indexOf("solaris") != -1) { + os = POSIX_UNIX; + dfPath = "/usr/xpg4/bin/df"; + } else if (osName.indexOf("hp-ux") != -1 || + osName.indexOf("aix") != -1) { + os = POSIX_UNIX; + } else { + os = OTHER; + } + + } catch (Exception ex) { + os = INIT_PROBLEM; + } + OS = os; + DF = dfPath; + } + + /** + * Instances should NOT be constructed in standard programming. + */ + public FileSystemUtils() { + super(); + } + + //----------------------------------------------------------------------- + /** + * Returns the free space on a drive or volume by invoking + * the command line. + * This method does not normalize the result, and typically returns + * bytes on Windows, 512 byte units on OS X and kilobytes on Unix. + * As this is not very useful, this method is deprecated in favour + * of {@link #freeSpaceKb(String)} which returns a result in kilobytes. + *

+ * Note that some OS's are NOT currently supported, including OS/390, + * OpenVMS. + *

+     * FileSystemUtils.freeSpace("C:");       // Windows
+     * FileSystemUtils.freeSpace("/volume");  // *nix
+     * 
+ * The free space is calculated via the command line. + * It uses 'dir /-c' on Windows and 'df' on *nix. + * + * @param path the path to get free space for, not null, not empty on Unix + * @return the amount of free drive space on the drive or volume + * @throws IllegalArgumentException if the path is invalid + * @throws IllegalStateException if an error occurred in initialisation + * @throws IOException if an error occurs when finding the free space + * @since Commons IO 1.1, enhanced OS support in 1.2 and 1.3 + * @deprecated Use freeSpaceKb(String) + * Deprecated from 1.3, may be removed in 2.0 + */ + @Deprecated + public static long freeSpace(String path) throws IOException { + return INSTANCE.freeSpaceOS(path, OS, false, -1); + } + + //----------------------------------------------------------------------- + /** + * Returns the free space on a drive or volume in kilobytes by invoking + * the command line. + *
+     * FileSystemUtils.freeSpaceKb("C:");       // Windows
+     * FileSystemUtils.freeSpaceKb("/volume");  // *nix
+     * 
+ * The free space is calculated via the command line. + * It uses 'dir /-c' on Windows, 'df -kP' on AIX/HP-UX and 'df -k' on other Unix. + *

+ * In order to work, you must be running Windows, or have a implementation of + * Unix df that supports GNU format when passed -k (or -kP). If you are going + * to rely on this code, please check that it works on your OS by running + * some simple tests to compare the command line with the output from this class. + * If your operating system isn't supported, please raise a JIRA call detailing + * the exact result from df -k and as much other detail as possible, thanks. + * + * @param path the path to get free space for, not null, not empty on Unix + * @return the amount of free drive space on the drive or volume in kilobytes + * @throws IllegalArgumentException if the path is invalid + * @throws IllegalStateException if an error occurred in initialisation + * @throws IOException if an error occurs when finding the free space + * @since Commons IO 1.2, enhanced OS support in 1.3 + */ + public static long freeSpaceKb(String path) throws IOException { + return freeSpaceKb(path, -1); + } + /** + * Returns the free space on a drive or volume in kilobytes by invoking + * the command line. + *

+     * FileSystemUtils.freeSpaceKb("C:");       // Windows
+     * FileSystemUtils.freeSpaceKb("/volume");  // *nix
+     * 
+ * The free space is calculated via the command line. + * It uses 'dir /-c' on Windows, 'df -kP' on AIX/HP-UX and 'df -k' on other Unix. + *

+ * In order to work, you must be running Windows, or have a implementation of + * Unix df that supports GNU format when passed -k (or -kP). If you are going + * to rely on this code, please check that it works on your OS by running + * some simple tests to compare the command line with the output from this class. + * If your operating system isn't supported, please raise a JIRA call detailing + * the exact result from df -k and as much other detail as possible, thanks. + * + * @param path the path to get free space for, not null, not empty on Unix + * @param timeout The timout amount in milliseconds or no timeout if the value + * is zero or less + * @return the amount of free drive space on the drive or volume in kilobytes + * @throws IllegalArgumentException if the path is invalid + * @throws IllegalStateException if an error occurred in initialisation + * @throws IOException if an error occurs when finding the free space + * @since Commons IO 2.0 + */ + public static long freeSpaceKb(String path, long timeout) throws IOException { + return INSTANCE.freeSpaceOS(path, OS, true, timeout); + } + + /** + * Returns the disk size of the volume which holds the working directory. + *

+ * Identical to: + *

+     * freeSpaceKb(new File(".").getAbsolutePath())
+     * 
+ * @return the amount of free drive space on the drive or volume in kilobytes + * @throws IllegalStateException if an error occurred in initialisation + * @throws IOException if an error occurs when finding the free space + * @since Commons IO 2.0 + */ + public static long freeSpaceKb() throws IOException { + return freeSpaceKb(-1); + } + + /** + * Returns the disk size of the volume which holds the working directory. + *

+ * Identical to: + *

+     * freeSpaceKb(new File(".").getAbsolutePath())
+     * 
+ * @param timeout The timout amount in milliseconds or no timeout if the value + * is zero or less + * @return the amount of free drive space on the drive or volume in kilobytes + * @throws IllegalStateException if an error occurred in initialisation + * @throws IOException if an error occurs when finding the free space + * @since Commons IO 2.0 + */ + public static long freeSpaceKb(long timeout) throws IOException { + return freeSpaceKb(new File(".").getAbsolutePath(), timeout); + } + + //----------------------------------------------------------------------- + /** + * Returns the free space on a drive or volume in a cross-platform manner. + * Note that some OS's are NOT currently supported, including OS/390. + *
+     * FileSystemUtils.freeSpace("C:");  // Windows
+     * FileSystemUtils.freeSpace("/volume");  // *nix
+     * 
+ * The free space is calculated via the command line. + * It uses 'dir /-c' on Windows and 'df' on *nix. + * + * @param path the path to get free space for, not null, not empty on Unix + * @param os the operating system code + * @param kb whether to normalize to kilobytes + * @param timeout The timout amount in milliseconds or no timeout if the value + * is zero or less + * @return the amount of free drive space on the drive or volume + * @throws IllegalArgumentException if the path is invalid + * @throws IllegalStateException if an error occurred in initialisation + * @throws IOException if an error occurs when finding the free space + */ + long freeSpaceOS(String path, int os, boolean kb, long timeout) throws IOException { + if (path == null) { + throw new IllegalArgumentException("Path must not be empty"); + } + switch (os) { + case WINDOWS: + return (kb ? freeSpaceWindows(path, timeout) / FileUtils.ONE_KB : freeSpaceWindows(path, timeout)); + case UNIX: + return freeSpaceUnix(path, kb, false, timeout); + case POSIX_UNIX: + return freeSpaceUnix(path, kb, true, timeout); + case OTHER: + throw new IllegalStateException("Unsupported operating system"); + default: + throw new IllegalStateException( + "Exception caught when determining operating system"); + } + } + + //----------------------------------------------------------------------- + /** + * Find free space on the Windows platform using the 'dir' command. + * + * @param path the path to get free space for, including the colon + * @param timeout The timout amount in milliseconds or no timeout if the value + * is zero or less + * @return the amount of free drive space on the drive + * @throws IOException if an error occurs + */ + long freeSpaceWindows(String path, long timeout) throws IOException { + path = FilenameUtils.normalize(path, false); + if (path.length() > 0 && path.charAt(0) != '"') { + path = "\"" + path + "\""; + } + + // build and run the 'dir' command + String[] cmdAttribs = new String[] {"cmd.exe", "/C", "dir /a /-c " + path}; + + // read in the output of the command to an ArrayList + List lines = performCommand(cmdAttribs, Integer.MAX_VALUE, timeout); + + // now iterate over the lines we just read and find the LAST + // non-empty line (the free space bytes should be in the last element + // of the ArrayList anyway, but this will ensure it works even if it's + // not, still assuming it is on the last non-blank line) + for (int i = lines.size() - 1; i >= 0; i--) { + String line = lines.get(i); + if (line.length() > 0) { + return parseDir(line, path); + } + } + // all lines are blank + throw new IOException( + "Command line 'dir /-c' did not return any info " + + "for path '" + path + "'"); + } + + /** + * Parses the Windows dir response last line + * + * @param line the line to parse + * @param path the path that was sent + * @return the number of bytes + * @throws IOException if an error occurs + */ + long parseDir(String line, String path) throws IOException { + // read from the end of the line to find the last numeric + // character on the line, then continue until we find the first + // non-numeric character, and everything between that and the last + // numeric character inclusive is our free space bytes count + int bytesStart = 0; + int bytesEnd = 0; + int j = line.length() - 1; + innerLoop1: while (j >= 0) { + char c = line.charAt(j); + if (Character.isDigit(c)) { + // found the last numeric character, this is the end of + // the free space bytes count + bytesEnd = j + 1; + break innerLoop1; + } + j--; + } + innerLoop2: while (j >= 0) { + char c = line.charAt(j); + if (!Character.isDigit(c) && c != ',' && c != '.') { + // found the next non-numeric character, this is the + // beginning of the free space bytes count + bytesStart = j + 1; + break innerLoop2; + } + j--; + } + if (j < 0) { + throw new IOException( + "Command line 'dir /-c' did not return valid info " + + "for path '" + path + "'"); + } + + // remove commas and dots in the bytes count + StringBuilder buf = new StringBuilder(line.substring(bytesStart, bytesEnd)); + for (int k = 0; k < buf.length(); k++) { + if (buf.charAt(k) == ',' || buf.charAt(k) == '.') { + buf.deleteCharAt(k--); + } + } + return parseBytes(buf.toString(), path); + } + + //----------------------------------------------------------------------- + /** + * Find free space on the *nix platform using the 'df' command. + * + * @param path the path to get free space for + * @param kb whether to normalize to kilobytes + * @param posix whether to use the posix standard format flag + * @param timeout The timout amount in milliseconds or no timeout if the value + * is zero or less + * @return the amount of free drive space on the volume + * @throws IOException if an error occurs + */ + long freeSpaceUnix(String path, boolean kb, boolean posix, long timeout) throws IOException { + if (path.length() == 0) { + throw new IllegalArgumentException("Path must not be empty"); + } + + // build and run the 'dir' command + String flags = "-"; + if (kb) { + flags += "k"; + } + if (posix) { + flags += "P"; + } + String[] cmdAttribs = + (flags.length() > 1 ? new String[] {DF, flags, path} : new String[] {DF, path}); + + // perform the command, asking for up to 3 lines (header, interesting, overflow) + List lines = performCommand(cmdAttribs, 3, timeout); + if (lines.size() < 2) { + // unknown problem, throw exception + throw new IOException( + "Command line '" + DF + "' did not return info as expected " + + "for path '" + path + "'- response was " + lines); + } + String line2 = lines.get(1); // the line we're interested in + + // Now, we tokenize the string. The fourth element is what we want. + StringTokenizer tok = new StringTokenizer(line2, " "); + if (tok.countTokens() < 4) { + // could be long Filesystem, thus data on third line + if (tok.countTokens() == 1 && lines.size() >= 3) { + String line3 = lines.get(2); // the line may be interested in + tok = new StringTokenizer(line3, " "); + } else { + throw new IOException( + "Command line '" + DF + "' did not return data as expected " + + "for path '" + path + "'- check path is valid"); + } + } else { + tok.nextToken(); // Ignore Filesystem + } + tok.nextToken(); // Ignore 1K-blocks + tok.nextToken(); // Ignore Used + String freeSpace = tok.nextToken(); + return parseBytes(freeSpace, path); + } + + //----------------------------------------------------------------------- + /** + * Parses the bytes from a string. + * + * @param freeSpace the free space string + * @param path the path + * @return the number of bytes + * @throws IOException if an error occurs + */ + long parseBytes(String freeSpace, String path) throws IOException { + try { + long bytes = Long.parseLong(freeSpace); + if (bytes < 0) { + throw new IOException( + "Command line '" + DF + "' did not find free space in response " + + "for path '" + path + "'- check path is valid"); + } + return bytes; + + } catch (NumberFormatException ex) { + throw new IOExceptionWithCause( + "Command line '" + DF + "' did not return numeric data as expected " + + "for path '" + path + "'- check path is valid", ex); + } + } + + //----------------------------------------------------------------------- + /** + * Performs the os command. + * + * @param cmdAttribs the command line parameters + * @param max The maximum limit for the lines returned + * @param timeout The timout amount in milliseconds or no timeout if the value + * is zero or less + * @return the parsed data + * @throws IOException if an error occurs + */ + List performCommand(String[] cmdAttribs, int max, long timeout) throws IOException { + // this method does what it can to avoid the 'Too many open files' error + // based on trial and error and these links: + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4784692 + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4801027 + // http://forum.java.sun.com/thread.jspa?threadID=533029&messageID=2572018 + // however, its still not perfect as the JDK support is so poor + // (see commond-exec or ant for a better multi-threaded multi-os solution) + + List lines = new ArrayList(20); + Process proc = null; + InputStream in = null; + OutputStream out = null; + InputStream err = null; + BufferedReader inr = null; + try { + + Thread monitor = ThreadMonitor.start(timeout); + + proc = openProcess(cmdAttribs); + in = proc.getInputStream(); + out = proc.getOutputStream(); + err = proc.getErrorStream(); + inr = new BufferedReader(new InputStreamReader(in)); + String line = inr.readLine(); + while (line != null && lines.size() < max) { + line = line.toLowerCase(Locale.ENGLISH).trim(); + lines.add(line); + line = inr.readLine(); + } + + proc.waitFor(); + + ThreadMonitor.stop(monitor); + + if (proc.exitValue() != 0) { + // os command problem, throw exception + throw new IOException( + "Command line returned OS error code '" + proc.exitValue() + + "' for command " + Arrays.asList(cmdAttribs)); + } + if (lines.size() == 0) { + // unknown problem, throw exception + throw new IOException( + "Command line did not return any info " + + "for command " + Arrays.asList(cmdAttribs)); + } + return lines; + + } catch (InterruptedException ex) { + throw new IOExceptionWithCause( + "Command line threw an InterruptedException " + + "for command " + Arrays.asList(cmdAttribs) + " timeout=" + timeout, ex); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(err); + IOUtils.closeQuietly(inr); + if (proc != null) { + proc.destroy(); + } + } + } + + /** + * Opens the process to the operating system. + * + * @param cmdAttribs the command line parameters + * @return the process + * @throws IOException if an error occurs + */ + Process openProcess(String[] cmdAttribs) throws IOException { + return Runtime.getRuntime().exec(cmdAttribs); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/FileUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/FileUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/FileUtils.java 1 Oct 2012 13:03:03 -0000 1.1 @@ -0,0 +1,2491 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.math.BigInteger; +import java.net.URL; +import java.net.URLConnection; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.zip.CRC32; +import java.util.zip.CheckedInputStream; +import java.util.zip.Checksum; + +import org.apache.commons.io.filefilter.DirectoryFileFilter; +import org.apache.commons.io.filefilter.FalseFileFilter; +import org.apache.commons.io.filefilter.FileFilterUtils; +import org.apache.commons.io.filefilter.IOFileFilter; +import org.apache.commons.io.filefilter.SuffixFileFilter; +import org.apache.commons.io.filefilter.TrueFileFilter; +import org.apache.commons.io.output.NullOutputStream; + +/** + * General file manipulation utilities. + *

+ * Facilities are provided in the following areas: + *

    + *
  • writing to a file + *
  • reading from a file + *
  • make a directory including parent directories + *
  • copying files and directories + *
  • deleting files and directories + *
  • converting to and from a URL + *
  • listing files and directories by filter and extension + *
  • comparing file content + *
  • file last changed date + *
  • calculating a checksum + *
+ *

+ * Origin of code: Excalibur, Alexandria, Commons-Utils + * + * @author Kevin A. Burton + * @author Scott Sanders + * @author Daniel Rall + * @author Christoph.Reck + * @author Peter Donald + * @author Jeff Turner + * @author Matthew Hawthorne + * @author Jeremias Maerki + * @author Stephen Colebourne + * @author Ian Springer + * @author Chris Eldredge + * @author Jim Harrington + * @author Sandy McArthur + * @version $Id: FileUtils.java,v 1.1 2012/10/01 13:03:03 marcin Exp $ + */ +public class FileUtils { + + /** + * Instances should NOT be constructed in standard programming. + */ + public FileUtils() { + super(); + } + + /** + * The number of bytes in a kilobyte. + */ + public static final long ONE_KB = 1024; + + /** + * The number of bytes in a megabyte. + */ + public static final long ONE_MB = ONE_KB * ONE_KB; + + /** + * The file copy buffer size (30 MB) + */ + private static final long FILE_COPY_BUFFER_SIZE = ONE_MB * 30; + + /** + * The number of bytes in a gigabyte. + */ + public static final long ONE_GB = ONE_KB * ONE_MB; + + /** + * The number of bytes in a terabyte. + */ + public static final long ONE_TB = ONE_KB * ONE_GB; + + /** + * The number of bytes in a petabyte. + */ + public static final long ONE_PB = ONE_KB * ONE_TB; + + /** + * The number of bytes in an exabyte. + */ + public static final long ONE_EB = ONE_KB * ONE_PB; + + /** + * The number of bytes in a zettabyte. + */ + public static final BigInteger ONE_ZB = BigInteger.valueOf(ONE_KB).multiply(BigInteger.valueOf(ONE_EB)); + + /** + * The number of bytes in a yottabyte. + */ + public static final BigInteger ONE_YB = ONE_ZB.multiply(BigInteger.valueOf(ONE_EB)); + + /** + * An empty array of type File. + */ + public static final File[] EMPTY_FILE_ARRAY = new File[0]; + + /** + * The UTF-8 character set, used to decode octets in URLs. + */ + private static final Charset UTF8 = Charset.forName("UTF-8"); + + //----------------------------------------------------------------------- + /** + * Construct a file from the set of name elements. + * + * @param directory the parent directory + * @param names the name elements + * @return the file + * @since Commons IO 2.1 + */ + public static File getFile(File directory, String... names) { + if (directory == null) { + throw new NullPointerException("directorydirectory must not be null"); + } + if (names == null) { + throw new NullPointerException("names must not be null"); + } + File file = directory; + for (String name : names) { + file = new File(file, name); + } + return file; + } + + /** + * Construct a file from the set of name elements. + * + * @param names the name elements + * @return the file + * @since Commons IO 2.1 + */ + public static File getFile(String... names) { + if (names == null) { + throw new NullPointerException("names must not be null"); + } + File file = null; + for (String name : names) { + if (file == null) { + file = new File(name); + } else { + file = new File(file, name); + } + } + return file; + } + + /** + * Returns the path to the system temporary directory. + * + * @return the path to the system temporary directory. + * + * @since Commons IO 2.0 + */ + public static String getTempDirectoryPath() { + return System.getProperty("java.io.tmpdir"); + } + + /** + * Returns a {@link File} representing the system temporary directory. + * + * @return the system temporary directory. + * + * @since Commons IO 2.0 + */ + public static File getTempDirectory() { + return new File(getTempDirectoryPath()); + } + + /** + * Returns the path to the user's home directory. + * + * @return the path to the user's home directory. + * + * @since Commons IO 2.0 + */ + public static String getUserDirectoryPath() { + return System.getProperty("user.home"); + } + + /** + * Returns a {@link File} representing the user's home directory. + * + * @return the user's home directory. + * + * @since Commons IO 2.0 + */ + public static File getUserDirectory() { + return new File(getUserDirectoryPath()); + } + + //----------------------------------------------------------------------- + /** + * Opens a {@link FileInputStream} for the specified file, providing better + * error messages than simply calling new FileInputStream(file). + *

+ * At the end of the method either the stream will be successfully opened, + * or an exception will have been thrown. + *

+ * An exception is thrown if the file does not exist. + * An exception is thrown if the file object exists but is a directory. + * An exception is thrown if the file exists but cannot be read. + * + * @param file the file to open for input, must not be null + * @return a new {@link FileInputStream} for the specified file + * @throws FileNotFoundException if the file does not exist + * @throws IOException if the file object is a directory + * @throws IOException if the file cannot be read + * @since Commons IO 1.3 + */ + public static FileInputStream openInputStream(File file) throws IOException { + if (file.exists()) { + if (file.isDirectory()) { + throw new IOException("File '" + file + "' exists but is a directory"); + } + if (file.canRead() == false) { + throw new IOException("File '" + file + "' cannot be read"); + } + } else { + throw new FileNotFoundException("File '" + file + "' does not exist"); + } + return new FileInputStream(file); + } + + //----------------------------------------------------------------------- + /** + * Opens a {@link FileOutputStream} for the specified file, checking and + * creating the parent directory if it does not exist. + *

+ * At the end of the method either the stream will be successfully opened, + * or an exception will have been thrown. + *

+ * The parent directory will be created if it does not exist. + * The file will be created if it does not exist. + * An exception is thrown if the file object exists but is a directory. + * An exception is thrown if the file exists but cannot be written to. + * An exception is thrown if the parent directory cannot be created. + * + * @param file the file to open for output, must not be null + * @return a new {@link FileOutputStream} for the specified file + * @throws IOException if the file object is a directory + * @throws IOException if the file cannot be written to + * @throws IOException if a parent directory needs creating but that fails + * @since Commons IO 1.3 + */ + public static FileOutputStream openOutputStream(File file) throws IOException { + return openOutputStream(file, false); + } + + /** + * Opens a {@link FileOutputStream} for the specified file, checking and + * creating the parent directory if it does not exist. + *

+ * At the end of the method either the stream will be successfully opened, + * or an exception will have been thrown. + *

+ * The parent directory will be created if it does not exist. + * The file will be created if it does not exist. + * An exception is thrown if the file object exists but is a directory. + * An exception is thrown if the file exists but cannot be written to. + * An exception is thrown if the parent directory cannot be created. + * + * @param file the file to open for output, must not be null + * @param append if true, then bytes will be added to the + * end of the file rather than overwriting + * @return a new {@link FileOutputStream} for the specified file + * @throws IOException if the file object is a directory + * @throws IOException if the file cannot be written to + * @throws IOException if a parent directory needs creating but that fails + * @since Commons IO 2.1 + */ + public static FileOutputStream openOutputStream(File file, boolean append) throws IOException { + if (file.exists()) { + if (file.isDirectory()) { + throw new IOException("File '" + file + "' exists but is a directory"); + } + if (file.canWrite() == false) { + throw new IOException("File '" + file + "' cannot be written to"); + } + } else { + File parent = file.getParentFile(); + if (parent != null) { + if (!parent.mkdirs() && !parent.isDirectory()) { + throw new IOException("Directory '" + parent + "' could not be created"); + } + } + } + return new FileOutputStream(file, append); + } + + //----------------------------------------------------------------------- + /** + * Returns a human-readable version of the file size, where the input + * represents a specific number of bytes. + * + * If the size is over 1GB, the size is returned as the number of whole GB, + * i.e. the size is rounded down to the nearest GB boundary. + * + * Similarly for the 1MB and 1KB boundaries. + * + * @param size the number of bytes + * @return a human-readable display value (includes units - GB, MB, KB or bytes) + */ + // See https://issues.apache.org/jira/browse/IO-226 - should the rounding be changed? + public static String byteCountToDisplaySize(long size) { + String displaySize; + +// if (size / ONE_EB > 0) { +// displaySize = String.valueOf(size / ONE_EB) + " EB"; +// } else if (size / ONE_PB > 0) { +// displaySize = String.valueOf(size / ONE_PB) + " PB"; +// } else if (size / ONE_TB > 0) { +// displaySize = String.valueOf(size / ONE_TB) + " TB"; +// } else + if (size / ONE_GB > 0) { + displaySize = String.valueOf(size / ONE_GB) + " GB"; + } else if (size / ONE_MB > 0) { + displaySize = String.valueOf(size / ONE_MB) + " MB"; + } else if (size / ONE_KB > 0) { + displaySize = String.valueOf(size / ONE_KB) + " KB"; + } else { + displaySize = String.valueOf(size) + " bytes"; + } + return displaySize; + } + + //----------------------------------------------------------------------- + /** + * Implements the same behaviour as the "touch" utility on Unix. It creates + * a new file with size 0 or, if the file exists already, it is opened and + * closed without modifying it, but updating the file date and time. + *

+ * NOTE: As from v1.3, this method throws an IOException if the last + * modified date of the file cannot be set. Also, as from v1.3 this method + * creates parent directories if they do not exist. + * + * @param file the File to touch + * @throws IOException If an I/O problem occurs + */ + public static void touch(File file) throws IOException { + if (!file.exists()) { + OutputStream out = openOutputStream(file); + IOUtils.closeQuietly(out); + } + boolean success = file.setLastModified(System.currentTimeMillis()); + if (!success) { + throw new IOException("Unable to set the last modification time for " + file); + } + } + + //----------------------------------------------------------------------- + /** + * Converts a Collection containing java.io.File instanced into array + * representation. This is to account for the difference between + * File.listFiles() and FileUtils.listFiles(). + * + * @param files a Collection containing java.io.File instances + * @return an array of java.io.File + */ + public static File[] convertFileCollectionToFileArray(Collection files) { + return files.toArray(new File[files.size()]); + } + + //----------------------------------------------------------------------- + /** + * Finds files within a given directory (and optionally its + * subdirectories). All files found are filtered by an IOFileFilter. + * + * @param files the collection of files found. + * @param directory the directory to search in. + * @param filter the filter to apply to files and directories. + */ + private static void innerListFiles(Collection files, File directory, + IOFileFilter filter) { + File[] found = directory.listFiles((FileFilter) filter); + if (found != null) { + for (File file : found) { + if (file.isDirectory()) { + innerListFiles(files, file, filter); + } else { + files.add(file); + } + } + } + } + + /** + * Finds files within a given directory (and optionally its + * subdirectories). All files found are filtered by an IOFileFilter. + *

+ * If your search should recurse into subdirectories you can pass in + * an IOFileFilter for directories. You don't need to bind a + * DirectoryFileFilter (via logical AND) to this filter. This method does + * that for you. + *

+ * An example: If you want to search through all directories called + * "temp" you pass in FileFilterUtils.NameFileFilter("temp") + *

+ * Another common usage of this method is find files in a directory + * tree but ignoring the directories generated CVS. You can simply pass + * in FileFilterUtils.makeCVSAware(null). + * + * @param directory the directory to search in + * @param fileFilter filter to apply when finding files. + * @param dirFilter optional filter to apply when finding subdirectories. + * If this parameter is null, subdirectories will not be included in the + * search. Use TrueFileFilter.INSTANCE to match all directories. + * @return an collection of java.io.File with the matching files + * @see org.apache.commons.io.filefilter.FileFilterUtils + * @see org.apache.commons.io.filefilter.NameFileFilter + */ + public static Collection listFiles( + File directory, IOFileFilter fileFilter, IOFileFilter dirFilter) { + if (!directory.isDirectory()) { + throw new IllegalArgumentException( + "Parameter 'directory' is not a directory"); + } + if (fileFilter == null) { + throw new NullPointerException("Parameter 'fileFilter' is null"); + } + + //Setup effective file filter + IOFileFilter effFileFilter = FileFilterUtils.and(fileFilter, + FileFilterUtils.notFileFilter(DirectoryFileFilter.INSTANCE)); + + //Setup effective directory filter + IOFileFilter effDirFilter; + if (dirFilter == null) { + effDirFilter = FalseFileFilter.INSTANCE; + } else { + effDirFilter = FileFilterUtils.and(dirFilter, + DirectoryFileFilter.INSTANCE); + } + + //Find files + Collection files = new java.util.LinkedList(); + innerListFiles(files, directory, + FileFilterUtils.or(effFileFilter, effDirFilter)); + return files; + } + + /** + * Allows iteration over the files in given directory (and optionally + * its subdirectories). + *

+ * All files found are filtered by an IOFileFilter. This method is + * based on {@link #listFiles(File, IOFileFilter, IOFileFilter)}, + * which supports Iterable ('foreach' loop). + *

+ * @param directory the directory to search in + * @param fileFilter filter to apply when finding files. + * @param dirFilter optional filter to apply when finding subdirectories. + * If this parameter is null, subdirectories will not be included in the + * search. Use TrueFileFilter.INSTANCE to match all directories. + * @return an iterator of java.io.File for the matching files + * @see org.apache.commons.io.filefilter.FileFilterUtils + * @see org.apache.commons.io.filefilter.NameFileFilter + * @since Commons IO 1.2 + */ + public static Iterator iterateFiles( + File directory, IOFileFilter fileFilter, IOFileFilter dirFilter) { + return listFiles(directory, fileFilter, dirFilter).iterator(); + } + + //----------------------------------------------------------------------- + /** + * Converts an array of file extensions to suffixes for use + * with IOFileFilters. + * + * @param extensions an array of extensions. Format: {"java", "xml"} + * @return an array of suffixes. Format: {".java", ".xml"} + */ + private static String[] toSuffixes(String[] extensions) { + String[] suffixes = new String[extensions.length]; + for (int i = 0; i < extensions.length; i++) { + suffixes[i] = "." + extensions[i]; + } + return suffixes; + } + + + /** + * Finds files within a given directory (and optionally its subdirectories) + * which match an array of extensions. + * + * @param directory the directory to search in + * @param extensions an array of extensions, ex. {"java","xml"}. If this + * parameter is null, all files are returned. + * @param recursive if true all subdirectories are searched as well + * @return an collection of java.io.File with the matching files + */ + public static Collection listFiles( + File directory, String[] extensions, boolean recursive) { + IOFileFilter filter; + if (extensions == null) { + filter = TrueFileFilter.INSTANCE; + } else { + String[] suffixes = toSuffixes(extensions); + filter = new SuffixFileFilter(suffixes); + } + return listFiles(directory, filter, + (recursive ? TrueFileFilter.INSTANCE : FalseFileFilter.INSTANCE)); + } + + /** + * Allows iteration over the files in a given directory (and optionally + * its subdirectories) which match an array of extensions. This method + * is based on {@link #listFiles(File, String[], boolean)}, + * which supports Iterable ('foreach' loop). + * + * @param directory the directory to search in + * @param extensions an array of extensions, ex. {"java","xml"}. If this + * parameter is null, all files are returned. + * @param recursive if true all subdirectories are searched as well + * @return an iterator of java.io.File with the matching files + * @since Commons IO 1.2 + */ + public static Iterator iterateFiles( + File directory, String[] extensions, boolean recursive) { + return listFiles(directory, extensions, recursive).iterator(); + } + + //----------------------------------------------------------------------- + /** + * Compares the contents of two files to determine if they are equal or not. + *

+ * This method checks to see if the two files are different lengths + * or if they point to the same file, before resorting to byte-by-byte + * comparison of the contents. + *

+ * Code origin: Avalon + * + * @param file1 the first file + * @param file2 the second file + * @return true if the content of the files are equal or they both don't + * exist, false otherwise + * @throws IOException in case of an I/O error + */ + public static boolean contentEquals(File file1, File file2) throws IOException { + boolean file1Exists = file1.exists(); + if (file1Exists != file2.exists()) { + return false; + } + + if (!file1Exists) { + // two not existing files are equal + return true; + } + + if (file1.isDirectory() || file2.isDirectory()) { + // don't want to compare directory contents + throw new IOException("Can't compare directories, only files"); + } + + if (file1.length() != file2.length()) { + // lengths differ, cannot be equal + return false; + } + + if (file1.getCanonicalFile().equals(file2.getCanonicalFile())) { + // same file + return true; + } + + InputStream input1 = null; + InputStream input2 = null; + try { + input1 = new FileInputStream(file1); + input2 = new FileInputStream(file2); + return IOUtils.contentEquals(input1, input2); + + } finally { + IOUtils.closeQuietly(input1); + IOUtils.closeQuietly(input2); + } + } + + //----------------------------------------------------------------------- + /** + * Convert from a URL to a File. + *

+ * From version 1.1 this method will decode the URL. + * Syntax such as file:///my%20docs/file.txt will be + * correctly decoded to /my docs/file.txt. Starting with version + * 1.5, this method uses UTF-8 to decode percent-encoded octets to characters. + * Additionally, malformed percent-encoded octets are handled leniently by + * passing them through literally. + * + * @param url the file URL to convert, null returns null + * @return the equivalent File object, or null + * if the URL's protocol is not file + */ + public static File toFile(URL url) { + if (url == null || !"file".equalsIgnoreCase(url.getProtocol())) { + return null; + } else { + String filename = url.getFile().replace('/', File.separatorChar); + filename = decodeUrl(filename); + return new File(filename); + } + } + + /** + * Decodes the specified URL as per RFC 3986, i.e. transforms + * percent-encoded octets to characters by decoding with the UTF-8 character + * set. This function is primarily intended for usage with + * {@link java.net.URL} which unfortunately does not enforce proper URLs. As + * such, this method will leniently accept invalid characters or malformed + * percent-encoded octets and simply pass them literally through to the + * result string. Except for rare edge cases, this will make unencoded URLs + * pass through unaltered. + * + * @param url The URL to decode, may be null. + * @return The decoded URL or null if the input was + * null. + */ + static String decodeUrl(String url) { + String decoded = url; + if (url != null && url.indexOf('%') >= 0) { + int n = url.length(); + StringBuffer buffer = new StringBuffer(); + ByteBuffer bytes = ByteBuffer.allocate(n); + for (int i = 0; i < n;) { + if (url.charAt(i) == '%') { + try { + do { + byte octet = (byte) Integer.parseInt(url.substring(i + 1, i + 3), 16); + bytes.put(octet); + i += 3; + } while (i < n && url.charAt(i) == '%'); + continue; + } catch (RuntimeException e) { + // malformed percent-encoded octet, fall through and + // append characters literally + } finally { + if (bytes.position() > 0) { + bytes.flip(); + buffer.append(UTF8.decode(bytes).toString()); + bytes.clear(); + } + } + } + buffer.append(url.charAt(i++)); + } + decoded = buffer.toString(); + } + return decoded; + } + + /** + * Converts each of an array of URL to a File. + *

+ * Returns an array of the same size as the input. + * If the input is null, an empty array is returned. + * If the input contains null, the output array contains null at the same + * index. + *

+ * This method will decode the URL. + * Syntax such as file:///my%20docs/file.txt will be + * correctly decoded to /my docs/file.txt. + * + * @param urls the file URLs to convert, null returns empty array + * @return a non-null array of Files matching the input, with a null item + * if there was a null at that index in the input array + * @throws IllegalArgumentException if any file is not a URL file + * @throws IllegalArgumentException if any file is incorrectly encoded + * @since Commons IO 1.1 + */ + public static File[] toFiles(URL[] urls) { + if (urls == null || urls.length == 0) { + return EMPTY_FILE_ARRAY; + } + File[] files = new File[urls.length]; + for (int i = 0; i < urls.length; i++) { + URL url = urls[i]; + if (url != null) { + if (url.getProtocol().equals("file") == false) { + throw new IllegalArgumentException( + "URL could not be converted to a File: " + url); + } + files[i] = toFile(url); + } + } + return files; + } + + /** + * Converts each of an array of File to a URL. + *

+ * Returns an array of the same size as the input. + * + * @param files the files to convert + * @return an array of URLs matching the input + * @throws IOException if a file cannot be converted + */ + public static URL[] toURLs(File[] files) throws IOException { + URL[] urls = new URL[files.length]; + + for (int i = 0; i < urls.length; i++) { + urls[i] = files[i].toURI().toURL(); + } + + return urls; + } + + //----------------------------------------------------------------------- + /** + * Copies a file to a directory preserving the file date. + *

+ * This method copies the contents of the specified source file + * to a file of the same name in the specified destination directory. + * The destination directory is created if it does not exist. + * If the destination file exists, then this method will overwrite it. + *

+ * Note: This method tries to preserve the file's last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that the operation will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcFile an existing file to copy, must not be null + * @param destDir the directory to place the copy in, must not be null + * + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFile(File, File, boolean) + */ + public static void copyFileToDirectory(File srcFile, File destDir) throws IOException { + copyFileToDirectory(srcFile, destDir, true); + } + + /** + * Copies a file to a directory optionally preserving the file date. + *

+ * This method copies the contents of the specified source file + * to a file of the same name in the specified destination directory. + * The destination directory is created if it does not exist. + * If the destination file exists, then this method will overwrite it. + *

+ * Note: Setting preserveFileDate to + * true tries to preserve the file's last modified + * date/times using {@link File#setLastModified(long)}, however it is + * not guaranteed that the operation will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcFile an existing file to copy, must not be null + * @param destDir the directory to place the copy in, must not be null + * @param preserveFileDate true if the file date of the copy + * should be the same as the original + * + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFile(File, File, boolean) + * @since Commons IO 1.3 + */ + public static void copyFileToDirectory(File srcFile, File destDir, boolean preserveFileDate) throws IOException { + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (destDir.exists() && destDir.isDirectory() == false) { + throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory"); + } + File destFile = new File(destDir, srcFile.getName()); + copyFile(srcFile, destFile, preserveFileDate); + } + + /** + * Copies a file to a new location preserving the file date. + *

+ * This method copies the contents of the specified source file to the + * specified destination file. The directory holding the destination file is + * created if it does not exist. If the destination file exists, then this + * method will overwrite it. + *

+ * Note: This method tries to preserve the file's last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that the operation will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcFile an existing file to copy, must not be null + * @param destFile the new file, must not be null + * + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFileToDirectory(File, File) + */ + public static void copyFile(File srcFile, File destFile) throws IOException { + copyFile(srcFile, destFile, true); + } + + /** + * Copies a file to a new location. + *

+ * This method copies the contents of the specified source file + * to the specified destination file. + * The directory holding the destination file is created if it does not exist. + * If the destination file exists, then this method will overwrite it. + *

+ * Note: Setting preserveFileDate to + * true tries to preserve the file's last modified + * date/times using {@link File#setLastModified(long)}, however it is + * not guaranteed that the operation will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcFile an existing file to copy, must not be null + * @param destFile the new file, must not be null + * @param preserveFileDate true if the file date of the copy + * should be the same as the original + * + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @see #copyFileToDirectory(File, File, boolean) + */ + public static void copyFile(File srcFile, File destFile, + boolean preserveFileDate) throws IOException { + if (srcFile == null) { + throw new NullPointerException("Source must not be null"); + } + if (destFile == null) { + throw new NullPointerException("Destination must not be null"); + } + if (srcFile.exists() == false) { + throw new FileNotFoundException("Source '" + srcFile + "' does not exist"); + } + if (srcFile.isDirectory()) { + throw new IOException("Source '" + srcFile + "' exists but is a directory"); + } + if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) { + throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same"); + } + File parentFile = destFile.getParentFile(); + if (parentFile != null) { + if (!parentFile.mkdirs() && !parentFile.isDirectory()) { + throw new IOException("Destination '" + parentFile + "' directory cannot be created"); + } + } + if (destFile.exists() && destFile.canWrite() == false) { + throw new IOException("Destination '" + destFile + "' exists but is read-only"); + } + doCopyFile(srcFile, destFile, preserveFileDate); + } + + /** + * Copy bytes from a File to an OutputStream. + *

+ * This method buffers the input internally, so there is no need to use a BufferedInputStream. + *

+ * + * @param input + * the File to read from + * @param output + * the OutputStream to write to + * @return the number of bytes copied + * @throws NullPointerException + * if the input or output is null + * @throws IOException + * if an I/O error occurs + * @since Commons IO 2.1 + */ + public static long copyFile(File input, OutputStream output) throws IOException { + final FileInputStream fis = new FileInputStream(input); + try { + return IOUtils.copyLarge(fis, output); + } finally { + fis.close(); + } + } + + /** + * Internal copy file method. + * + * @param srcFile the validated source file, must not be null + * @param destFile the validated destination file, must not be null + * @param preserveFileDate whether to preserve the file date + * @throws IOException if an error occurs + */ + private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException { + if (destFile.exists() && destFile.isDirectory()) { + throw new IOException("Destination '" + destFile + "' exists but is a directory"); + } + + FileInputStream fis = null; + FileOutputStream fos = null; + FileChannel input = null; + FileChannel output = null; + try { + fis = new FileInputStream(srcFile); + fos = new FileOutputStream(destFile); + input = fis.getChannel(); + output = fos.getChannel(); + long size = input.size(); + long pos = 0; + long count = 0; + while (pos < size) { + count = (size - pos) > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : (size - pos); + pos += output.transferFrom(input, pos, count); + } + } finally { + IOUtils.closeQuietly(output); + IOUtils.closeQuietly(fos); + IOUtils.closeQuietly(input); + IOUtils.closeQuietly(fis); + } + + if (srcFile.length() != destFile.length()) { + throw new IOException("Failed to copy full contents from '" + + srcFile + "' to '" + destFile + "'"); + } + if (preserveFileDate) { + destFile.setLastModified(srcFile.lastModified()); + } + } + + //----------------------------------------------------------------------- + /** + * Copies a directory to within another directory preserving the file dates. + *

+ * This method copies the source directory and all its contents to a + * directory of the same name in the specified destination directory. + *

+ * The destination directory is created if it does not exist. + * If the destination directory did exist, then this method merges + * the source with the destination, with the source taking precedence. + *

+ * Note: This method tries to preserve the files' last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that those operations will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcDir an existing directory to copy, must not be null + * @param destDir the directory to place the copy in, must not be null + * + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since Commons IO 1.2 + */ + public static void copyDirectoryToDirectory(File srcDir, File destDir) throws IOException { + if (srcDir == null) { + throw new NullPointerException("Source must not be null"); + } + if (srcDir.exists() && srcDir.isDirectory() == false) { + throw new IllegalArgumentException("Source '" + destDir + "' is not a directory"); + } + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (destDir.exists() && destDir.isDirectory() == false) { + throw new IllegalArgumentException("Destination '" + destDir + "' is not a directory"); + } + copyDirectory(srcDir, new File(destDir, srcDir.getName()), true); + } + + /** + * Copies a whole directory to a new location preserving the file dates. + *

+ * This method copies the specified directory and all its child + * directories and files to the specified destination. + * The destination is the new location and name of the directory. + *

+ * The destination directory is created if it does not exist. + * If the destination directory did exist, then this method merges + * the source with the destination, with the source taking precedence. + *

+ * Note: This method tries to preserve the files' last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that those operations will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcDir an existing directory to copy, must not be null + * @param destDir the new directory, must not be null + * + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since Commons IO 1.1 + */ + public static void copyDirectory(File srcDir, File destDir) throws IOException { + copyDirectory(srcDir, destDir, true); + } + + /** + * Copies a whole directory to a new location. + *

+ * This method copies the contents of the specified source directory + * to within the specified destination directory. + *

+ * The destination directory is created if it does not exist. + * If the destination directory did exist, then this method merges + * the source with the destination, with the source taking precedence. + *

+ * Note: Setting preserveFileDate to + * true tries to preserve the files' last modified + * date/times using {@link File#setLastModified(long)}, however it is + * not guaranteed that those operations will succeed. + * If the modification operation fails, no indication is provided. + * + * @param srcDir an existing directory to copy, must not be null + * @param destDir the new directory, must not be null + * @param preserveFileDate true if the file date of the copy + * should be the same as the original + * + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since Commons IO 1.1 + */ + public static void copyDirectory(File srcDir, File destDir, + boolean preserveFileDate) throws IOException { + copyDirectory(srcDir, destDir, null, preserveFileDate); + } + + /** + * Copies a filtered directory to a new location preserving the file dates. + *

+ * This method copies the contents of the specified source directory + * to within the specified destination directory. + *

+ * The destination directory is created if it does not exist. + * If the destination directory did exist, then this method merges + * the source with the destination, with the source taking precedence. + *

+ * Note: This method tries to preserve the files' last + * modified date/times using {@link File#setLastModified(long)}, however + * it is not guaranteed that those operations will succeed. + * If the modification operation fails, no indication is provided. + * + *

Example: Copy directories only

+ *
+     *  // only copy the directory structure
+     *  FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY);
+     *  
+ * + *

Example: Copy directories and txt files

+ *
+     *  // Create a filter for ".txt" files
+     *  IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
+     *  IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
+     *
+     *  // Create a filter for either directories or ".txt" files
+     *  FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
+     *
+     *  // Copy using the filter
+     *  FileUtils.copyDirectory(srcDir, destDir, filter);
+     *  
+ * + * @param srcDir an existing directory to copy, must not be null + * @param destDir the new directory, must not be null + * @param filter the filter to apply, null means copy all directories and files + * should be the same as the original + * + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since Commons IO 1.4 + */ + public static void copyDirectory(File srcDir, File destDir, + FileFilter filter) throws IOException { + copyDirectory(srcDir, destDir, filter, true); + } + + /** + * Copies a filtered directory to a new location. + *

+ * This method copies the contents of the specified source directory + * to within the specified destination directory. + *

+ * The destination directory is created if it does not exist. + * If the destination directory did exist, then this method merges + * the source with the destination, with the source taking precedence. + *

+ * Note: Setting preserveFileDate to + * true tries to preserve the files' last modified + * date/times using {@link File#setLastModified(long)}, however it is + * not guaranteed that those operations will succeed. + * If the modification operation fails, no indication is provided. + * + *

Example: Copy directories only

+ *
+     *  // only copy the directory structure
+     *  FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY, false);
+     *  
+ * + *

Example: Copy directories and txt files

+ *
+     *  // Create a filter for ".txt" files
+     *  IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
+     *  IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
+     *
+     *  // Create a filter for either directories or ".txt" files
+     *  FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
+     *
+     *  // Copy using the filter
+     *  FileUtils.copyDirectory(srcDir, destDir, filter, false);
+     *  
+ * + * @param srcDir an existing directory to copy, must not be null + * @param destDir the new directory, must not be null + * @param filter the filter to apply, null means copy all directories and files + * @param preserveFileDate true if the file date of the copy + * should be the same as the original + * + * @throws NullPointerException if source or destination is null + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs during copying + * @since Commons IO 1.4 + */ + public static void copyDirectory(File srcDir, File destDir, + FileFilter filter, boolean preserveFileDate) throws IOException { + if (srcDir == null) { + throw new NullPointerException("Source must not be null"); + } + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (srcDir.exists() == false) { + throw new FileNotFoundException("Source '" + srcDir + "' does not exist"); + } + if (srcDir.isDirectory() == false) { + throw new IOException("Source '" + srcDir + "' exists but is not a directory"); + } + if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath())) { + throw new IOException("Source '" + srcDir + "' and destination '" + destDir + "' are the same"); + } + + // Cater for destination being directory within the source directory (see IO-141) + List exclusionList = null; + if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath())) { + File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter); + if (srcFiles != null && srcFiles.length > 0) { + exclusionList = new ArrayList(srcFiles.length); + for (File srcFile : srcFiles) { + File copiedFile = new File(destDir, srcFile.getName()); + exclusionList.add(copiedFile.getCanonicalPath()); + } + } + } + doCopyDirectory(srcDir, destDir, filter, preserveFileDate, exclusionList); + } + + /** + * Internal copy directory method. + * + * @param srcDir the validated source directory, must not be null + * @param destDir the validated destination directory, must not be null + * @param filter the filter to apply, null means copy all directories and files + * @param preserveFileDate whether to preserve the file date + * @param exclusionList List of files and directories to exclude from the copy, may be null + * @throws IOException if an error occurs + * @since Commons IO 1.1 + */ + private static void doCopyDirectory(File srcDir, File destDir, FileFilter filter, + boolean preserveFileDate, List exclusionList) throws IOException { + // recurse + File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter); + if (srcFiles == null) { // null if abstract pathname does not denote a directory, or if an I/O error occurs + throw new IOException("Failed to list contents of " + srcDir); + } + if (destDir.exists()) { + if (destDir.isDirectory() == false) { + throw new IOException("Destination '" + destDir + "' exists but is not a directory"); + } + } else { + if (!destDir.mkdirs() && !destDir.isDirectory()) { + throw new IOException("Destination '" + destDir + "' directory cannot be created"); + } + } + if (destDir.canWrite() == false) { + throw new IOException("Destination '" + destDir + "' cannot be written to"); + } + for (File srcFile : srcFiles) { + File dstFile = new File(destDir, srcFile.getName()); + if (exclusionList == null || !exclusionList.contains(srcFile.getCanonicalPath())) { + if (srcFile.isDirectory()) { + doCopyDirectory(srcFile, dstFile, filter, preserveFileDate, exclusionList); + } else { + doCopyFile(srcFile, dstFile, preserveFileDate); + } + } + } + + // Do this last, as the above has probably affected directory metadata + if (preserveFileDate) { + destDir.setLastModified(srcDir.lastModified()); + } + } + + //----------------------------------------------------------------------- + /** + * Copies bytes from the URL source to a file + * destination. The directories up to destination + * will be created if they don't already exist. destination + * will be overwritten if it already exists. + *

+ * Warning: this method does not set a connection or read timeout and thus + * might block forever. Use {@link #copyURLToFile(URL, File, int, int)} + * with reasonable timeouts to prevent this. + * + * @param source the URL to copy bytes from, must not be null + * @param destination the non-directory File to write bytes to + * (possibly overwriting), must not be null + * @throws IOException if source URL cannot be opened + * @throws IOException if destination is a directory + * @throws IOException if destination cannot be written + * @throws IOException if destination needs creating but can't be + * @throws IOException if an IO error occurs during copying + */ + public static void copyURLToFile(URL source, File destination) throws IOException { + InputStream input = source.openStream(); + copyInputStreamToFile(input, destination); + } + + /** + * Copies bytes from the URL source to a file + * destination. The directories up to destination + * will be created if they don't already exist. destination + * will be overwritten if it already exists. + * + * @param source the URL to copy bytes from, must not be null + * @param destination the non-directory File to write bytes to + * (possibly overwriting), must not be null + * @param connectionTimeout the number of milliseconds until this method + * will timeout if no connection could be established to the source + * @param readTimeout the number of milliseconds until this method will + * timeout if no data could be read from the source + * @throws IOException if source URL cannot be opened + * @throws IOException if destination is a directory + * @throws IOException if destination cannot be written + * @throws IOException if destination needs creating but can't be + * @throws IOException if an IO error occurs during copying + * @since Commons IO 2.0 + */ + public static void copyURLToFile(URL source, File destination, + int connectionTimeout, int readTimeout) throws IOException { + URLConnection connection = source.openConnection(); + connection.setConnectTimeout(connectionTimeout); + connection.setReadTimeout(readTimeout); + InputStream input = connection.getInputStream(); + copyInputStreamToFile(input, destination); + } + + /** + * Copies bytes from an {@link InputStream} source to a file + * destination. The directories up to destination + * will be created if they don't already exist. destination + * will be overwritten if it already exists. + * + * @param source the InputStream to copy bytes from, must not be null + * @param destination the non-directory File to write bytes to + * (possibly overwriting), must not be null + * @throws IOException if destination is a directory + * @throws IOException if destination cannot be written + * @throws IOException if destination needs creating but can't be + * @throws IOException if an IO error occurs during copying + * @since Commons IO 2.0 + */ + public static void copyInputStreamToFile(InputStream source, File destination) throws IOException { + try { + FileOutputStream output = openOutputStream(destination); + try { + IOUtils.copy(source, output); + } finally { + IOUtils.closeQuietly(output); + } + } finally { + IOUtils.closeQuietly(source); + } + } + + //----------------------------------------------------------------------- + /** + * Deletes a directory recursively. + * + * @param directory directory to delete + * @throws IOException in case deletion is unsuccessful + */ + public static void deleteDirectory(File directory) throws IOException { + if (!directory.exists()) { + return; + } + + if (!isSymlink(directory)) { + cleanDirectory(directory); + } + + if (!directory.delete()) { + String message = + "Unable to delete directory " + directory + "."; + throw new IOException(message); + } + } + + /** + * Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories. + *

+ * The difference between File.delete() and this method are: + *

    + *
  • A directory to be deleted does not have to be empty.
  • + *
  • No exceptions are thrown when a file or directory cannot be deleted.
  • + *
+ * + * @param file file or directory to delete, can be null + * @return true if the file or directory was deleted, otherwise + * false + * + * @since Commons IO 1.4 + */ + public static boolean deleteQuietly(File file) { + if (file == null) { + return false; + } + try { + if (file.isDirectory()) { + cleanDirectory(file); + } + } catch (Exception ignored) { + } + + try { + return file.delete(); + } catch (Exception ignored) { + return false; + } + } + + /** + * Cleans a directory without deleting it. + * + * @param directory directory to clean + * @throws IOException in case cleaning is unsuccessful + */ + public static void cleanDirectory(File directory) throws IOException { + if (!directory.exists()) { + String message = directory + " does not exist"; + throw new IllegalArgumentException(message); + } + + if (!directory.isDirectory()) { + String message = directory + " is not a directory"; + throw new IllegalArgumentException(message); + } + + File[] files = directory.listFiles(); + if (files == null) { // null if security restricted + throw new IOException("Failed to list contents of " + directory); + } + + IOException exception = null; + for (File file : files) { + try { + forceDelete(file); + } catch (IOException ioe) { + exception = ioe; + } + } + + if (null != exception) { + throw exception; + } + } + + //----------------------------------------------------------------------- + /** + * Waits for NFS to propagate a file creation, imposing a timeout. + *

+ * This method repeatedly tests {@link File#exists()} until it returns + * true up to the maximum time specified in seconds. + * + * @param file the file to check, must not be null + * @param seconds the maximum time in seconds to wait + * @return true if file exists + * @throws NullPointerException if the file is null + */ + public static boolean waitFor(File file, int seconds) { + int timeout = 0; + int tick = 0; + while (!file.exists()) { + if (tick++ >= 10) { + tick = 0; + if (timeout++ > seconds) { + return false; + } + } + try { + Thread.sleep(100); + } catch (InterruptedException ignore) { + // ignore exception + } catch (Exception ex) { + break; + } + } + return true; + } + + //----------------------------------------------------------------------- + /** + * Reads the contents of a file into a String. + * The file is always closed. + * + * @param file the file to read, must not be null + * @param encoding the encoding to use, null means platform default + * @return the file contents, never null + * @throws IOException in case of an I/O error + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + */ + public static String readFileToString(File file, String encoding) throws IOException { + InputStream in = null; + try { + in = openInputStream(file); + return IOUtils.toString(in, encoding); + } finally { + IOUtils.closeQuietly(in); + } + } + + + /** + * Reads the contents of a file into a String using the default encoding for the VM. + * The file is always closed. + * + * @param file the file to read, must not be null + * @return the file contents, never null + * @throws IOException in case of an I/O error + * @since Commons IO 1.3.1 + */ + public static String readFileToString(File file) throws IOException { + return readFileToString(file, null); + } + + /** + * Reads the contents of a file into a byte array. + * The file is always closed. + * + * @param file the file to read, must not be null + * @return the file contents, never null + * @throws IOException in case of an I/O error + * @since Commons IO 1.1 + */ + public static byte[] readFileToByteArray(File file) throws IOException { + InputStream in = null; + try { + in = openInputStream(file); + return IOUtils.toByteArray(in, file.length()); + } finally { + IOUtils.closeQuietly(in); + } + } + + /** + * Reads the contents of a file line by line to a List of Strings. + * The file is always closed. + * + * @param file the file to read, must not be null + * @param encoding the encoding to use, null means platform default + * @return the list of Strings representing each line in the file, never null + * @throws IOException in case of an I/O error + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @since Commons IO 1.1 + */ + public static List readLines(File file, String encoding) throws IOException { + InputStream in = null; + try { + in = openInputStream(file); + return IOUtils.readLines(in, encoding); + } finally { + IOUtils.closeQuietly(in); + } + } + + /** + * Reads the contents of a file line by line to a List of Strings using the default encoding for the VM. + * The file is always closed. + * + * @param file the file to read, must not be null + * @return the list of Strings representing each line in the file, never null + * @throws IOException in case of an I/O error + * @since Commons IO 1.3 + */ + public static List readLines(File file) throws IOException { + return readLines(file, null); + } + + /** + * Returns an Iterator for the lines in a File. + *

+ * This method opens an InputStream for the file. + * When you have finished with the iterator you should close the stream + * to free internal resources. This can be done by calling the + * {@link LineIterator#close()} or + * {@link LineIterator#closeQuietly(LineIterator)} method. + *

+ * The recommended usage pattern is: + *

+     * LineIterator it = FileUtils.lineIterator(file, "UTF-8");
+     * try {
+     *   while (it.hasNext()) {
+     *     String line = it.nextLine();
+     *     /// do something with line
+     *   }
+     * } finally {
+     *   LineIterator.closeQuietly(iterator);
+     * }
+     * 
+ *

+ * If an exception occurs during the creation of the iterator, the + * underlying stream is closed. + * + * @param file the file to open for input, must not be null + * @param encoding the encoding to use, null means platform default + * @return an Iterator of the lines in the file, never null + * @throws IOException in case of an I/O error (file closed) + * @since Commons IO 1.2 + */ + public static LineIterator lineIterator(File file, String encoding) throws IOException { + InputStream in = null; + try { + in = openInputStream(file); + return IOUtils.lineIterator(in, encoding); + } catch (IOException ex) { + IOUtils.closeQuietly(in); + throw ex; + } catch (RuntimeException ex) { + IOUtils.closeQuietly(in); + throw ex; + } + } + + /** + * Returns an Iterator for the lines in a File using the default encoding for the VM. + * + * @param file the file to open for input, must not be null + * @return an Iterator of the lines in the file, never null + * @throws IOException in case of an I/O error (file closed) + * @since Commons IO 1.3 + * @see #lineIterator(File, String) + */ + public static LineIterator lineIterator(File file) throws IOException { + return lineIterator(file, null); + } + + //----------------------------------------------------------------------- + /** + * Writes a String to a file creating the file if it does not exist. + * + * NOTE: As from v1.3, the parent directories of the file will be created + * if they do not exist. + * + * @param file the file to write + * @param data the content to write to the file + * @param encoding the encoding to use, null means platform default + * @throws IOException in case of an I/O error + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + */ + public static void writeStringToFile(File file, String data, String encoding) throws IOException { + writeStringToFile(file, data, encoding, false); + } + + /** + * Writes a String to a file creating the file if it does not exist. + * + * @param file the file to write + * @param data the content to write to the file + * @param encoding the encoding to use, null means platform default + * @param append if true, then the String will be added to the + * end of the file rather than overwriting + * @throws IOException in case of an I/O error + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @since Commons IO 2.1 + */ + public static void writeStringToFile(File file, String data, String encoding, boolean append) throws IOException { + OutputStream out = null; + try { + out = openOutputStream(file, append); + IOUtils.write(data, out, encoding); + } finally { + IOUtils.closeQuietly(out); + } + } + + /** + * Writes a String to a file creating the file if it does not exist using the default encoding for the VM. + * + * @param file the file to write + * @param data the content to write to the file + * @throws IOException in case of an I/O error + */ + public static void writeStringToFile(File file, String data) throws IOException { + writeStringToFile(file, data, null, false); + } + + /** + * Writes a String to a file creating the file if it does not exist using the default encoding for the VM. + * + * @param file the file to write + * @param data the content to write to the file + * @param append if true, then the String will be added to the + * end of the file rather than overwriting + * @throws IOException in case of an I/O error + * @since Commons IO 2.1 + */ + public static void writeStringToFile(File file, String data, boolean append) throws IOException { + writeStringToFile(file, data, null, append); + } + + /** + * Writes a CharSequence to a file creating the file if it does not exist using the default encoding for the VM. + * + * @param file the file to write + * @param data the content to write to the file + * @throws IOException in case of an I/O error + * @since Commons IO 2.0 + */ + public static void write(File file, CharSequence data) throws IOException { + write(file, data, null, false); + } + + /** + * Writes a CharSequence to a file creating the file if it does not exist using the default encoding for the VM. + * + * @param file the file to write + * @param data the content to write to the file + * @param append if true, then the data will be added to the + * end of the file rather than overwriting + * @throws IOException in case of an I/O error + * @since Commons IO 2.1 + */ + public static void write(File file, CharSequence data, boolean append) throws IOException { + write(file, data, null, append); + } + + /** + * Writes a CharSequence to a file creating the file if it does not exist. + * + * @param file the file to write + * @param data the content to write to the file + * @param encoding the encoding to use, null means platform default + * @throws IOException in case of an I/O error + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @since Commons IO 2.0 + */ + public static void write(File file, CharSequence data, String encoding) throws IOException { + write(file, data, encoding, false); + } + + /** + * Writes a CharSequence to a file creating the file if it does not exist. + * + * @param file the file to write + * @param data the content to write to the file + * @param encoding the encoding to use, null means platform default + * @param append if true, then the data will be added to the + * end of the file rather than overwriting + * @throws IOException in case of an I/O error + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @since IO 2.1 + */ + public static void write(File file, CharSequence data, String encoding, boolean append) throws IOException { + String str = data == null ? null : data.toString(); + writeStringToFile(file, str, encoding, append); + } + + /** + * Writes a byte array to a file creating the file if it does not exist. + *

+ * NOTE: As from v1.3, the parent directories of the file will be created + * if they do not exist. + * + * @param file the file to write to + * @param data the content to write to the file + * @throws IOException in case of an I/O error + * @since Commons IO 1.1 + */ + public static void writeByteArrayToFile(File file, byte[] data) throws IOException { + writeByteArrayToFile(file, data, false); + } + + /** + * Writes a byte array to a file creating the file if it does not exist. + * + * @param file the file to write to + * @param data the content to write to the file + * @param append if true, then bytes will be added to the + * end of the file rather than overwriting + * @throws IOException in case of an I/O error + * @since IO 2.1 + */ + public static void writeByteArrayToFile(File file, byte[] data, boolean append) throws IOException { + OutputStream out = null; + try { + out = openOutputStream(file, append); + out.write(data); + } finally { + IOUtils.closeQuietly(out); + } + } + + /** + * Writes the toString() value of each item in a collection to + * the specified File line by line. + * The specified character encoding and the default line ending will be used. + *

+ * NOTE: As from v1.3, the parent directories of the file will be created + * if they do not exist. + * + * @param file the file to write to + * @param encoding the encoding to use, null means platform default + * @param lines the lines to write, null entries produce blank lines + * @throws IOException in case of an I/O error + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @since Commons IO 1.1 + */ + public static void writeLines(File file, String encoding, Collection lines) throws IOException { + writeLines(file, encoding, lines, null, false); + } + + /** + * Writes the toString() value of each item in a collection to + * the specified File line by line, optionally appending. + * The specified character encoding and the default line ending will be used. + * + * @param file the file to write to + * @param encoding the encoding to use, null means platform default + * @param lines the lines to write, null entries produce blank lines + * @param append if true, then the lines will be added to the + * end of the file rather than overwriting + * @throws IOException in case of an I/O error + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @since Commons IO 2.1 + */ + public static void writeLines(File file, String encoding, Collection lines, boolean append) throws IOException { + writeLines(file, encoding, lines, null, append); + } + + /** + * Writes the toString() value of each item in a collection to + * the specified File line by line. + * The default VM encoding and the default line ending will be used. + * + * @param file the file to write to + * @param lines the lines to write, null entries produce blank lines + * @throws IOException in case of an I/O error + * @since Commons IO 1.3 + */ + public static void writeLines(File file, Collection lines) throws IOException { + writeLines(file, null, lines, null, false); + } + + /** + * Writes the toString() value of each item in a collection to + * the specified File line by line. + * The default VM encoding and the default line ending will be used. + * + * @param file the file to write to + * @param lines the lines to write, null entries produce blank lines + * @param append if true, then the lines will be added to the + * end of the file rather than overwriting + * @throws IOException in case of an I/O error + * @since Commons IO 2.1 + */ + public static void writeLines(File file, Collection lines, boolean append) throws IOException { + writeLines(file, null, lines, null, append); + } + + /** + * Writes the toString() value of each item in a collection to + * the specified File line by line. + * The specified character encoding and the line ending will be used. + *

+ * NOTE: As from v1.3, the parent directories of the file will be created + * if they do not exist. + * + * @param file the file to write to + * @param encoding the encoding to use, null means platform default + * @param lines the lines to write, null entries produce blank lines + * @param lineEnding the line separator to use, null is system default + * @throws IOException in case of an I/O error + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @since Commons IO 1.1 + */ + public static void writeLines(File file, String encoding, Collection lines, String lineEnding) + throws IOException { + writeLines(file, encoding, lines, lineEnding, false); + } + + /** + * Writes the toString() value of each item in a collection to + * the specified File line by line. + * The specified character encoding and the line ending will be used. + * + * @param file the file to write to + * @param encoding the encoding to use, null means platform default + * @param lines the lines to write, null entries produce blank lines + * @param lineEnding the line separator to use, null is system default + * @param append if true, then the lines will be added to the + * end of the file rather than overwriting + * @throws IOException in case of an I/O error + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @since Commons IO 2.1 + */ + public static void writeLines(File file, String encoding, Collection lines, String lineEnding, boolean append) + throws IOException { + OutputStream out = null; + try { + out = openOutputStream(file, append); + IOUtils.writeLines(lines, lineEnding, out, encoding); + } finally { + IOUtils.closeQuietly(out); + } + } + + /** + * Writes the toString() value of each item in a collection to + * the specified File line by line. + * The default VM encoding and the specified line ending will be used. + * + * @param file the file to write to + * @param lines the lines to write, null entries produce blank lines + * @param lineEnding the line separator to use, null is system default + * @throws IOException in case of an I/O error + * @since Commons IO 1.3 + */ + public static void writeLines(File file, Collection lines, String lineEnding) throws IOException { + writeLines(file, null, lines, lineEnding, false); + } + + /** + * Writes the toString() value of each item in a collection to + * the specified File line by line. + * The default VM encoding and the specified line ending will be used. + * + * @param file the file to write to + * @param lines the lines to write, null entries produce blank lines + * @param lineEnding the line separator to use, null is system default + * @param append if true, then the lines will be added to the + * end of the file rather than overwriting + * @throws IOException in case of an I/O error + * @since Commons IO 2.1 + */ + public static void writeLines(File file, Collection lines, String lineEnding, boolean append) + throws IOException { + writeLines(file, null, lines, lineEnding, append); + } + + //----------------------------------------------------------------------- + /** + * Deletes a file. If file is a directory, delete it and all sub-directories. + *

+ * The difference between File.delete() and this method are: + *

    + *
  • A directory to be deleted does not have to be empty.
  • + *
  • You get exceptions when a file or directory cannot be deleted. + * (java.io.File methods returns a boolean)
  • + *
+ * + * @param file file or directory to delete, must not be null + * @throws NullPointerException if the directory is null + * @throws FileNotFoundException if the file was not found + * @throws IOException in case deletion is unsuccessful + */ + public static void forceDelete(File file) throws IOException { + if (file.isDirectory()) { + deleteDirectory(file); + } else { + boolean filePresent = file.exists(); + if (!file.delete()) { + if (!filePresent){ + throw new FileNotFoundException("File does not exist: " + file); + } + String message = + "Unable to delete file: " + file; + throw new IOException(message); + } + } + } + + /** + * Schedules a file to be deleted when JVM exits. + * If file is directory delete it and all sub-directories. + * + * @param file file or directory to delete, must not be null + * @throws NullPointerException if the file is null + * @throws IOException in case deletion is unsuccessful + */ + public static void forceDeleteOnExit(File file) throws IOException { + if (file.isDirectory()) { + deleteDirectoryOnExit(file); + } else { + file.deleteOnExit(); + } + } + + /** + * Schedules a directory recursively for deletion on JVM exit. + * + * @param directory directory to delete, must not be null + * @throws NullPointerException if the directory is null + * @throws IOException in case deletion is unsuccessful + */ + private static void deleteDirectoryOnExit(File directory) throws IOException { + if (!directory.exists()) { + return; + } + + if (!isSymlink(directory)) { + cleanDirectoryOnExit(directory); + } + directory.deleteOnExit(); + } + + /** + * Cleans a directory without deleting it. + * + * @param directory directory to clean, must not be null + * @throws NullPointerException if the directory is null + * @throws IOException in case cleaning is unsuccessful + */ + private static void cleanDirectoryOnExit(File directory) throws IOException { + if (!directory.exists()) { + String message = directory + " does not exist"; + throw new IllegalArgumentException(message); + } + + if (!directory.isDirectory()) { + String message = directory + " is not a directory"; + throw new IllegalArgumentException(message); + } + + File[] files = directory.listFiles(); + if (files == null) { // null if security restricted + throw new IOException("Failed to list contents of " + directory); + } + + IOException exception = null; + for (File file : files) { + try { + forceDeleteOnExit(file); + } catch (IOException ioe) { + exception = ioe; + } + } + + if (null != exception) { + throw exception; + } + } + + /** + * Makes a directory, including any necessary but nonexistent parent + * directories. If a file already exists with specified name but it is + * not a directory then an IOException is thrown. + * If the directory cannot be created (or does not already exist) + * then an IOException is thrown. + * + * @param directory directory to create, must not be null + * @throws NullPointerException if the directory is null + * @throws IOException if the directory cannot be created or the file already exists but is not a directory + */ + public static void forceMkdir(File directory) throws IOException { + if (directory.exists()) { + if (!directory.isDirectory()) { + String message = + "File " + + directory + + " exists and is " + + "not a directory. Unable to create directory."; + throw new IOException(message); + } + } else { + if (!directory.mkdirs()) { + // Double-check that some other thread or process hasn't made + // the directory in the background + if (!directory.isDirectory()) + { + String message = + "Unable to create directory " + directory; + throw new IOException(message); + } + } + } + } + + //----------------------------------------------------------------------- + /** + * Returns the size of the specified file or directory. If the provided + * {@link File} is a regular file, then the file's length is returned. + * If the argument is a directory, then the size of the directory is + * calculated recursively. If a directory or subdirectory is security + * restricted, its size will not be included. + * + * @param file the regular file or directory to return the size + * of (must not be null). + * + * @return the length of the file, or recursive size of the directory, + * provided (in bytes). + * + * @throws NullPointerException if the file is null + * @throws IllegalArgumentException if the file does not exist. + * + * @since Commons IO 2.0 + */ + public static long sizeOf(File file) { + + if (!file.exists()) { + String message = file + " does not exist"; + throw new IllegalArgumentException(message); + } + + if (file.isDirectory()) { + return sizeOfDirectory(file); + } else { + return file.length(); + } + + } + + /** + * Counts the size of a directory recursively (sum of the length of all files). + * + * @param directory directory to inspect, must not be null + * @return size of directory in bytes, 0 if directory is security restricted + * @throws NullPointerException if the directory is null + */ + public static long sizeOfDirectory(File directory) { + if (!directory.exists()) { + String message = directory + " does not exist"; + throw new IllegalArgumentException(message); + } + + if (!directory.isDirectory()) { + String message = directory + " is not a directory"; + throw new IllegalArgumentException(message); + } + + long size = 0; + + File[] files = directory.listFiles(); + if (files == null) { // null if security restricted + return 0L; + } + for (File file : files) { + size += sizeOf(file); + } + + return size; + } + + //----------------------------------------------------------------------- + /** + * Tests if the specified File is newer than the reference + * File. + * + * @param file the File of which the modification date must + * be compared, must not be null + * @param reference the File of which the modification date + * is used, must not be null + * @return true if the File exists and has been modified more + * recently than the reference File + * @throws IllegalArgumentException if the file is null + * @throws IllegalArgumentException if the reference file is null or doesn't exist + */ + public static boolean isFileNewer(File file, File reference) { + if (reference == null) { + throw new IllegalArgumentException("No specified reference file"); + } + if (!reference.exists()) { + throw new IllegalArgumentException("The reference file '" + + reference + "' doesn't exist"); + } + return isFileNewer(file, reference.lastModified()); + } + + /** + * Tests if the specified File is newer than the specified + * Date. + * + * @param file the File of which the modification date + * must be compared, must not be null + * @param date the date reference, must not be null + * @return true if the File exists and has been modified + * after the given Date. + * @throws IllegalArgumentException if the file is null + * @throws IllegalArgumentException if the date is null + */ + public static boolean isFileNewer(File file, Date date) { + if (date == null) { + throw new IllegalArgumentException("No specified date"); + } + return isFileNewer(file, date.getTime()); + } + + /** + * Tests if the specified File is newer than the specified + * time reference. + * + * @param file the File of which the modification date must + * be compared, must not be null + * @param timeMillis the time reference measured in milliseconds since the + * epoch (00:00:00 GMT, January 1, 1970) + * @return true if the File exists and has been modified after + * the given time reference. + * @throws IllegalArgumentException if the file is null + */ + public static boolean isFileNewer(File file, long timeMillis) { + if (file == null) { + throw new IllegalArgumentException("No specified file"); + } + if (!file.exists()) { + return false; + } + return file.lastModified() > timeMillis; + } + + + //----------------------------------------------------------------------- + /** + * Tests if the specified File is older than the reference + * File. + * + * @param file the File of which the modification date must + * be compared, must not be null + * @param reference the File of which the modification date + * is used, must not be null + * @return true if the File exists and has been modified before + * the reference File + * @throws IllegalArgumentException if the file is null + * @throws IllegalArgumentException if the reference file is null or doesn't exist + */ + public static boolean isFileOlder(File file, File reference) { + if (reference == null) { + throw new IllegalArgumentException("No specified reference file"); + } + if (!reference.exists()) { + throw new IllegalArgumentException("The reference file '" + + reference + "' doesn't exist"); + } + return isFileOlder(file, reference.lastModified()); + } + + /** + * Tests if the specified File is older than the specified + * Date. + * + * @param file the File of which the modification date + * must be compared, must not be null + * @param date the date reference, must not be null + * @return true if the File exists and has been modified + * before the given Date. + * @throws IllegalArgumentException if the file is null + * @throws IllegalArgumentException if the date is null + */ + public static boolean isFileOlder(File file, Date date) { + if (date == null) { + throw new IllegalArgumentException("No specified date"); + } + return isFileOlder(file, date.getTime()); + } + + /** + * Tests if the specified File is older than the specified + * time reference. + * + * @param file the File of which the modification date must + * be compared, must not be null + * @param timeMillis the time reference measured in milliseconds since the + * epoch (00:00:00 GMT, January 1, 1970) + * @return true if the File exists and has been modified before + * the given time reference. + * @throws IllegalArgumentException if the file is null + */ + public static boolean isFileOlder(File file, long timeMillis) { + if (file == null) { + throw new IllegalArgumentException("No specified file"); + } + if (!file.exists()) { + return false; + } + return file.lastModified() < timeMillis; + } + + //----------------------------------------------------------------------- + /** + * Computes the checksum of a file using the CRC32 checksum routine. + * The value of the checksum is returned. + * + * @param file the file to checksum, must not be null + * @return the checksum value + * @throws NullPointerException if the file or checksum is null + * @throws IllegalArgumentException if the file is a directory + * @throws IOException if an IO error occurs reading the file + * @since Commons IO 1.3 + */ + public static long checksumCRC32(File file) throws IOException { + CRC32 crc = new CRC32(); + checksum(file, crc); + return crc.getValue(); + } + + /** + * Computes the checksum of a file using the specified checksum object. + * Multiple files may be checked using one Checksum instance + * if desired simply by reusing the same checksum object. + * For example: + *
+     *   long csum = FileUtils.checksum(file, new CRC32()).getValue();
+     * 
+ * + * @param file the file to checksum, must not be null + * @param checksum the checksum object to be used, must not be null + * @return the checksum specified, updated with the content of the file + * @throws NullPointerException if the file or checksum is null + * @throws IllegalArgumentException if the file is a directory + * @throws IOException if an IO error occurs reading the file + * @since Commons IO 1.3 + */ + public static Checksum checksum(File file, Checksum checksum) throws IOException { + if (file.isDirectory()) { + throw new IllegalArgumentException("Checksums can't be computed on directories"); + } + InputStream in = null; + try { + in = new CheckedInputStream(new FileInputStream(file), checksum); + IOUtils.copy(in, new NullOutputStream()); + } finally { + IOUtils.closeQuietly(in); + } + return checksum; + } + + /** + * Moves a directory. + *

+ * When the destination directory is on another file system, do a "copy and delete". + * + * @param srcDir the directory to be moved + * @param destDir the destination directory + * @throws NullPointerException if source or destination is null + * @throws FileExistsException if the destination directory exists + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs moving the file + * @since Commons IO 1.4 + */ + public static void moveDirectory(File srcDir, File destDir) throws IOException { + if (srcDir == null) { + throw new NullPointerException("Source must not be null"); + } + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (!srcDir.exists()) { + throw new FileNotFoundException("Source '" + srcDir + "' does not exist"); + } + if (!srcDir.isDirectory()) { + throw new IOException("Source '" + srcDir + "' is not a directory"); + } + if (destDir.exists()) { + throw new FileExistsException("Destination '" + destDir + "' already exists"); + } + boolean rename = srcDir.renameTo(destDir); + if (!rename) { + copyDirectory( srcDir, destDir ); + deleteDirectory( srcDir ); + if (srcDir.exists()) { + throw new IOException("Failed to delete original directory '" + srcDir + + "' after copy to '" + destDir + "'"); + } + } + } + + /** + * Moves a directory to another directory. + * + * @param src the file to be moved + * @param destDir the destination file + * @param createDestDir If true create the destination directory, + * otherwise if false throw an IOException + * @throws NullPointerException if source or destination is null + * @throws FileExistsException if the directory exists in the destination directory + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs moving the file + * @since Commons IO 1.4 + */ + public static void moveDirectoryToDirectory(File src, File destDir, boolean createDestDir) throws IOException { + if (src == null) { + throw new NullPointerException("Source must not be null"); + } + if (destDir == null) { + throw new NullPointerException("Destination directory must not be null"); + } + if (!destDir.exists() && createDestDir) { + destDir.mkdirs(); + } + if (!destDir.exists()) { + throw new FileNotFoundException("Destination directory '" + destDir + + "' does not exist [createDestDir=" + createDestDir +"]"); + } + if (!destDir.isDirectory()) { + throw new IOException("Destination '" + destDir + "' is not a directory"); + } + moveDirectory(src, new File(destDir, src.getName())); + + } + + /** + * Moves a file. + *

+ * When the destination file is on another file system, do a "copy and delete". + * + * @param srcFile the file to be moved + * @param destFile the destination file + * @throws NullPointerException if source or destination is null + * @throws FileExistsException if the destination file exists + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs moving the file + * @since Commons IO 1.4 + */ + public static void moveFile(File srcFile, File destFile) throws IOException { + if (srcFile == null) { + throw new NullPointerException("Source must not be null"); + } + if (destFile == null) { + throw new NullPointerException("Destination must not be null"); + } + if (!srcFile.exists()) { + throw new FileNotFoundException("Source '" + srcFile + "' does not exist"); + } + if (srcFile.isDirectory()) { + throw new IOException("Source '" + srcFile + "' is a directory"); + } + if (destFile.exists()) { + throw new FileExistsException("Destination '" + destFile + "' already exists"); + } + if (destFile.isDirectory()) { + throw new IOException("Destination '" + destFile + "' is a directory"); + } + boolean rename = srcFile.renameTo(destFile); + if (!rename) { + copyFile( srcFile, destFile ); + if (!srcFile.delete()) { + FileUtils.deleteQuietly(destFile); + throw new IOException("Failed to delete original file '" + srcFile + + "' after copy to '" + destFile + "'"); + } + } + } + + /** + * Moves a file to a directory. + * + * @param srcFile the file to be moved + * @param destDir the destination file + * @param createDestDir If true create the destination directory, + * otherwise if false throw an IOException + * @throws NullPointerException if source or destination is null + * @throws FileExistsException if the destination file exists + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs moving the file + * @since Commons IO 1.4 + */ + public static void moveFileToDirectory(File srcFile, File destDir, boolean createDestDir) throws IOException { + if (srcFile == null) { + throw new NullPointerException("Source must not be null"); + } + if (destDir == null) { + throw new NullPointerException("Destination directory must not be null"); + } + if (!destDir.exists() && createDestDir) { + destDir.mkdirs(); + } + if (!destDir.exists()) { + throw new FileNotFoundException("Destination directory '" + destDir + + "' does not exist [createDestDir=" + createDestDir +"]"); + } + if (!destDir.isDirectory()) { + throw new IOException("Destination '" + destDir + "' is not a directory"); + } + moveFile(srcFile, new File(destDir, srcFile.getName())); + } + + /** + * Moves a file or directory to the destination directory. + *

+ * When the destination is on another file system, do a "copy and delete". + * + * @param src the file or directory to be moved + * @param destDir the destination directory + * @param createDestDir If true create the destination directory, + * otherwise if false throw an IOException + * @throws NullPointerException if source or destination is null + * @throws FileExistsException if the directory or file exists in the destination directory + * @throws IOException if source or destination is invalid + * @throws IOException if an IO error occurs moving the file + * @since Commons IO 1.4 + */ + public static void moveToDirectory(File src, File destDir, boolean createDestDir) throws IOException { + if (src == null) { + throw new NullPointerException("Source must not be null"); + } + if (destDir == null) { + throw new NullPointerException("Destination must not be null"); + } + if (!src.exists()) { + throw new FileNotFoundException("Source '" + src + "' does not exist"); + } + if (src.isDirectory()) { + moveDirectoryToDirectory(src, destDir, createDestDir); + } else { + moveFileToDirectory(src, destDir, createDestDir); + } + } + + /** + * Determines whether the specified file is a Symbolic Link rather than an actual file. + *

+ * Will not return true if there is a Symbolic Link anywhere in the path, + * only if the specific file is. + * + * @param file the file to check + * @return true if the file is a Symbolic Link + * @throws IOException if an IO error occurs while checking the file + * @since Commons IO 2.0 + */ + public static boolean isSymlink(File file) throws IOException { + if (file == null) { + throw new NullPointerException("File must not be null"); + } + if (FilenameUtils.isSystemWindows()) { + return false; + } + File fileInCanonicalDir = null; + if (file.getParent() == null) { + fileInCanonicalDir = file; + } else { + File canonicalDir = file.getParentFile().getCanonicalFile(); + fileInCanonicalDir = new File(canonicalDir, file.getName()); + } + + if (fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile())) { + return false; + } else { + return true; + } + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/FilenameUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/FilenameUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/FilenameUtils.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,1368 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Stack; + +/** + * General filename and filepath manipulation utilities. + *

+ * When dealing with filenames you can hit problems when moving from a Windows + * based development machine to a Unix based production machine. + * This class aims to help avoid those problems. + *

+ * NOTE: You may be able to avoid using this class entirely simply by + * using JDK {@link java.io.File File} objects and the two argument constructor + * {@link java.io.File#File(java.io.File, java.lang.String) File(File,String)}. + *

+ * Most methods on this class are designed to work the same on both Unix and Windows. + * Those that don't include 'System', 'Unix' or 'Windows' in their name. + *

+ * Most methods recognise both separators (forward and back), and both + * sets of prefixes. See the javadoc of each method for details. + *

+ * This class defines six components within a filename + * (example C:\dev\project\file.txt): + *

    + *
  • the prefix - C:\
  • + *
  • the path - dev\project\
  • + *
  • the full path - C:\dev\project\
  • + *
  • the name - file.txt
  • + *
  • the base name - file
  • + *
  • the extension - txt
  • + *
+ * Note that this class works best if directory filenames end with a separator. + * If you omit the last separator, it is impossible to determine if the filename + * corresponds to a file or a directory. As a result, we have chosen to say + * it corresponds to a file. + *

+ * This class only supports Unix and Windows style names. + * Prefixes are matched as follows: + *

+ * Windows:
+ * a\b\c.txt           --> ""          --> relative
+ * \a\b\c.txt          --> "\"         --> current drive absolute
+ * C:a\b\c.txt         --> "C:"        --> drive relative
+ * C:\a\b\c.txt        --> "C:\"       --> absolute
+ * \\server\a\b\c.txt  --> "\\server\" --> UNC
+ *
+ * Unix:
+ * a/b/c.txt           --> ""          --> relative
+ * /a/b/c.txt          --> "/"         --> absolute
+ * ~/a/b/c.txt         --> "~/"        --> current user
+ * ~                   --> "~/"        --> current user (slash added)
+ * ~user/a/b/c.txt     --> "~user/"    --> named user
+ * ~user               --> "~user/"    --> named user (slash added)
+ * 
+ * Both prefix styles are matched always, irrespective of the machine that you are + * currently running on. + *

+ * Origin of code: Excalibur, Alexandria, Tomcat, Commons-Utils. + * + * @author Kevin A. Burton + * @author Scott Sanders + * @author Daniel Rall + * @author Christoph.Reck + * @author Peter Donald + * @author Jeff Turner + * @author Matthew Hawthorne + * @author Martin Cooper + * @author Jeremias Maerki + * @author Stephen Colebourne + * @version $Id: FilenameUtils.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + * @since Commons IO 1.1 + */ +public class FilenameUtils { + + /** + * The extension separator character. + * @since Commons IO 1.4 + */ + public static final char EXTENSION_SEPARATOR = '.'; + + /** + * The extension separator String. + * @since Commons IO 1.4 + */ + public static final String EXTENSION_SEPARATOR_STR = Character.toString(EXTENSION_SEPARATOR); + + /** + * The Unix separator character. + */ + private static final char UNIX_SEPARATOR = '/'; + + /** + * The Windows separator character. + */ + private static final char WINDOWS_SEPARATOR = '\\'; + + /** + * The system separator character. + */ + private static final char SYSTEM_SEPARATOR = File.separatorChar; + + /** + * The separator character that is the opposite of the system separator. + */ + private static final char OTHER_SEPARATOR; + static { + if (isSystemWindows()) { + OTHER_SEPARATOR = UNIX_SEPARATOR; + } else { + OTHER_SEPARATOR = WINDOWS_SEPARATOR; + } + } + + /** + * Instances should NOT be constructed in standard programming. + */ + public FilenameUtils() { + super(); + } + + //----------------------------------------------------------------------- + /** + * Determines if Windows file system is in use. + * + * @return true if the system is Windows + */ + static boolean isSystemWindows() { + return SYSTEM_SEPARATOR == WINDOWS_SEPARATOR; + } + + //----------------------------------------------------------------------- + /** + * Checks if the character is a separator. + * + * @param ch the character to check + * @return true if it is a separator character + */ + private static boolean isSeparator(char ch) { + return (ch == UNIX_SEPARATOR) || (ch == WINDOWS_SEPARATOR); + } + + //----------------------------------------------------------------------- + /** + * Normalizes a path, removing double and single dot path steps. + *

+ * This method normalizes a path to a standard format. + * The input may contain separators in either Unix or Windows format. + * The output will contain separators in the format of the system. + *

+ * A trailing slash will be retained. + * A double slash will be merged to a single slash (but UNC names are handled). + * A single dot path segment will be removed. + * A double dot will cause that path segment and the one before to be removed. + * If the double dot has no parent path segment to work with, null + * is returned. + *

+ * The output will be the same on both Unix and Windows except + * for the separator character. + *

+     * /foo//               -->   /foo/
+     * /foo/./              -->   /foo/
+     * /foo/../bar          -->   /bar
+     * /foo/../bar/         -->   /bar/
+     * /foo/../bar/../baz   -->   /baz
+     * //foo//./bar         -->   /foo/bar
+     * /../                 -->   null
+     * ../foo               -->   null
+     * foo/bar/..           -->   foo/
+     * foo/../../bar        -->   null
+     * foo/../bar           -->   bar
+     * //server/foo/../bar  -->   //server/bar
+     * //server/../bar      -->   null
+     * C:\foo\..\bar        -->   C:\bar
+     * C:\..\bar            -->   null
+     * ~/foo/../bar/        -->   ~/bar/
+     * ~/../bar             -->   null
+     * 
+ * (Note the file separator returned will be correct for Windows/Unix) + * + * @param filename the filename to normalize, null returns null + * @return the normalized filename, or null if invalid + */ + public static String normalize(String filename) { + return doNormalize(filename, SYSTEM_SEPARATOR, true); + } + /** + * Normalizes a path, removing double and single dot path steps. + *

+ * This method normalizes a path to a standard format. + * The input may contain separators in either Unix or Windows format. + * The output will contain separators in the format specified. + *

+ * A trailing slash will be retained. + * A double slash will be merged to a single slash (but UNC names are handled). + * A single dot path segment will be removed. + * A double dot will cause that path segment and the one before to be removed. + * If the double dot has no parent path segment to work with, null + * is returned. + *

+ * The output will be the same on both Unix and Windows except + * for the separator character. + *

+     * /foo//               -->   /foo/
+     * /foo/./              -->   /foo/
+     * /foo/../bar          -->   /bar
+     * /foo/../bar/         -->   /bar/
+     * /foo/../bar/../baz   -->   /baz
+     * //foo//./bar         -->   /foo/bar
+     * /../                 -->   null
+     * ../foo               -->   null
+     * foo/bar/..           -->   foo/
+     * foo/../../bar        -->   null
+     * foo/../bar           -->   bar
+     * //server/foo/../bar  -->   //server/bar
+     * //server/../bar      -->   null
+     * C:\foo\..\bar        -->   C:\bar
+     * C:\..\bar            -->   null
+     * ~/foo/../bar/        -->   ~/bar/
+     * ~/../bar             -->   null
+     * 
+ * The output will be the same on both Unix and Windows including + * the separator character. + * + * @param filename the filename to normalize, null returns null + * @param unixSeparator true if a unix separator should + * be used or false if a windows separator should be used. + * @return the normalized filename, or null if invalid + * @since Commons IO 2.0 + */ + public static String normalize(String filename, boolean unixSeparator) { + char separator = (unixSeparator ? UNIX_SEPARATOR : WINDOWS_SEPARATOR); + return doNormalize(filename, separator, true); + } + + //----------------------------------------------------------------------- + /** + * Normalizes a path, removing double and single dot path steps, + * and removing any final directory separator. + *

+ * This method normalizes a path to a standard format. + * The input may contain separators in either Unix or Windows format. + * The output will contain separators in the format of the system. + *

+ * A trailing slash will be removed. + * A double slash will be merged to a single slash (but UNC names are handled). + * A single dot path segment will be removed. + * A double dot will cause that path segment and the one before to be removed. + * If the double dot has no parent path segment to work with, null + * is returned. + *

+ * The output will be the same on both Unix and Windows except + * for the separator character. + *

+     * /foo//               -->   /foo
+     * /foo/./              -->   /foo
+     * /foo/../bar          -->   /bar
+     * /foo/../bar/         -->   /bar
+     * /foo/../bar/../baz   -->   /baz
+     * //foo//./bar         -->   /foo/bar
+     * /../                 -->   null
+     * ../foo               -->   null
+     * foo/bar/..           -->   foo
+     * foo/../../bar        -->   null
+     * foo/../bar           -->   bar
+     * //server/foo/../bar  -->   //server/bar
+     * //server/../bar      -->   null
+     * C:\foo\..\bar        -->   C:\bar
+     * C:\..\bar            -->   null
+     * ~/foo/../bar/        -->   ~/bar
+     * ~/../bar             -->   null
+     * 
+ * (Note the file separator returned will be correct for Windows/Unix) + * + * @param filename the filename to normalize, null returns null + * @return the normalized filename, or null if invalid + */ + public static String normalizeNoEndSeparator(String filename) { + return doNormalize(filename, SYSTEM_SEPARATOR, false); + } + + /** + * Normalizes a path, removing double and single dot path steps, + * and removing any final directory separator. + *

+ * This method normalizes a path to a standard format. + * The input may contain separators in either Unix or Windows format. + * The output will contain separators in the format specified. + *

+ * A trailing slash will be removed. + * A double slash will be merged to a single slash (but UNC names are handled). + * A single dot path segment will be removed. + * A double dot will cause that path segment and the one before to be removed. + * If the double dot has no parent path segment to work with, null + * is returned. + *

+ * The output will be the same on both Unix and Windows including + * the separator character. + *

+     * /foo//               -->   /foo
+     * /foo/./              -->   /foo
+     * /foo/../bar          -->   /bar
+     * /foo/../bar/         -->   /bar
+     * /foo/../bar/../baz   -->   /baz
+     * //foo//./bar         -->   /foo/bar
+     * /../                 -->   null
+     * ../foo               -->   null
+     * foo/bar/..           -->   foo
+     * foo/../../bar        -->   null
+     * foo/../bar           -->   bar
+     * //server/foo/../bar  -->   //server/bar
+     * //server/../bar      -->   null
+     * C:\foo\..\bar        -->   C:\bar
+     * C:\..\bar            -->   null
+     * ~/foo/../bar/        -->   ~/bar
+     * ~/../bar             -->   null
+     * 
+ * + * @param filename the filename to normalize, null returns null + * @param unixSeparator true if a unix separator should + * be used or false if a windows separtor should be used. + * @return the normalized filename, or null if invalid + * @since Commons IO 2.0 + */ + public static String normalizeNoEndSeparator(String filename, boolean unixSeparator) { + char separator = (unixSeparator ? UNIX_SEPARATOR : WINDOWS_SEPARATOR); + return doNormalize(filename, separator, false); + } + + /** + * Internal method to perform the normalization. + * + * @param filename the filename + * @param separator The separator character to use + * @param keepSeparator true to keep the final separator + * @return the normalized filename + */ + private static String doNormalize(String filename, char separator, boolean keepSeparator) { + if (filename == null) { + return null; + } + int size = filename.length(); + if (size == 0) { + return filename; + } + int prefix = getPrefixLength(filename); + if (prefix < 0) { + return null; + } + + char[] array = new char[size + 2]; // +1 for possible extra slash, +2 for arraycopy + filename.getChars(0, filename.length(), array, 0); + + // fix separators throughout + char otherSeparator = (separator == SYSTEM_SEPARATOR ? OTHER_SEPARATOR : SYSTEM_SEPARATOR); + for (int i = 0; i < array.length; i++) { + if (array[i] == otherSeparator) { + array[i] = separator; + } + } + + // add extra separator on the end to simplify code below + boolean lastIsDirectory = true; + if (array[size - 1] != separator) { + array[size++] = separator; + lastIsDirectory = false; + } + + // adjoining slashes + for (int i = prefix + 1; i < size; i++) { + if (array[i] == separator && array[i - 1] == separator) { + System.arraycopy(array, i, array, i - 1, size - i); + size--; + i--; + } + } + + // dot slash + for (int i = prefix + 1; i < size; i++) { + if (array[i] == separator && array[i - 1] == '.' && + (i == prefix + 1 || array[i - 2] == separator)) { + if (i == size - 1) { + lastIsDirectory = true; + } + System.arraycopy(array, i + 1, array, i - 1, size - i); + size -=2; + i--; + } + } + + // double dot slash + outer: + for (int i = prefix + 2; i < size; i++) { + if (array[i] == separator && array[i - 1] == '.' && array[i - 2] == '.' && + (i == prefix + 2 || array[i - 3] == separator)) { + if (i == prefix + 2) { + return null; + } + if (i == size - 1) { + lastIsDirectory = true; + } + int j; + for (j = i - 4 ; j >= prefix; j--) { + if (array[j] == separator) { + // remove b/../ from a/b/../c + System.arraycopy(array, i + 1, array, j + 1, size - i); + size -= (i - j); + i = j + 1; + continue outer; + } + } + // remove a/../ from a/../c + System.arraycopy(array, i + 1, array, prefix, size - i); + size -= (i + 1 - prefix); + i = prefix + 1; + } + } + + if (size <= 0) { // should never be less than 0 + return ""; + } + if (size <= prefix) { // should never be less than prefix + return new String(array, 0, size); + } + if (lastIsDirectory && keepSeparator) { + return new String(array, 0, size); // keep trailing separator + } + return new String(array, 0, size - 1); // lose trailing separator + } + + //----------------------------------------------------------------------- + /** + * Concatenates a filename to a base path using normal command line style rules. + *

+ * The effect is equivalent to resultant directory after changing + * directory to the first argument, followed by changing directory to + * the second argument. + *

+ * The first argument is the base path, the second is the path to concatenate. + * The returned path is always normalized via {@link #normalize(String)}, + * thus .. is handled. + *

+ * If pathToAdd is absolute (has an absolute prefix), then + * it will be normalized and returned. + * Otherwise, the paths will be joined, normalized and returned. + *

+ * The output will be the same on both Unix and Windows except + * for the separator character. + *

+     * /foo/ + bar          -->   /foo/bar
+     * /foo + bar           -->   /foo/bar
+     * /foo + /bar          -->   /bar
+     * /foo + C:/bar        -->   C:/bar
+     * /foo + C:bar         -->   C:bar (*)
+     * /foo/a/ + ../bar     -->   foo/bar
+     * /foo/ + ../../bar    -->   null
+     * /foo/ + /bar         -->   /bar
+     * /foo/.. + /bar       -->   /bar
+     * /foo + bar/c.txt     -->   /foo/bar/c.txt
+     * /foo/c.txt + bar     -->   /foo/c.txt/bar (!)
+     * 
+ * (*) Note that the Windows relative drive prefix is unreliable when + * used with this method. + * (!) Note that the first parameter must be a path. If it ends with a name, then + * the name will be built into the concatenated path. If this might be a problem, + * use {@link #getFullPath(String)} on the base path argument. + * + * @param basePath the base path to attach to, always treated as a path + * @param fullFilenameToAdd the filename (or path) to attach to the base + * @return the concatenated path, or null if invalid + */ + public static String concat(String basePath, String fullFilenameToAdd) { + int prefix = getPrefixLength(fullFilenameToAdd); + if (prefix < 0) { + return null; + } + if (prefix > 0) { + return normalize(fullFilenameToAdd); + } + if (basePath == null) { + return null; + } + int len = basePath.length(); + if (len == 0) { + return normalize(fullFilenameToAdd); + } + char ch = basePath.charAt(len - 1); + if (isSeparator(ch)) { + return normalize(basePath + fullFilenameToAdd); + } else { + return normalize(basePath + '/' + fullFilenameToAdd); + } + } + + //----------------------------------------------------------------------- + /** + * Converts all separators to the Unix separator of forward slash. + * + * @param path the path to be changed, null ignored + * @return the updated path + */ + public static String separatorsToUnix(String path) { + if (path == null || path.indexOf(WINDOWS_SEPARATOR) == -1) { + return path; + } + return path.replace(WINDOWS_SEPARATOR, UNIX_SEPARATOR); + } + + /** + * Converts all separators to the Windows separator of backslash. + * + * @param path the path to be changed, null ignored + * @return the updated path + */ + public static String separatorsToWindows(String path) { + if (path == null || path.indexOf(UNIX_SEPARATOR) == -1) { + return path; + } + return path.replace(UNIX_SEPARATOR, WINDOWS_SEPARATOR); + } + + /** + * Converts all separators to the system separator. + * + * @param path the path to be changed, null ignored + * @return the updated path + */ + public static String separatorsToSystem(String path) { + if (path == null) { + return null; + } + if (isSystemWindows()) { + return separatorsToWindows(path); + } else { + return separatorsToUnix(path); + } + } + + //----------------------------------------------------------------------- + /** + * Returns the length of the filename prefix, such as C:/ or ~/. + *

+ * This method will handle a file in either Unix or Windows format. + *

+ * The prefix length includes the first slash in the full filename + * if applicable. Thus, it is possible that the length returned is greater + * than the length of the input string. + *

+     * Windows:
+     * a\b\c.txt           --> ""          --> relative
+     * \a\b\c.txt          --> "\"         --> current drive absolute
+     * C:a\b\c.txt         --> "C:"        --> drive relative
+     * C:\a\b\c.txt        --> "C:\"       --> absolute
+     * \\server\a\b\c.txt  --> "\\server\" --> UNC
+     *
+     * Unix:
+     * a/b/c.txt           --> ""          --> relative
+     * /a/b/c.txt          --> "/"         --> absolute
+     * ~/a/b/c.txt         --> "~/"        --> current user
+     * ~                   --> "~/"        --> current user (slash added)
+     * ~user/a/b/c.txt     --> "~user/"    --> named user
+     * ~user               --> "~user/"    --> named user (slash added)
+     * 
+ *

+ * The output will be the same irrespective of the machine that the code is running on. + * ie. both Unix and Windows prefixes are matched regardless. + * + * @param filename the filename to find the prefix in, null returns -1 + * @return the length of the prefix, -1 if invalid or null + */ + public static int getPrefixLength(String filename) { + if (filename == null) { + return -1; + } + int len = filename.length(); + if (len == 0) { + return 0; + } + char ch0 = filename.charAt(0); + if (ch0 == ':') { + return -1; + } + if (len == 1) { + if (ch0 == '~') { + return 2; // return a length greater than the input + } + return (isSeparator(ch0) ? 1 : 0); + } else { + if (ch0 == '~') { + int posUnix = filename.indexOf(UNIX_SEPARATOR, 1); + int posWin = filename.indexOf(WINDOWS_SEPARATOR, 1); + if (posUnix == -1 && posWin == -1) { + return len + 1; // return a length greater than the input + } + posUnix = (posUnix == -1 ? posWin : posUnix); + posWin = (posWin == -1 ? posUnix : posWin); + return Math.min(posUnix, posWin) + 1; + } + char ch1 = filename.charAt(1); + if (ch1 == ':') { + ch0 = Character.toUpperCase(ch0); + if (ch0 >= 'A' && ch0 <= 'Z') { + if (len == 2 || isSeparator(filename.charAt(2)) == false) { + return 2; + } + return 3; + } + return -1; + + } else if (isSeparator(ch0) && isSeparator(ch1)) { + int posUnix = filename.indexOf(UNIX_SEPARATOR, 2); + int posWin = filename.indexOf(WINDOWS_SEPARATOR, 2); + if ((posUnix == -1 && posWin == -1) || posUnix == 2 || posWin == 2) { + return -1; + } + posUnix = (posUnix == -1 ? posWin : posUnix); + posWin = (posWin == -1 ? posUnix : posWin); + return Math.min(posUnix, posWin) + 1; + } else { + return (isSeparator(ch0) ? 1 : 0); + } + } + } + + /** + * Returns the index of the last directory separator character. + *

+ * This method will handle a file in either Unix or Windows format. + * The position of the last forward or backslash is returned. + *

+ * The output will be the same irrespective of the machine that the code is running on. + * + * @param filename the filename to find the last path separator in, null returns -1 + * @return the index of the last separator character, or -1 if there + * is no such character + */ + public static int indexOfLastSeparator(String filename) { + if (filename == null) { + return -1; + } + int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR); + int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR); + return Math.max(lastUnixPos, lastWindowsPos); + } + + /** + * Returns the index of the last extension separator character, which is a dot. + *

+ * This method also checks that there is no directory separator after the last dot. + * To do this it uses {@link #indexOfLastSeparator(String)} which will + * handle a file in either Unix or Windows format. + *

+ * The output will be the same irrespective of the machine that the code is running on. + * + * @param filename the filename to find the last path separator in, null returns -1 + * @return the index of the last separator character, or -1 if there + * is no such character + */ + public static int indexOfExtension(String filename) { + if (filename == null) { + return -1; + } + int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR); + int lastSeparator = indexOfLastSeparator(filename); + return (lastSeparator > extensionPos ? -1 : extensionPos); + } + + //----------------------------------------------------------------------- + /** + * Gets the prefix from a full filename, such as C:/ + * or ~/. + *

+ * This method will handle a file in either Unix or Windows format. + * The prefix includes the first slash in the full filename where applicable. + *

+     * Windows:
+     * a\b\c.txt           --> ""          --> relative
+     * \a\b\c.txt          --> "\"         --> current drive absolute
+     * C:a\b\c.txt         --> "C:"        --> drive relative
+     * C:\a\b\c.txt        --> "C:\"       --> absolute
+     * \\server\a\b\c.txt  --> "\\server\" --> UNC
+     *
+     * Unix:
+     * a/b/c.txt           --> ""          --> relative
+     * /a/b/c.txt          --> "/"         --> absolute
+     * ~/a/b/c.txt         --> "~/"        --> current user
+     * ~                   --> "~/"        --> current user (slash added)
+     * ~user/a/b/c.txt     --> "~user/"    --> named user
+     * ~user               --> "~user/"    --> named user (slash added)
+     * 
+ *

+ * The output will be the same irrespective of the machine that the code is running on. + * ie. both Unix and Windows prefixes are matched regardless. + * + * @param filename the filename to query, null returns null + * @return the prefix of the file, null if invalid + */ + public static String getPrefix(String filename) { + if (filename == null) { + return null; + } + int len = getPrefixLength(filename); + if (len < 0) { + return null; + } + if (len > filename.length()) { + return filename + UNIX_SEPARATOR; // we know this only happens for unix + } + return filename.substring(0, len); + } + + /** + * Gets the path from a full filename, which excludes the prefix. + *

+ * This method will handle a file in either Unix or Windows format. + * The method is entirely text based, and returns the text before and + * including the last forward or backslash. + *

+     * C:\a\b\c.txt --> a\b\
+     * ~/a/b/c.txt  --> a/b/
+     * a.txt        --> ""
+     * a/b/c        --> a/b/
+     * a/b/c/       --> a/b/c/
+     * 
+ *

+ * The output will be the same irrespective of the machine that the code is running on. + *

+ * This method drops the prefix from the result. + * See {@link #getFullPath(String)} for the method that retains the prefix. + * + * @param filename the filename to query, null returns null + * @return the path of the file, an empty string if none exists, null if invalid + */ + public static String getPath(String filename) { + return doGetPath(filename, 1); + } + + /** + * Gets the path from a full filename, which excludes the prefix, and + * also excluding the final directory separator. + *

+ * This method will handle a file in either Unix or Windows format. + * The method is entirely text based, and returns the text before the + * last forward or backslash. + *

+     * C:\a\b\c.txt --> a\b
+     * ~/a/b/c.txt  --> a/b
+     * a.txt        --> ""
+     * a/b/c        --> a/b
+     * a/b/c/       --> a/b/c
+     * 
+ *

+ * The output will be the same irrespective of the machine that the code is running on. + *

+ * This method drops the prefix from the result. + * See {@link #getFullPathNoEndSeparator(String)} for the method that retains the prefix. + * + * @param filename the filename to query, null returns null + * @return the path of the file, an empty string if none exists, null if invalid + */ + public static String getPathNoEndSeparator(String filename) { + return doGetPath(filename, 0); + } + + /** + * Does the work of getting the path. + * + * @param filename the filename + * @param separatorAdd 0 to omit the end separator, 1 to return it + * @return the path + */ + private static String doGetPath(String filename, int separatorAdd) { + if (filename == null) { + return null; + } + int prefix = getPrefixLength(filename); + if (prefix < 0) { + return null; + } + int index = indexOfLastSeparator(filename); + int endIndex = index+separatorAdd; + if (prefix >= filename.length() || index < 0 || prefix >= endIndex) { + return ""; + } + return filename.substring(prefix, endIndex); + } + + /** + * Gets the full path from a full filename, which is the prefix + path. + *

+ * This method will handle a file in either Unix or Windows format. + * The method is entirely text based, and returns the text before and + * including the last forward or backslash. + *

+     * C:\a\b\c.txt --> C:\a\b\
+     * ~/a/b/c.txt  --> ~/a/b/
+     * a.txt        --> ""
+     * a/b/c        --> a/b/
+     * a/b/c/       --> a/b/c/
+     * C:           --> C:
+     * C:\          --> C:\
+     * ~            --> ~/
+     * ~/           --> ~/
+     * ~user        --> ~user/
+     * ~user/       --> ~user/
+     * 
+ *

+ * The output will be the same irrespective of the machine that the code is running on. + * + * @param filename the filename to query, null returns null + * @return the path of the file, an empty string if none exists, null if invalid + */ + public static String getFullPath(String filename) { + return doGetFullPath(filename, true); + } + + /** + * Gets the full path from a full filename, which is the prefix + path, + * and also excluding the final directory separator. + *

+ * This method will handle a file in either Unix or Windows format. + * The method is entirely text based, and returns the text before the + * last forward or backslash. + *

+     * C:\a\b\c.txt --> C:\a\b
+     * ~/a/b/c.txt  --> ~/a/b
+     * a.txt        --> ""
+     * a/b/c        --> a/b
+     * a/b/c/       --> a/b/c
+     * C:           --> C:
+     * C:\          --> C:\
+     * ~            --> ~
+     * ~/           --> ~
+     * ~user        --> ~user
+     * ~user/       --> ~user
+     * 
+ *

+ * The output will be the same irrespective of the machine that the code is running on. + * + * @param filename the filename to query, null returns null + * @return the path of the file, an empty string if none exists, null if invalid + */ + public static String getFullPathNoEndSeparator(String filename) { + return doGetFullPath(filename, false); + } + + /** + * Does the work of getting the path. + * + * @param filename the filename + * @param includeSeparator true to include the end separator + * @return the path + */ + private static String doGetFullPath(String filename, boolean includeSeparator) { + if (filename == null) { + return null; + } + int prefix = getPrefixLength(filename); + if (prefix < 0) { + return null; + } + if (prefix >= filename.length()) { + if (includeSeparator) { + return getPrefix(filename); // add end slash if necessary + } else { + return filename; + } + } + int index = indexOfLastSeparator(filename); + if (index < 0) { + return filename.substring(0, prefix); + } + int end = index + (includeSeparator ? 1 : 0); + if (end == 0) { + end++; + } + return filename.substring(0, end); + } + + /** + * Gets the name minus the path from a full filename. + *

+ * This method will handle a file in either Unix or Windows format. + * The text after the last forward or backslash is returned. + *

+     * a/b/c.txt --> c.txt
+     * a.txt     --> a.txt
+     * a/b/c     --> c
+     * a/b/c/    --> ""
+     * 
+ *

+ * The output will be the same irrespective of the machine that the code is running on. + * + * @param filename the filename to query, null returns null + * @return the name of the file without the path, or an empty string if none exists + */ + public static String getName(String filename) { + if (filename == null) { + return null; + } + int index = indexOfLastSeparator(filename); + return filename.substring(index + 1); + } + + /** + * Gets the base name, minus the full path and extension, from a full filename. + *

+ * This method will handle a file in either Unix or Windows format. + * The text after the last forward or backslash and before the last dot is returned. + *

+     * a/b/c.txt --> c
+     * a.txt     --> a
+     * a/b/c     --> c
+     * a/b/c/    --> ""
+     * 
+ *

+ * The output will be the same irrespective of the machine that the code is running on. + * + * @param filename the filename to query, null returns null + * @return the name of the file without the path, or an empty string if none exists + */ + public static String getBaseName(String filename) { + return removeExtension(getName(filename)); + } + + /** + * Gets the extension of a filename. + *

+ * This method returns the textual part of the filename after the last dot. + * There must be no directory separator after the dot. + *

+     * foo.txt      --> "txt"
+     * a/b/c.jpg    --> "jpg"
+     * a/b.txt/c    --> ""
+     * a/b/c        --> ""
+     * 
+ *

+ * The output will be the same irrespective of the machine that the code is running on. + * + * @param filename the filename to retrieve the extension of. + * @return the extension of the file or an empty string if none exists or null + * if the filename is null. + */ + public static String getExtension(String filename) { + if (filename == null) { + return null; + } + int index = indexOfExtension(filename); + if (index == -1) { + return ""; + } else { + return filename.substring(index + 1); + } + } + + //----------------------------------------------------------------------- + /** + * Removes the extension from a filename. + *

+ * This method returns the textual part of the filename before the last dot. + * There must be no directory separator after the dot. + *

+     * foo.txt    --> foo
+     * a\b\c.jpg  --> a\b\c
+     * a\b\c      --> a\b\c
+     * a.b\c      --> a.b\c
+     * 
+ *

+ * The output will be the same irrespective of the machine that the code is running on. + * + * @param filename the filename to query, null returns null + * @return the filename minus the extension + */ + public static String removeExtension(String filename) { + if (filename == null) { + return null; + } + int index = indexOfExtension(filename); + if (index == -1) { + return filename; + } else { + return filename.substring(0, index); + } + } + + //----------------------------------------------------------------------- + /** + * Checks whether two filenames are equal exactly. + *

+ * No processing is performed on the filenames other than comparison, + * thus this is merely a null-safe case-sensitive equals. + * + * @param filename1 the first filename to query, may be null + * @param filename2 the second filename to query, may be null + * @return true if the filenames are equal, null equals null + * @see IOCase#SENSITIVE + */ + public static boolean equals(String filename1, String filename2) { + return equals(filename1, filename2, false, IOCase.SENSITIVE); + } + + /** + * Checks whether two filenames are equal using the case rules of the system. + *

+ * No processing is performed on the filenames other than comparison. + * The check is case-sensitive on Unix and case-insensitive on Windows. + * + * @param filename1 the first filename to query, may be null + * @param filename2 the second filename to query, may be null + * @return true if the filenames are equal, null equals null + * @see IOCase#SYSTEM + */ + public static boolean equalsOnSystem(String filename1, String filename2) { + return equals(filename1, filename2, false, IOCase.SYSTEM); + } + + //----------------------------------------------------------------------- + /** + * Checks whether two filenames are equal after both have been normalized. + *

+ * Both filenames are first passed to {@link #normalize(String)}. + * The check is then performed in a case-sensitive manner. + * + * @param filename1 the first filename to query, may be null + * @param filename2 the second filename to query, may be null + * @return true if the filenames are equal, null equals null + * @see IOCase#SENSITIVE + */ + public static boolean equalsNormalized(String filename1, String filename2) { + return equals(filename1, filename2, true, IOCase.SENSITIVE); + } + + /** + * Checks whether two filenames are equal after both have been normalized + * and using the case rules of the system. + *

+ * Both filenames are first passed to {@link #normalize(String)}. + * The check is then performed case-sensitive on Unix and + * case-insensitive on Windows. + * + * @param filename1 the first filename to query, may be null + * @param filename2 the second filename to query, may be null + * @return true if the filenames are equal, null equals null + * @see IOCase#SYSTEM + */ + public static boolean equalsNormalizedOnSystem(String filename1, String filename2) { + return equals(filename1, filename2, true, IOCase.SYSTEM); + } + + /** + * Checks whether two filenames are equal, optionally normalizing and providing + * control over the case-sensitivity. + * + * @param filename1 the first filename to query, may be null + * @param filename2 the second filename to query, may be null + * @param normalized whether to normalize the filenames + * @param caseSensitivity what case sensitivity rule to use, null means case-sensitive + * @return true if the filenames are equal, null equals null + * @since Commons IO 1.3 + */ + public static boolean equals( + String filename1, String filename2, + boolean normalized, IOCase caseSensitivity) { + + if (filename1 == null || filename2 == null) { + return (filename1 == null && filename2 == null); + } + if (normalized) { + filename1 = normalize(filename1); + filename2 = normalize(filename2); + if (filename1 == null || filename2 == null) { + throw new NullPointerException( + "Error normalizing one or both of the file names"); + } + } + if (caseSensitivity == null) { + caseSensitivity = IOCase.SENSITIVE; + } + return caseSensitivity.checkEquals(filename1, filename2); + } + + //----------------------------------------------------------------------- + /** + * Checks whether the extension of the filename is that specified. + *

+ * This method obtains the extension as the textual part of the filename + * after the last dot. There must be no directory separator after the dot. + * The extension check is case-sensitive on all platforms. + * + * @param filename the filename to query, null returns false + * @param extension the extension to check for, null or empty checks for no extension + * @return true if the filename has the specified extension + */ + public static boolean isExtension(String filename, String extension) { + if (filename == null) { + return false; + } + if (extension == null || extension.length() == 0) { + return (indexOfExtension(filename) == -1); + } + String fileExt = getExtension(filename); + return fileExt.equals(extension); + } + + /** + * Checks whether the extension of the filename is one of those specified. + *

+ * This method obtains the extension as the textual part of the filename + * after the last dot. There must be no directory separator after the dot. + * The extension check is case-sensitive on all platforms. + * + * @param filename the filename to query, null returns false + * @param extensions the extensions to check for, null checks for no extension + * @return true if the filename is one of the extensions + */ + public static boolean isExtension(String filename, String[] extensions) { + if (filename == null) { + return false; + } + if (extensions == null || extensions.length == 0) { + return (indexOfExtension(filename) == -1); + } + String fileExt = getExtension(filename); + for (String extension : extensions) { + if (fileExt.equals(extension)) { + return true; + } + } + return false; + } + + /** + * Checks whether the extension of the filename is one of those specified. + *

+ * This method obtains the extension as the textual part of the filename + * after the last dot. There must be no directory separator after the dot. + * The extension check is case-sensitive on all platforms. + * + * @param filename the filename to query, null returns false + * @param extensions the extensions to check for, null checks for no extension + * @return true if the filename is one of the extensions + */ + public static boolean isExtension(String filename, Collection extensions) { + if (filename == null) { + return false; + } + if (extensions == null || extensions.isEmpty()) { + return (indexOfExtension(filename) == -1); + } + String fileExt = getExtension(filename); + for (String extension : extensions) { + if (fileExt.equals(extension)) { + return true; + } + } + return false; + } + + //----------------------------------------------------------------------- + /** + * Checks a filename to see if it matches the specified wildcard matcher, + * always testing case-sensitive. + *

+ * The wildcard matcher uses the characters '?' and '*' to represent a + * single or multiple (zero or more) wildcard characters. + * This is the same as often found on Dos/Unix command lines. + * The check is case-sensitive always. + *

+     * wildcardMatch("c.txt", "*.txt")      --> true
+     * wildcardMatch("c.txt", "*.jpg")      --> false
+     * wildcardMatch("a/b/c.txt", "a/b/*")  --> true
+     * wildcardMatch("c.txt", "*.???")      --> true
+     * wildcardMatch("c.txt", "*.????")     --> false
+     * 
+ * N.B. the sequence "*?" does not work properly at present in match strings. + * + * @param filename the filename to match on + * @param wildcardMatcher the wildcard string to match against + * @return true if the filename matches the wilcard string + * @see IOCase#SENSITIVE + */ + public static boolean wildcardMatch(String filename, String wildcardMatcher) { + return wildcardMatch(filename, wildcardMatcher, IOCase.SENSITIVE); + } + + /** + * Checks a filename to see if it matches the specified wildcard matcher + * using the case rules of the system. + *

+ * The wildcard matcher uses the characters '?' and '*' to represent a + * single or multiple (zero or more) wildcard characters. + * This is the same as often found on Dos/Unix command lines. + * The check is case-sensitive on Unix and case-insensitive on Windows. + *

+     * wildcardMatch("c.txt", "*.txt")      --> true
+     * wildcardMatch("c.txt", "*.jpg")      --> false
+     * wildcardMatch("a/b/c.txt", "a/b/*")  --> true
+     * wildcardMatch("c.txt", "*.???")      --> true
+     * wildcardMatch("c.txt", "*.????")     --> false
+     * 
+ * N.B. the sequence "*?" does not work properly at present in match strings. + * + * @param filename the filename to match on + * @param wildcardMatcher the wildcard string to match against + * @return true if the filename matches the wilcard string + * @see IOCase#SYSTEM + */ + public static boolean wildcardMatchOnSystem(String filename, String wildcardMatcher) { + return wildcardMatch(filename, wildcardMatcher, IOCase.SYSTEM); + } + + /** + * Checks a filename to see if it matches the specified wildcard matcher + * allowing control over case-sensitivity. + *

+ * The wildcard matcher uses the characters '?' and '*' to represent a + * single or multiple (zero or more) wildcard characters. + * N.B. the sequence "*?" does not work properly at present in match strings. + * + * @param filename the filename to match on + * @param wildcardMatcher the wildcard string to match against + * @param caseSensitivity what case sensitivity rule to use, null means case-sensitive + * @return true if the filename matches the wilcard string + * @since Commons IO 1.3 + */ + public static boolean wildcardMatch(String filename, String wildcardMatcher, IOCase caseSensitivity) { + if (filename == null && wildcardMatcher == null) { + return true; + } + if (filename == null || wildcardMatcher == null) { + return false; + } + if (caseSensitivity == null) { + caseSensitivity = IOCase.SENSITIVE; + } + String[] wcs = splitOnTokens(wildcardMatcher); + boolean anyChars = false; + int textIdx = 0; + int wcsIdx = 0; + Stack backtrack = new Stack(); + + // loop around a backtrack stack, to handle complex * matching + do { + if (backtrack.size() > 0) { + int[] array = backtrack.pop(); + wcsIdx = array[0]; + textIdx = array[1]; + anyChars = true; + } + + // loop whilst tokens and text left to process + while (wcsIdx < wcs.length) { + + if (wcs[wcsIdx].equals("?")) { + // ? so move to next text char + textIdx++; + if (textIdx > filename.length()) { + break; + } + anyChars = false; + + } else if (wcs[wcsIdx].equals("*")) { + // set any chars status + anyChars = true; + if (wcsIdx == wcs.length - 1) { + textIdx = filename.length(); + } + + } else { + // matching text token + if (anyChars) { + // any chars then try to locate text token + textIdx = caseSensitivity.checkIndexOf(filename, textIdx, wcs[wcsIdx]); + if (textIdx == -1) { + // token not found + break; + } + int repeat = caseSensitivity.checkIndexOf(filename, textIdx + 1, wcs[wcsIdx]); + if (repeat >= 0) { + backtrack.push(new int[] {wcsIdx, repeat}); + } + } else { + // matching from current position + if (!caseSensitivity.checkRegionMatches(filename, textIdx, wcs[wcsIdx])) { + // couldnt match token + break; + } + } + + // matched text token, move text index to end of matched token + textIdx += wcs[wcsIdx].length(); + anyChars = false; + } + + wcsIdx++; + } + + // full match + if (wcsIdx == wcs.length && textIdx == filename.length()) { + return true; + } + + } while (backtrack.size() > 0); + + return false; + } + + /** + * Splits a string into a number of tokens. + * The text is split by '?' and '*'. + * Where multiple '*' occur consecutively they are collapsed into a single '*'. + * + * @param text the text to split + * @return the array of tokens, never null + */ + static String[] splitOnTokens(String text) { + // used by wildcardMatch + // package level so a unit test may run on this + + if (text.indexOf('?') == -1 && text.indexOf('*') == -1) { + return new String[] { text }; + } + + char[] array = text.toCharArray(); + ArrayList list = new ArrayList(); + StringBuilder buffer = new StringBuilder(); + for (int i = 0; i < array.length; i++) { + if (array[i] == '?' || array[i] == '*') { + if (buffer.length() != 0) { + list.add(buffer.toString()); + buffer.setLength(0); + } + if (array[i] == '?') { + list.add("?"); + } else if (list.size() == 0 || + (i > 0 && list.get(list.size() - 1).equals("*") == false)) { + list.add("*"); + } + } else { + buffer.append(array[i]); + } + } + if (buffer.length() != 0) { + list.add(buffer.toString()); + } + + return list.toArray( new String[ list.size() ] ); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/HexDump.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/HexDump.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/HexDump.java 1 Oct 2012 13:03:03 -0000 1.1 @@ -0,0 +1,163 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Dumps data in hexadecimal format. + *

+ * Provides a single function to take an array of bytes and display it + * in hexadecimal form. + *

+ * Origin of code: POI. + * + * @author Scott Sanders + * @author Marc Johnson + * @version $Id: HexDump.java,v 1.1 2012/10/01 13:03:03 marcin Exp $ + */ +public class HexDump { + + /** + * Instances should NOT be constructed in standard programming. + */ + public HexDump() { + super(); + } + + /** + * Dump an array of bytes to an OutputStream. The output is formatted + * for human inspection, with a hexadecimal offset followed by the + * hexadecimal values of the next 16 bytes of data and the printable ASCII + * characters (if any) that those bytes represent printed per each line + * of output. + *

+ * The offset argument specifies the start offset of the data array + * within a larger entity like a file or an incoming stream. For example, + * if the data array contains the third kibibyte of a file, then the + * offset argument should be set to 2048. The offset value printed + * at the beginning of each line indicates where in that larger entity + * the first byte on that line is located. + *

+ * All bytes between the given index (inclusive) and the end of the + * data array are dumped. + * + * @param data the byte array to be dumped + * @param offset offset of the byte array within a larger entity + * @param stream the OutputStream to which the data is to be + * written + * @param index initial index into the byte array + * + * @throws IOException is thrown if anything goes wrong writing + * the data to stream + * @throws ArrayIndexOutOfBoundsException if the index is + * outside the data array's bounds + * @throws IllegalArgumentException if the output stream is null + */ + + public static void dump(byte[] data, long offset, + OutputStream stream, int index) + throws IOException, ArrayIndexOutOfBoundsException, + IllegalArgumentException { + + if ((index < 0) || (index >= data.length)) { + throw new ArrayIndexOutOfBoundsException( + "illegal index: " + index + " into array of length " + + data.length); + } + if (stream == null) { + throw new IllegalArgumentException("cannot write to nullstream"); + } + long display_offset = offset + index; + StringBuilder buffer = new StringBuilder(74); + + for (int j = index; j < data.length; j += 16) { + int chars_read = data.length - j; + + if (chars_read > 16) { + chars_read = 16; + } + dump(buffer, display_offset).append(' '); + for (int k = 0; k < 16; k++) { + if (k < chars_read) { + dump(buffer, data[k + j]); + } else { + buffer.append(" "); + } + buffer.append(' '); + } + for (int k = 0; k < chars_read; k++) { + if ((data[k + j] >= ' ') && (data[k + j] < 127)) { + buffer.append((char) data[k + j]); + } else { + buffer.append('.'); + } + } + buffer.append(EOL); + stream.write(buffer.toString().getBytes()); + stream.flush(); + buffer.setLength(0); + display_offset += chars_read; + } + } + + /** + * The line-separator (initializes to "line.separator" system property. + */ + public static final String EOL = + System.getProperty("line.separator"); + private static final char[] _hexcodes = + { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F' + }; + private static final int[] _shifts = + { + 28, 24, 20, 16, 12, 8, 4, 0 + }; + + /** + * Dump a long value into a StringBuilder. + * + * @param _lbuffer the StringBuilder to dump the value in + * @param value the long value to be dumped + * @return StringBuilder containing the dumped value. + */ + private static StringBuilder dump(StringBuilder _lbuffer, long value) { + for (int j = 0; j < 8; j++) { + _lbuffer + .append(_hexcodes[((int) (value >> _shifts[j])) & 15]); + } + return _lbuffer; + } + + /** + * Dump a byte value into a StringBuilder. + * + * @param _cbuffer the StringBuilder to dump the value in + * @param value the byte value to be dumped + * @return StringBuilder containing the dumped value. + */ + private static StringBuilder dump(StringBuilder _cbuffer, byte value) { + for (int j = 0; j < 2; j++) { + _cbuffer.append(_hexcodes[(value >> _shifts[j + 6]) & 15]); + } + return _cbuffer; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/IOCase.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/IOCase.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/IOCase.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,257 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.Serializable; + +/** + * Enumeration of IO case sensitivity. + *

+ * Different filing systems have different rules for case-sensitivity. + * Windows is case-insensitive, Unix is case-sensitive. + *

+ * This class captures that difference, providing an enumeration to + * control how filename comparisons should be performed. It also provides + * methods that use the enumeration to perform comparisons. + *

+ * Wherever possible, you should use the check methods in this + * class to compare filenames. + * + * @author Stephen Colebourne + * @version $Id: IOCase.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + * @since Commons IO 1.3 + */ +public final class IOCase implements Serializable { + + /** + * The constant for case sensitive regardless of operating system. + */ + public static final IOCase SENSITIVE = new IOCase("Sensitive", true); + + /** + * The constant for case insensitive regardless of operating system. + */ + public static final IOCase INSENSITIVE = new IOCase("Insensitive", false); + + /** + * The constant for case sensitivity determined by the current operating system. + * Windows is case-insensitive when comparing filenames, Unix is case-sensitive. + *

+ * Note: This only caters for Windows and Unix. Other operating + * systems (e.g. OSX and OpenVMS) are treated as case sensitive if they use the + * Unix file separator and case-insensitive if they use the Windows file separator + * (see {@link java.io.File#separatorChar}). + *

+ * If you derialize this constant of Windows, and deserialize on Unix, or vice + * versa, then the value of the case-sensitivity flag will change. + */ + public static final IOCase SYSTEM = new IOCase("System", !FilenameUtils.isSystemWindows()); + + /** Serialization version. */ + private static final long serialVersionUID = -6343169151696340687L; + + /** The enumeration name. */ + private final String name; + + /** The sensitivity flag. */ + private final transient boolean sensitive; + + //----------------------------------------------------------------------- + /** + * Factory method to create an IOCase from a name. + * + * @param name the name to find + * @return the IOCase object + * @throws IllegalArgumentException if the name is invalid + */ + public static IOCase forName(String name) { + if (IOCase.SENSITIVE.name.equals(name)){ + return IOCase.SENSITIVE; + } + if (IOCase.INSENSITIVE.name.equals(name)){ + return IOCase.INSENSITIVE; + } + if (IOCase.SYSTEM.name.equals(name)){ + return IOCase.SYSTEM; + } + throw new IllegalArgumentException("Invalid IOCase name: " + name); + } + + //----------------------------------------------------------------------- + /** + * Private constructor. + * + * @param name the name + * @param sensitive the sensitivity + */ + private IOCase(String name, boolean sensitive) { + this.name = name; + this.sensitive = sensitive; + } + + /** + * Replaces the enumeration from the stream with a real one. + * This ensures that the correct flag is set for SYSTEM. + * + * @return the resolved object + */ + private Object readResolve() { + return forName(name); + } + + //----------------------------------------------------------------------- + /** + * Gets the name of the constant. + * + * @return the name of the constant + */ + public String getName() { + return name; + } + + /** + * Does the object represent case sensitive comparison. + * + * @return true if case sensitive + */ + public boolean isCaseSensitive() { + return sensitive; + } + + //----------------------------------------------------------------------- + /** + * Compares two strings using the case-sensitivity rule. + *

+ * This method mimics {@link String#compareTo} but takes case-sensitivity + * into account. + * + * @param str1 the first string to compare, not null + * @param str2 the second string to compare, not null + * @return true if equal using the case rules + * @throws NullPointerException if either string is null + */ + public int checkCompareTo(String str1, String str2) { + if (str1 == null || str2 == null) { + throw new NullPointerException("The strings must not be null"); + } + return sensitive ? str1.compareTo(str2) : str1.compareToIgnoreCase(str2); + } + + /** + * Compares two strings using the case-sensitivity rule. + *

+ * This method mimics {@link String#equals} but takes case-sensitivity + * into account. + * + * @param str1 the first string to compare, not null + * @param str2 the second string to compare, not null + * @return true if equal using the case rules + * @throws NullPointerException if either string is null + */ + public boolean checkEquals(String str1, String str2) { + if (str1 == null || str2 == null) { + throw new NullPointerException("The strings must not be null"); + } + return sensitive ? str1.equals(str2) : str1.equalsIgnoreCase(str2); + } + + /** + * Checks if one string starts with another using the case-sensitivity rule. + *

+ * This method mimics {@link String#startsWith(String)} but takes case-sensitivity + * into account. + * + * @param str the string to check, not null + * @param start the start to compare against, not null + * @return true if equal using the case rules + * @throws NullPointerException if either string is null + */ + public boolean checkStartsWith(String str, String start) { + return str.regionMatches(!sensitive, 0, start, 0, start.length()); + } + + /** + * Checks if one string ends with another using the case-sensitivity rule. + *

+ * This method mimics {@link String#endsWith} but takes case-sensitivity + * into account. + * + * @param str the string to check, not null + * @param end the end to compare against, not null + * @return true if equal using the case rules + * @throws NullPointerException if either string is null + */ + public boolean checkEndsWith(String str, String end) { + int endLen = end.length(); + return str.regionMatches(!sensitive, str.length() - endLen, end, 0, endLen); + } + + /** + * Checks if one string contains another starting at a specific index using the + * case-sensitivity rule. + *

+ * This method mimics parts of {@link String#indexOf(String, int)} + * but takes case-sensitivity into account. + * + * @param str the string to check, not null + * @param strStartIndex the index to start at in str + * @param search the start to search for, not null + * @return the first index of the search String, + * -1 if no match or null string input + * @throws NullPointerException if either string is null + * @since Commons IO 2.0 + */ + public int checkIndexOf(String str, int strStartIndex, String search) { + int endIndex = str.length() - search.length(); + if (endIndex >= strStartIndex) { + for (int i = strStartIndex; i <= endIndex; i++) { + if (checkRegionMatches(str, i, search)) { + return i; + } + } + } + return -1; + } + + /** + * Checks if one string contains another at a specific index using the case-sensitivity rule. + *

+ * This method mimics parts of {@link String#regionMatches(boolean, int, String, int, int)} + * but takes case-sensitivity into account. + * + * @param str the string to check, not null + * @param strStartIndex the index to start at in str + * @param search the start to search for, not null + * @return true if equal using the case rules + * @throws NullPointerException if either string is null + */ + public boolean checkRegionMatches(String str, int strStartIndex, String search) { + return str.regionMatches(!sensitive, strStartIndex, search, 0, search.length()); + } + + //----------------------------------------------------------------------- + /** + * Gets a string describing the sensitivity. + * + * @return a string describing the sensitivity + */ + @Override + public String toString() { + return name; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/IOExceptionWithCause.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/IOExceptionWithCause.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/IOExceptionWithCause.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io; + +import java.io.IOException; + +/** + * Subclasses IOException with the {@link Throwable} constructors missing before Java 6. If you are using Java 6, + * consider this class deprecated and use {@link IOException}. + * + * @author Apache Commons IO + * @version $Id: IOExceptionWithCause.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + * @since Commons IO 1.4 + */ +public class IOExceptionWithCause extends IOException { + + /** + * Defines the serial version UID. + */ + private static final long serialVersionUID = 1L; + + /** + * Constructs a new instance with the given message and cause. + *

+ * As specified in {@link Throwable}, the message in the given cause is not used in this instance's + * message. + *

+ * + * @param message + * the message (see {@link #getMessage()}) + * @param cause + * the cause (see {@link #getCause()}). A null value is allowed. + */ + public IOExceptionWithCause(String message, Throwable cause) { + super(message); + this.initCause(cause); + } + + /** + * Constructs a new instance with the given cause. + *

+ * The message is set to cause==null ? null : cause.toString(), which by default contains the class + * and message of cause. This constructor is useful for call sites that just wrap another throwable. + *

+ * + * @param cause + * the cause (see {@link #getCause()}). A null value is allowed. + */ + public IOExceptionWithCause(Throwable cause) { + super(cause == null ? null : cause.toString()); + this.initCause(cause); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/IOUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/IOUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/IOUtils.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,1759 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.CharArrayWriter; +import java.io.Closeable; +import java.io.EOFException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.Writer; +import java.net.Socket; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.commons.io.output.StringBuilderWriter; + +/** + * General IO stream manipulation utilities. + *

+ * This class provides static utility methods for input/output operations. + *

    + *
  • closeQuietly - these methods close a stream ignoring nulls and exceptions + *
  • toXxx/read - these methods read data from a stream + *
  • write - these methods write data to a stream + *
  • copy - these methods copy all the data from one stream to another + *
  • contentEquals - these methods compare the content of two streams + *
+ *

+ * The byte-to-char methods and char-to-byte methods involve a conversion step. + * Two methods are provided in each case, one that uses the platform default + * encoding and the other which allows you to specify an encoding. You are + * encouraged to always specify an encoding because relying on the platform + * default can lead to unexpected results, for example when moving from + * development to production. + *

+ * All the methods in this class that read a stream are buffered internally. + * This means that there is no cause to use a BufferedInputStream + * or BufferedReader. The default buffer size of 4K has been shown + * to be efficient in tests. + *

+ * Wherever possible, the methods in this class do not flush or close + * the stream. This is to avoid making non-portable assumptions about the + * streams' origin and further use. Thus the caller is still responsible for + * closing streams after use. + *

+ * Origin of code: Excalibur. + * + * @author Peter Donald + * @author Jeff Turner + * @author Matthew Hawthorne + * @author Stephen Colebourne + * @author Gareth Davis + * @author Ian Springer + * @author Sandy McArthur + * @version $Id: IOUtils.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + */ +public class IOUtils { + // NOTE: This class is focussed on InputStream, OutputStream, Reader and + // Writer. Each method should take at least one of these as a parameter, + // or return one of them. + + /** + * The Unix directory separator character. + */ + public static final char DIR_SEPARATOR_UNIX = '/'; + /** + * The Windows directory separator character. + */ + public static final char DIR_SEPARATOR_WINDOWS = '\\'; + /** + * The system directory separator character. + */ + public static final char DIR_SEPARATOR = File.separatorChar; + /** + * The Unix line separator string. + */ + public static final String LINE_SEPARATOR_UNIX = "\n"; + /** + * The Windows line separator string. + */ + public static final String LINE_SEPARATOR_WINDOWS = "\r\n"; + /** + * The system line separator string. + */ + public static final String LINE_SEPARATOR; + static { + // avoid security issues + StringBuilderWriter buf = new StringBuilderWriter(4); + PrintWriter out = new PrintWriter(buf); + out.println(); + LINE_SEPARATOR = buf.toString(); + out.close(); + } + + /** + * The default buffer size to use for + * {@link #copyLarge(InputStream, OutputStream)} + * and + * {@link #copyLarge(Reader, Writer)} + */ + private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; + + /** + * The default buffer size to use for the skip() methods. + */ + private static final int SKIP_BUFFER_SIZE = 2048; + + // Allocated in the skip method if necessary. + private static char[] SKIP_CHAR_BUFFER; + private static byte[] SKIP_BYTE_BUFFER; + + /** + * Instances should NOT be constructed in standard programming. + */ + public IOUtils() { + super(); + } + + //----------------------------------------------------------------------- + /** + * Unconditionally close an Reader. + *

+ * Equivalent to {@link Reader#close()}, except any exceptions will be ignored. + * This is typically used in finally blocks. + *

+ * Example code: + *

+     *   char[] data = new char[1024];
+     *   Reader in = null;
+     *   try {
+     *       in = new FileReader("foo.txt");
+     *       in.read(data);
+     *       in.close(); //close errors are handled
+     *   } catch (Exception e) {
+     *       // error handling
+     *   } finally {
+     *       IOUtils.closeQuietly(in);
+     *   }
+     * 
+ * + * @param input the Reader to close, may be null or already closed + */ + public static void closeQuietly(Reader input) { + closeQuietly((Closeable)input); + } + + /** + * Unconditionally close a Writer. + *

+ * Equivalent to {@link Writer#close()}, except any exceptions will be ignored. + * This is typically used in finally blocks. + *

+ * Example code: + *

+     *   Writer out = null;
+     *   try {
+     *       out = new StringWriter();
+     *       out.write("Hello World");
+     *       out.close(); //close errors are handled
+     *   } catch (Exception e) {
+     *       // error handling
+     *   } finally {
+     *       IOUtils.closeQuietly(out);
+     *   }
+     * 
+ * + * @param output the Writer to close, may be null or already closed + */ + public static void closeQuietly(Writer output) { + closeQuietly((Closeable)output); + } + + /** + * Unconditionally close an InputStream. + *

+ * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored. + * This is typically used in finally blocks. + *

+ * Example code: + *

+     *   byte[] data = new byte[1024];
+     *   InputStream in = null;
+     *   try {
+     *       in = new FileInputStream("foo.txt");
+     *       in.read(data);
+     *       in.close(); //close errors are handled
+     *   } catch (Exception e) {
+     *       // error handling
+     *   } finally {
+     *       IOUtils.closeQuietly(in);
+     *   }
+     * 
+ * + * @param input the InputStream to close, may be null or already closed + */ + public static void closeQuietly(InputStream input) { + closeQuietly((Closeable)input); + } + + /** + * Unconditionally close an OutputStream. + *

+ * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored. + * This is typically used in finally blocks. + *

+ * Example code: + *

+     * byte[] data = "Hello, World".getBytes();
+     *
+     * OutputStream out = null;
+     * try {
+     *     out = new FileOutputStream("foo.txt");
+     *     out.write(data);
+     *     out.close(); //close errors are handled
+     * } catch (IOException e) {
+     *     // error handling
+     * } finally {
+     *     IOUtils.closeQuietly(out);
+     * }
+     * 
+ * + * @param output the OutputStream to close, may be null or already closed + */ + public static void closeQuietly(OutputStream output) { + closeQuietly((Closeable)output); + } + + /** + * Unconditionally close a Closeable. + *

+ * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. + * This is typically used in finally blocks. + *

+ * Example code: + *

+     *   Closeable closeable = null;
+     *   try {
+     *       closeable = new FileReader("foo.txt");
+     *       // process closeable
+     *       closeable.close();
+     *   } catch (Exception e) {
+     *       // error handling
+     *   } finally {
+     *       IOUtils.closeQuietly(closeable);
+     *   }
+     * 
+ * + * @param closeable the object to close, may be null or already closed + * @since Commons IO 2.0 + */ + public static void closeQuietly(Closeable closeable) { + try { + if (closeable != null) { + closeable.close(); + } + } catch (IOException ioe) { + // ignore + } + } + + /** + * Unconditionally close a Socket. + *

+ * Equivalent to {@link Socket#close()}, except any exceptions will be ignored. + * This is typically used in finally blocks. + *

+ * Example code: + *

+     *   Socket socket = null;
+     *   try {
+     *       socket = new Socket("http://www.foo.com/", 80);
+     *       // process socket
+     *       socket.close();
+     *   } catch (Exception e) {
+     *       // error handling
+     *   } finally {
+     *       IOUtils.closeQuietly(socket);
+     *   }
+     * 
+ * + * @param sock the Socket to close, may be null or already closed + * @since Commons IO 2.0 + */ + public static void closeQuietly(Socket sock){ + if (sock != null){ + try { + sock.close(); + } catch (IOException ioe) { + // ignored + } + } + } + + /** + * Fetches entire contents of an InputStream and represent + * same data as result InputStream. + *

+ * This method is useful where, + *

    + *
  • Source InputStream is slow.
  • + *
  • It has network resources associated, so we cannot keep it open for + * long time.
  • + *
  • It has network timeout associated.
  • + *
+ * It can be used in favor of {@link #toByteArray(InputStream)}, since it + * avoids unnecessary allocation and copy of byte[].
+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + * + * @param input Stream to be fully buffered. + * @return A fully buffered stream. + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + public static InputStream toBufferedInputStream(InputStream input) throws IOException { + return ByteArrayOutputStream.toBufferedInputStream(input); + } + + // read toByteArray + //----------------------------------------------------------------------- + /** + * Get the contents of an InputStream as a byte[]. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + * + * @param input the InputStream to read from + * @return the requested byte array + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + */ + public static byte[] toByteArray(InputStream input) throws IOException { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + copy(input, output); + return output.toByteArray(); + } + + /** + * Get contents of an InputStream as a byte[]. + * Use this method instead of toByteArray(InputStream) + * when InputStream size is known. + * NOTE: the method checks that the length can safely be cast to an int without truncation + * before using {@link IOUtils#toByteArray(java.io.InputStream, int)} to read into the byte array. + * (Arrays can have no more than Integer.MAX_VALUE entries anyway) + * + * @param input the InputStream to read from + * @param size the size of InputStream + * @return the requested byte array + * @throws IOException if an I/O error occurs or InputStream size differ from parameter size + * @throws IllegalArgumentException if size is less than zero or size is greater than Integer.MAX_VALUE + * @see IOUtils#toByteArray(java.io.InputStream, int) + * @since Commons IO 2.1 + */ + public static byte[] toByteArray(InputStream input, long size) throws IOException { + + if(size > Integer.MAX_VALUE) { + throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size); + } + + return toByteArray(input, (int) size); + } + + /** + * Get the contents of an InputStream as a byte[]. + * Use this method instead of toByteArray(InputStream) + * when InputStream size is known + * @param input the InputStream to read from + * @param size the size of InputStream + * @return the requested byte array + * @throws IOException if an I/O error occurs or InputStream size differ from parameter size + * @throws IllegalArgumentException if size is less than zero + * @since Commons IO 2.1 + */ + public static byte[] toByteArray(InputStream input, int size) throws IOException { + + if(size < 0) { + throw new IllegalArgumentException("Size must be equal or greater than zero: " + size); + } + + if(size == 0) { + return new byte[0]; + } + + byte[] data = new byte[size]; + int offset = 0; + int readed; + + while(offset < size && (readed = input.read(data, offset, (size - offset))) != -1) { + offset += readed; + } + + if(offset != size) { + throw new IOException("Unexpected readed size. current: " + offset + ", excepted: " + size); + } + + return data; + } + + /** + * Get the contents of a Reader as a byte[] + * using the default character encoding of the platform. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedReader. + * + * @param input the Reader to read from + * @return the requested byte array + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + */ + public static byte[] toByteArray(Reader input) throws IOException { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + copy(input, output); + return output.toByteArray(); + } + + /** + * Get the contents of a Reader as a byte[] + * using the specified character encoding. + *

+ * Character encoding names can be found at + * IANA. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedReader. + * + * @param input the Reader to read from + * @param encoding the encoding to use, null means platform default + * @return the requested byte array + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static byte[] toByteArray(Reader input, String encoding) + throws IOException { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + copy(input, output, encoding); + return output.toByteArray(); + } + + /** + * Get the contents of a String as a byte[] + * using the default character encoding of the platform. + *

+ * This is the same as {@link String#getBytes()}. + * + * @param input the String to convert + * @return the requested byte array + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs (never occurs) + * @deprecated Use {@link String#getBytes()} + */ + @Deprecated + public static byte[] toByteArray(String input) throws IOException { + return input.getBytes(); + } + + // read char[] + //----------------------------------------------------------------------- + /** + * Get the contents of an InputStream as a character array + * using the default character encoding of the platform. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + * + * @param is the InputStream to read from + * @return the requested character array + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static char[] toCharArray(InputStream is) throws IOException { + CharArrayWriter output = new CharArrayWriter(); + copy(is, output); + return output.toCharArray(); + } + + /** + * Get the contents of an InputStream as a character array + * using the specified character encoding. + *

+ * Character encoding names can be found at + * IANA. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + * + * @param is the InputStream to read from + * @param encoding the encoding to use, null means platform default + * @return the requested character array + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static char[] toCharArray(InputStream is, String encoding) + throws IOException { + CharArrayWriter output = new CharArrayWriter(); + copy(is, output, encoding); + return output.toCharArray(); + } + + /** + * Get the contents of a Reader as a character array. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedReader. + * + * @param input the Reader to read from + * @return the requested character array + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static char[] toCharArray(Reader input) throws IOException { + CharArrayWriter sw = new CharArrayWriter(); + copy(input, sw); + return sw.toCharArray(); + } + + // read toString + //----------------------------------------------------------------------- + /** + * Get the contents of an InputStream as a String + * using the default character encoding of the platform. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + * + * @param input the InputStream to read from + * @return the requested String + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + */ + public static String toString(InputStream input) throws IOException { + return toString(input, null); + } + + /** + * Get the contents of an InputStream as a String + * using the specified character encoding. + *

+ * Character encoding names can be found at + * IANA. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + * + * @param input the InputStream to read from + * @param encoding the encoding to use, null means platform default + * @return the requested String + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + */ + public static String toString(InputStream input, String encoding) + throws IOException { + StringBuilderWriter sw = new StringBuilderWriter(); + copy(input, sw, encoding); + return sw.toString(); + } + + /** + * Get the contents of a Reader as a String. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedReader. + * + * @param input the Reader to read from + * @return the requested String + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + */ + public static String toString(Reader input) throws IOException { + StringBuilderWriter sw = new StringBuilderWriter(); + copy(input, sw); + return sw.toString(); + } + + /** + * Gets the contents at the given URI. + * + * @param uri + * The URI source. + * @return The contents of the URL as a String. + * @throws IOException if an I/O exception occurs. + * @since 2.1. + */ + public static String toString(URI uri) throws IOException { + return toString(uri, null); + } + + /** + * Gets the contents at the given URI. + * + * @param uri + * The URI source. + * @param encoding + * The encoding name for the URL contents. + * @return The contents of the URL as a String. + * @throws IOException if an I/O exception occurs. + * @since 2.1. + */ + public static String toString(URI uri, String encoding) throws IOException { + return toString(uri.toURL(), encoding); + } + + /** + * Gets the contents at the given URL. + * + * @param url + * The URL source. + * @return The contents of the URL as a String. + * @throws IOException if an I/O exception occurs. + * @since 2.1. + */ + public static String toString(URL url) throws IOException { + return toString(url, null); + } + + /** + * Gets the contents at the given URL. + * + * @param url + * The URL source. + * @param encoding + * The encoding name for the URL contents. + * @return The contents of the URL as a String. + * @throws IOException if an I/O exception occurs. + * @since 2.1. + */ + public static String toString(URL url, String encoding) throws IOException { + InputStream inputStream = url.openStream(); + try { + return toString(inputStream, encoding); + } finally { + inputStream.close(); + } + } + + /** + * Get the contents of a byte[] as a String + * using the default character encoding of the platform. + * + * @param input the byte array to read from + * @return the requested String + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs (never occurs) + * @deprecated Use {@link String#String(byte[])} + */ + @Deprecated + public static String toString(byte[] input) throws IOException { + return new String(input); + } + + /** + * Get the contents of a byte[] as a String + * using the specified character encoding. + *

+ * Character encoding names can be found at + * IANA. + * + * @param input the byte array to read from + * @param encoding the encoding to use, null means platform default + * @return the requested String + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs (never occurs) + * @deprecated Use {@link String#String(byte[],String)} + */ + @Deprecated + public static String toString(byte[] input, String encoding) + throws IOException { + if (encoding == null) { + return new String(input); + } else { + return new String(input, encoding); + } + } + + // readLines + //----------------------------------------------------------------------- + /** + * Get the contents of an InputStream as a list of Strings, + * one entry per line, using the default character encoding of the platform. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + * + * @param input the InputStream to read from, not null + * @return the list of Strings, never null + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static List readLines(InputStream input) throws IOException { + InputStreamReader reader = new InputStreamReader(input); + return readLines(reader); + } + + /** + * Get the contents of an InputStream as a list of Strings, + * one entry per line, using the specified character encoding. + *

+ * Character encoding names can be found at + * IANA. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + * + * @param input the InputStream to read from, not null + * @param encoding the encoding to use, null means platform default + * @return the list of Strings, never null + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static List readLines(InputStream input, String encoding) throws IOException { + if (encoding == null) { + return readLines(input); + } else { + InputStreamReader reader = new InputStreamReader(input, encoding); + return readLines(reader); + } + } + + /** + * Get the contents of a Reader as a list of Strings, + * one entry per line. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedReader. + * + * @param input the Reader to read from, not null + * @return the list of Strings, never null + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static List readLines(Reader input) throws IOException { + BufferedReader reader = new BufferedReader(input); + List list = new ArrayList(); + String line = reader.readLine(); + while (line != null) { + list.add(line); + line = reader.readLine(); + } + return list; + } + + // lineIterator + //----------------------------------------------------------------------- + /** + * Return an Iterator for the lines in a Reader. + *

+ * LineIterator holds a reference to the open + * Reader specified here. When you have finished with the + * iterator you should close the reader to free internal resources. + * This can be done by closing the reader directly, or by calling + * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}. + *

+ * The recommended usage pattern is: + *

+     * try {
+     *   LineIterator it = IOUtils.lineIterator(reader);
+     *   while (it.hasNext()) {
+     *     String line = it.nextLine();
+     *     /// do something with line
+     *   }
+     * } finally {
+     *   IOUtils.closeQuietly(reader);
+     * }
+     * 
+ * + * @param reader the Reader to read from, not null + * @return an Iterator of the lines in the reader, never null + * @throws IllegalArgumentException if the reader is null + * @since Commons IO 1.2 + */ + public static LineIterator lineIterator(Reader reader) { + return new LineIterator(reader); + } + + /** + * Return an Iterator for the lines in an InputStream, using + * the character encoding specified (or default encoding if null). + *

+ * LineIterator holds a reference to the open + * InputStream specified here. When you have finished with + * the iterator you should close the stream to free internal resources. + * This can be done by closing the stream directly, or by calling + * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}. + *

+ * The recommended usage pattern is: + *

+     * try {
+     *   LineIterator it = IOUtils.lineIterator(stream, "UTF-8");
+     *   while (it.hasNext()) {
+     *     String line = it.nextLine();
+     *     /// do something with line
+     *   }
+     * } finally {
+     *   IOUtils.closeQuietly(stream);
+     * }
+     * 
+ * + * @param input the InputStream to read from, not null + * @param encoding the encoding to use, null means platform default + * @return an Iterator of the lines in the reader, never null + * @throws IllegalArgumentException if the input is null + * @throws IOException if an I/O error occurs, such as if the encoding is invalid + * @since Commons IO 1.2 + */ + public static LineIterator lineIterator(InputStream input, String encoding) + throws IOException { + Reader reader = null; + if (encoding == null) { + reader = new InputStreamReader(input); + } else { + reader = new InputStreamReader(input, encoding); + } + return new LineIterator(reader); + } + + //----------------------------------------------------------------------- + /** + * Convert the specified CharSequence to an input stream, encoded as bytes + * using the default character encoding of the platform. + * + * @param input the CharSequence to convert + * @return an input stream + * @since Commons IO 2.0 + */ + public static InputStream toInputStream(CharSequence input) { + return toInputStream(input.toString()); + } + + /** + * Convert the specified CharSequence to an input stream, encoded as bytes + * using the specified character encoding. + *

+ * Character encoding names can be found at + * IANA. + * + * @param input the CharSequence to convert + * @param encoding the encoding to use, null means platform default + * @throws IOException if the encoding is invalid + * @return an input stream + * @since Commons IO 2.0 + */ + public static InputStream toInputStream(CharSequence input, String encoding) throws IOException { + return toInputStream(input.toString(), encoding); + } + + //----------------------------------------------------------------------- + /** + * Convert the specified string to an input stream, encoded as bytes + * using the default character encoding of the platform. + * + * @param input the string to convert + * @return an input stream + * @since Commons IO 1.1 + */ + public static InputStream toInputStream(String input) { + byte[] bytes = input.getBytes(); + return new ByteArrayInputStream(bytes); + } + + /** + * Convert the specified string to an input stream, encoded as bytes + * using the specified character encoding. + *

+ * Character encoding names can be found at + * IANA. + * + * @param input the string to convert + * @param encoding the encoding to use, null means platform default + * @throws IOException if the encoding is invalid + * @return an input stream + * @since Commons IO 1.1 + */ + public static InputStream toInputStream(String input, String encoding) throws IOException { + byte[] bytes = encoding != null ? input.getBytes(encoding) : input.getBytes(); + return new ByteArrayInputStream(bytes); + } + + // write byte[] + //----------------------------------------------------------------------- + /** + * Writes bytes from a byte[] to an OutputStream. + * + * @param data the byte array to write, do not modify during output, + * null ignored + * @param output the OutputStream to write to + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void write(byte[] data, OutputStream output) + throws IOException { + if (data != null) { + output.write(data); + } + } + + /** + * Writes bytes from a byte[] to chars on a Writer + * using the default character encoding of the platform. + *

+ * This method uses {@link String#String(byte[])}. + * + * @param data the byte array to write, do not modify during output, + * null ignored + * @param output the Writer to write to + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void write(byte[] data, Writer output) throws IOException { + if (data != null) { + output.write(new String(data)); + } + } + + /** + * Writes bytes from a byte[] to chars on a Writer + * using the specified character encoding. + *

+ * Character encoding names can be found at + * IANA. + *

+ * This method uses {@link String#String(byte[], String)}. + * + * @param data the byte array to write, do not modify during output, + * null ignored + * @param output the Writer to write to + * @param encoding the encoding to use, null means platform default + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void write(byte[] data, Writer output, String encoding) + throws IOException { + if (data != null) { + if (encoding == null) { + write(data, output); + } else { + output.write(new String(data, encoding)); + } + } + } + + // write char[] + //----------------------------------------------------------------------- + /** + * Writes chars from a char[] to a Writer + * using the default character encoding of the platform. + * + * @param data the char array to write, do not modify during output, + * null ignored + * @param output the Writer to write to + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void write(char[] data, Writer output) throws IOException { + if (data != null) { + output.write(data); + } + } + + /** + * Writes chars from a char[] to bytes on an + * OutputStream. + *

+ * This method uses {@link String#String(char[])} and + * {@link String#getBytes()}. + * + * @param data the char array to write, do not modify during output, + * null ignored + * @param output the OutputStream to write to + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void write(char[] data, OutputStream output) + throws IOException { + if (data != null) { + output.write(new String(data).getBytes()); + } + } + + /** + * Writes chars from a char[] to bytes on an + * OutputStream using the specified character encoding. + *

+ * Character encoding names can be found at + * IANA. + *

+ * This method uses {@link String#String(char[])} and + * {@link String#getBytes(String)}. + * + * @param data the char array to write, do not modify during output, + * null ignored + * @param output the OutputStream to write to + * @param encoding the encoding to use, null means platform default + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void write(char[] data, OutputStream output, String encoding) + throws IOException { + if (data != null) { + if (encoding == null) { + write(data, output); + } else { + output.write(new String(data).getBytes(encoding)); + } + } + } + + // write CharSequence + //----------------------------------------------------------------------- + /** + * Writes chars from a CharSequence to a Writer. + * + * @param data the CharSequence to write, null ignored + * @param output the Writer to write to + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + public static void write(CharSequence data, Writer output) throws IOException { + if (data != null) { + write(data.toString(), output); + } + } + + /** + * Writes chars from a CharSequence to bytes on an + * OutputStream using the default character encoding of the + * platform. + *

+ * This method uses {@link String#getBytes()}. + * + * @param data the CharSequence to write, null ignored + * @param output the OutputStream to write to + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + public static void write(CharSequence data, OutputStream output) + throws IOException { + if (data != null) { + write(data.toString(), output); + } + } + + /** + * Writes chars from a CharSequence to bytes on an + * OutputStream using the specified character encoding. + *

+ * Character encoding names can be found at + * IANA. + *

+ * This method uses {@link String#getBytes(String)}. + * + * @param data the CharSequence to write, null ignored + * @param output the OutputStream to write to + * @param encoding the encoding to use, null means platform default + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + public static void write(CharSequence data, OutputStream output, String encoding) + throws IOException { + if (data != null) { + write(data.toString(), output, encoding); + } + } + + // write String + //----------------------------------------------------------------------- + /** + * Writes chars from a String to a Writer. + * + * @param data the String to write, null ignored + * @param output the Writer to write to + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void write(String data, Writer output) throws IOException { + if (data != null) { + output.write(data); + } + } + + /** + * Writes chars from a String to bytes on an + * OutputStream using the default character encoding of the + * platform. + *

+ * This method uses {@link String#getBytes()}. + * + * @param data the String to write, null ignored + * @param output the OutputStream to write to + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void write(String data, OutputStream output) + throws IOException { + if (data != null) { + output.write(data.getBytes()); + } + } + + /** + * Writes chars from a String to bytes on an + * OutputStream using the specified character encoding. + *

+ * Character encoding names can be found at + * IANA. + *

+ * This method uses {@link String#getBytes(String)}. + * + * @param data the String to write, null ignored + * @param output the OutputStream to write to + * @param encoding the encoding to use, null means platform default + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void write(String data, OutputStream output, String encoding) + throws IOException { + if (data != null) { + if (encoding == null) { + write(data, output); + } else { + output.write(data.getBytes(encoding)); + } + } + } + + // write StringBuffer + //----------------------------------------------------------------------- + /** + * Writes chars from a StringBuffer to a Writer. + * + * @param data the StringBuffer to write, null ignored + * @param output the Writer to write to + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + * @deprecated replaced by write(CharSequence, Writer) + */ + @Deprecated + public static void write(StringBuffer data, Writer output) + throws IOException { + if (data != null) { + output.write(data.toString()); + } + } + + /** + * Writes chars from a StringBuffer to bytes on an + * OutputStream using the default character encoding of the + * platform. + *

+ * This method uses {@link String#getBytes()}. + * + * @param data the StringBuffer to write, null ignored + * @param output the OutputStream to write to + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + * @deprecated replaced by write(CharSequence, OutputStream) + */ + @Deprecated + public static void write(StringBuffer data, OutputStream output) + throws IOException { + if (data != null) { + output.write(data.toString().getBytes()); + } + } + + /** + * Writes chars from a StringBuffer to bytes on an + * OutputStream using the specified character encoding. + *

+ * Character encoding names can be found at + * IANA. + *

+ * This method uses {@link String#getBytes(String)}. + * + * @param data the StringBuffer to write, null ignored + * @param output the OutputStream to write to + * @param encoding the encoding to use, null means platform default + * @throws NullPointerException if output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + * @deprecated replaced by write(CharSequence, OutputStream, String) + */ + @Deprecated + public static void write(StringBuffer data, OutputStream output, + String encoding) throws IOException { + if (data != null) { + if (encoding == null) { + write(data, output); + } else { + output.write(data.toString().getBytes(encoding)); + } + } + } + + // writeLines + //----------------------------------------------------------------------- + /** + * Writes the toString() value of each item in a collection to + * an OutputStream line by line, using the default character + * encoding of the platform and the specified line ending. + * + * @param lines the lines to write, null entries produce blank lines + * @param lineEnding the line separator to use, null is system default + * @param output the OutputStream to write to, not null, not closed + * @throws NullPointerException if the output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void writeLines(Collection lines, String lineEnding, + OutputStream output) throws IOException { + if (lines == null) { + return; + } + if (lineEnding == null) { + lineEnding = LINE_SEPARATOR; + } + for (Object line : lines) { + if (line != null) { + output.write(line.toString().getBytes()); + } + output.write(lineEnding.getBytes()); + } + } + + /** + * Writes the toString() value of each item in a collection to + * an OutputStream line by line, using the specified character + * encoding and the specified line ending. + *

+ * Character encoding names can be found at + * IANA. + * + * @param lines the lines to write, null entries produce blank lines + * @param lineEnding the line separator to use, null is system default + * @param output the OutputStream to write to, not null, not closed + * @param encoding the encoding to use, null means platform default + * @throws NullPointerException if the output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void writeLines(Collection lines, String lineEnding, + OutputStream output, String encoding) throws IOException { + if (encoding == null) { + writeLines(lines, lineEnding, output); + } else { + if (lines == null) { + return; + } + if (lineEnding == null) { + lineEnding = LINE_SEPARATOR; + } + for (Object line : lines) { + if (line != null) { + output.write(line.toString().getBytes(encoding)); + } + output.write(lineEnding.getBytes(encoding)); + } + } + } + + /** + * Writes the toString() value of each item in a collection to + * a Writer line by line, using the specified line ending. + * + * @param lines the lines to write, null entries produce blank lines + * @param lineEnding the line separator to use, null is system default + * @param writer the Writer to write to, not null, not closed + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void writeLines(Collection lines, String lineEnding, + Writer writer) throws IOException { + if (lines == null) { + return; + } + if (lineEnding == null) { + lineEnding = LINE_SEPARATOR; + } + for (Object line : lines) { + if (line != null) { + writer.write(line.toString()); + } + writer.write(lineEnding); + } + } + + // copy from InputStream + //----------------------------------------------------------------------- + /** + * Copy bytes from an InputStream to an + * OutputStream. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + *

+ * Large streams (over 2GB) will return a bytes copied value of + * -1 after the copy has completed since the correct + * number of bytes cannot be returned as an int. For large streams + * use the copyLarge(InputStream, OutputStream) method. + * + * @param input the InputStream to read from + * @param output the OutputStream to write to + * @return the number of bytes copied, or -1 if > Integer.MAX_VALUE + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static int copy(InputStream input, OutputStream output) throws IOException { + long count = copyLarge(input, output); + if (count > Integer.MAX_VALUE) { + return -1; + } + return (int) count; + } + + /** + * Copy bytes from a large (over 2GB) InputStream to an + * OutputStream. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + * + * @param input the InputStream to read from + * @param output the OutputStream to write to + * @return the number of bytes copied + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.3 + */ + public static long copyLarge(InputStream input, OutputStream output) + throws IOException { + byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; + long count = 0; + int n = 0; + while (-1 != (n = input.read(buffer))) { + output.write(buffer, 0, n); + count += n; + } + return count; + } + + /** + * Copy bytes from an InputStream to chars on a + * Writer using the default character encoding of the platform. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + *

+ * This method uses {@link InputStreamReader}. + * + * @param input the InputStream to read from + * @param output the Writer to write to + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void copy(InputStream input, Writer output) + throws IOException { + InputStreamReader in = new InputStreamReader(input); + copy(in, output); + } + + /** + * Copy bytes from an InputStream to chars on a + * Writer using the specified character encoding. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + *

+ * Character encoding names can be found at + * IANA. + *

+ * This method uses {@link InputStreamReader}. + * + * @param input the InputStream to read from + * @param output the Writer to write to + * @param encoding the encoding to use, null means platform default + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void copy(InputStream input, Writer output, String encoding) + throws IOException { + if (encoding == null) { + copy(input, output); + } else { + InputStreamReader in = new InputStreamReader(input, encoding); + copy(in, output); + } + } + + // copy from Reader + //----------------------------------------------------------------------- + /** + * Copy chars from a Reader to a Writer. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedReader. + *

+ * Large streams (over 2GB) will return a chars copied value of + * -1 after the copy has completed since the correct + * number of chars cannot be returned as an int. For large streams + * use the copyLarge(Reader, Writer) method. + * + * @param input the Reader to read from + * @param output the Writer to write to + * @return the number of characters copied, or -1 if > Integer.MAX_VALUE + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static int copy(Reader input, Writer output) throws IOException { + long count = copyLarge(input, output); + if (count > Integer.MAX_VALUE) { + return -1; + } + return (int) count; + } + + /** + * Copy chars from a large (over 2GB) Reader to a Writer. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedReader. + * + * @param input the Reader to read from + * @param output the Writer to write to + * @return the number of characters copied + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.3 + */ + public static long copyLarge(Reader input, Writer output) throws IOException { + char[] buffer = new char[DEFAULT_BUFFER_SIZE]; + long count = 0; + int n = 0; + while (-1 != (n = input.read(buffer))) { + output.write(buffer, 0, n); + count += n; + } + return count; + } + + /** + * Copy chars from a Reader to bytes on an + * OutputStream using the default character encoding of the + * platform, and calling flush. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedReader. + *

+ * Due to the implementation of OutputStreamWriter, this method performs a + * flush. + *

+ * This method uses {@link OutputStreamWriter}. + * + * @param input the Reader to read from + * @param output the OutputStream to write to + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void copy(Reader input, OutputStream output) + throws IOException { + OutputStreamWriter out = new OutputStreamWriter(output); + copy(input, out); + // XXX Unless anyone is planning on rewriting OutputStreamWriter, we + // have to flush here. + out.flush(); + } + + /** + * Copy chars from a Reader to bytes on an + * OutputStream using the specified character encoding, and + * calling flush. + *

+ * This method buffers the input internally, so there is no need to use a + * BufferedReader. + *

+ * Character encoding names can be found at + * IANA. + *

+ * Due to the implementation of OutputStreamWriter, this method performs a + * flush. + *

+ * This method uses {@link OutputStreamWriter}. + * + * @param input the Reader to read from + * @param output the OutputStream to write to + * @param encoding the encoding to use, null means platform default + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static void copy(Reader input, OutputStream output, String encoding) + throws IOException { + if (encoding == null) { + copy(input, output); + } else { + OutputStreamWriter out = new OutputStreamWriter(output, encoding); + copy(input, out); + // XXX Unless anyone is planning on rewriting OutputStreamWriter, + // we have to flush here. + out.flush(); + } + } + + // content equals + //----------------------------------------------------------------------- + /** + * Compare the contents of two Streams to determine if they are equal or + * not. + *

+ * This method buffers the input internally using + * BufferedInputStream if they are not already buffered. + * + * @param input1 the first stream + * @param input2 the second stream + * @return true if the content of the streams are equal or they both don't + * exist, false otherwise + * @throws NullPointerException if either input is null + * @throws IOException if an I/O error occurs + */ + public static boolean contentEquals(InputStream input1, InputStream input2) + throws IOException { + if (!(input1 instanceof BufferedInputStream)) { + input1 = new BufferedInputStream(input1); + } + if (!(input2 instanceof BufferedInputStream)) { + input2 = new BufferedInputStream(input2); + } + + int ch = input1.read(); + while (-1 != ch) { + int ch2 = input2.read(); + if (ch != ch2) { + return false; + } + ch = input1.read(); + } + + int ch2 = input2.read(); + return (ch2 == -1); + } + + /** + * Compare the contents of two Readers to determine if they are equal or + * not. + *

+ * This method buffers the input internally using + * BufferedReader if they are not already buffered. + * + * @param input1 the first reader + * @param input2 the second reader + * @return true if the content of the readers are equal or they both don't + * exist, false otherwise + * @throws NullPointerException if either input is null + * @throws IOException if an I/O error occurs + * @since Commons IO 1.1 + */ + public static boolean contentEquals(Reader input1, Reader input2) + throws IOException { + if (!(input1 instanceof BufferedReader)) { + input1 = new BufferedReader(input1); + } + if (!(input2 instanceof BufferedReader)) { + input2 = new BufferedReader(input2); + } + + int ch = input1.read(); + while (-1 != ch) { + int ch2 = input2.read(); + if (ch != ch2) { + return false; + } + ch = input1.read(); + } + + int ch2 = input2.read(); + return (ch2 == -1); + } + + /** + * Skip bytes from an input byte stream. + * This implementation guarantees that it will read as many bytes + * as possible before giving up; this may not always be the case for + * subclasses of {@link Reader}. + * + * @param input byte stream to skip + * @param toSkip number of bytes to skip. + * @return number of bytes actually skipped. + * + * @see InputStream#skip(long) + * + * @throws IOException if there is a problem reading the file + * @throws IllegalArgumentException if toSkip is negative + * @since Commons IO 2.0 + */ + public static long skip(InputStream input, long toSkip) throws IOException { + if (toSkip < 0) { + throw new IllegalArgumentException("Skip count must be non-negative, actual: "+toSkip); + } + /* + * N.B. no need to synchronize this because: + * - we don't care if the buffer is created multiple times (the data is ignored) + * - we always use the same size buffer, so if it it is recreated it will still be OK + * (if the buffer size were variable, we would need to synch. to ensure some other thread + * did not create a smaller one) + */ + if (SKIP_BYTE_BUFFER == null){ + SKIP_BYTE_BUFFER = new byte[SKIP_BUFFER_SIZE]; + } + long remain=toSkip; + while(remain > 0) { + long n = input.read(SKIP_BYTE_BUFFER, 0, (int) Math.min(remain, SKIP_BUFFER_SIZE)); + if (n < 0) { // EOF + break; + } + remain -= n; + } + return toSkip - remain; + } + + /** + * Skip characters from an input character stream. + * This implementation guarantees that it will read as many characters + * as possible before giving up; this may not always be the case for + * subclasses of {@link Reader}. + * + * @param input character stream to skip + * @param toSkip number of characters to skip. + * @return number of characters actually skipped. + * + * @see Reader#skip(long) + * + * @throws IOException if there is a problem reading the file + * @throws IllegalArgumentException if toSkip is negative + * @since Commons IO 2.0 + */ + public static long skip(Reader input, long toSkip) throws IOException { + if (toSkip < 0) { + throw new IllegalArgumentException("Skip count must be non-negative, actual: "+toSkip); + } + /* + * N.B. no need to synchronize this because: + * - we don't care if the buffer is created multiple times (the data is ignored) + * - we always use the same size buffer, so if it it is recreated it will still be OK + * (if the buffer size were variable, we would need to synch. to ensure some other thread + * did not create a smaller one) + */ + if (SKIP_CHAR_BUFFER == null){ + SKIP_CHAR_BUFFER = new char[SKIP_BUFFER_SIZE]; + } + long remain=toSkip; + while(remain > 0) { + long n = input.read(SKIP_CHAR_BUFFER, 0, (int) Math.min(remain, SKIP_BUFFER_SIZE)); + if (n < 0) { // EOF + break; + } + remain -= n; + } + return toSkip - remain; + } + + /** + * Skip the requested number of bytes or fail if there are not enough left. + *

+ * This allows for the possibility that {@link InputStream#skip(long)} may + * not skip as many bytes as requested (most likely because of reaching EOF). + * + * @param input stream to skip + * @param toSkip the number of bytes to skip + * @see InputStream#skip(long) + * + * @throws IOException if there is a problem reading the file + * @throws IllegalArgumentException if toSkip is negative + * @throws EOFException if the number of bytes skipped was incorrect + * @since Commons IO 2.0 + */ + public static void skipFully(InputStream input, long toSkip) throws IOException { + if (toSkip < 0){ + throw new IllegalArgumentException("Bytes to skip must not be negative: "+toSkip); + } + long skipped = skip(input, toSkip); + if (skipped != toSkip) { + throw new EOFException("Bytes to skip: "+toSkip+" actual: "+skipped); + } + } + + /** + * Skip the requested number of characters or fail if there are not enough left. + *

+ * This allows for the possibility that {@link Reader#skip(long)} may + * not skip as many characters as requested (most likely because of reaching EOF). + * + * @param input stream to skip + * @param toSkip the number of characters to skip + * @see Reader#skip(long) + * + * @throws IOException if there is a problem reading the file + * @throws IllegalArgumentException if toSkip is negative + * @throws EOFException if the number of characters skipped was incorrect + * @since Commons IO 2.0 + */ + public static void skipFully(Reader input, long toSkip) throws IOException { + long skipped = skip(input, toSkip); + if (skipped != toSkip) { + throw new EOFException("Bytes to skip: "+toSkip+" actual: "+skipped); + } + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/LineIterator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/LineIterator.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/LineIterator.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * An Iterator over the lines in a Reader. + *

+ * LineIterator holds a reference to an open Reader. + * When you have finished with the iterator you should close the reader + * to free internal resources. This can be done by closing the reader directly, + * or by calling the {@link #close()} or {@link #closeQuietly(LineIterator)} + * method on the iterator. + *

+ * The recommended usage pattern is: + *

+ * LineIterator it = FileUtils.lineIterator(file, "UTF-8");
+ * try {
+ *   while (it.hasNext()) {
+ *     String line = it.nextLine();
+ *     // do something with line
+ *   }
+ * } finally {
+ *   it.close();
+ * }
+ * 
+ * + * @author Stephen Colebourne + * @author Sandy McArthur + * @version $Id: LineIterator.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + * @since Commons IO 1.2 + */ +public class LineIterator implements Iterator { + + // N.B. This class deliberately does not implement Iterable, see https://issues.apache.org/jira/browse/IO-181 + + /** The reader that is being read. */ + private final BufferedReader bufferedReader; + /** The current line. */ + private String cachedLine; + /** A flag indicating if the iterator has been fully read. */ + private boolean finished = false; + + /** + * Constructs an iterator of the lines for a Reader. + * + * @param reader the Reader to read from, not null + * @throws IllegalArgumentException if the reader is null + */ + public LineIterator(final Reader reader) throws IllegalArgumentException { + if (reader == null) { + throw new IllegalArgumentException("Reader must not be null"); + } + if (reader instanceof BufferedReader) { + bufferedReader = (BufferedReader) reader; + } else { + bufferedReader = new BufferedReader(reader); + } + } + + //----------------------------------------------------------------------- + /** + * Indicates whether the Reader has more lines. + * If there is an IOException then {@link #close()} will + * be called on this instance. + * + * @return true if the Reader has more lines + * @throws IllegalStateException if an IO exception occurs + */ + public boolean hasNext() { + if (cachedLine != null) { + return true; + } else if (finished) { + return false; + } else { + try { + while (true) { + String line = bufferedReader.readLine(); + if (line == null) { + finished = true; + return false; + } else if (isValidLine(line)) { + cachedLine = line; + return true; + } + } + } catch(IOException ioe) { + close(); + throw new IllegalStateException(ioe); + } + } + } + + /** + * Overridable method to validate each line that is returned. + * + * @param line the line that is to be validated + * @return true if valid, false to remove from the iterator + */ + protected boolean isValidLine(String line) { + return true; + } + + /** + * Returns the next line in the wrapped Reader. + * + * @return the next line from the input + * @throws NoSuchElementException if there is no line to return + */ + public String next() { + return nextLine(); + } + + /** + * Returns the next line in the wrapped Reader. + * + * @return the next line from the input + * @throws NoSuchElementException if there is no line to return + */ + public String nextLine() { + if (!hasNext()) { + throw new NoSuchElementException("No more lines"); + } + String currentLine = cachedLine; + cachedLine = null; + return currentLine; + } + + /** + * Closes the underlying Reader quietly. + * This method is useful if you only want to process the first few + * lines of a larger file. If you do not close the iterator + * then the Reader remains open. + * This method can safely be called multiple times. + */ + public void close() { + finished = true; + IOUtils.closeQuietly(bufferedReader); + cachedLine = null; + } + + /** + * Unsupported. + * + * @throws UnsupportedOperationException always + */ + public void remove() { + throw new UnsupportedOperationException("Remove unsupported on LineIterator"); + } + + //----------------------------------------------------------------------- + /** + * Closes the iterator, handling null and ignoring exceptions. + * + * @param iterator the iterator to close + */ + public static void closeQuietly(LineIterator iterator) { + if (iterator != null) { + iterator.close(); + } + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/TaggedIOException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/TaggedIOException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/TaggedIOException.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import java.io.IOException; +import java.io.Serializable; + +/** + * An {@link IOException} decorator that adds a serializable tag to the + * wrapped exception. Both the tag and the original exception can be used + * to determine further processing when this exception is caught. + * + * @since Commons IO 2.0 + */ +public class TaggedIOException extends IOExceptionWithCause { + + /** + * Generated serial version UID. + */ + private static final long serialVersionUID = -6994123481142850163L; + + /** + * Checks whether the given throwable is tagged with the given tag. + *

+ * This check can only succeed if the throwable is a + * {@link TaggedIOException} and the tag is {@link Serializable}, but + * the argument types are intentionally more generic to make it easier + * to use this method without type casts. + *

+ * A typical use for this method is in a catch block to + * determine how a caught exception should be handled: + *

+     * Serializable tag = ...;
+     * try {
+     *     ...;
+     * } catch (Throwable t) {
+     *     if (TaggedIOExcepton.isTaggedWith(t, tag)) {
+     *         // special processing for tagged exception
+     *     } else {
+     *         // handling of other kinds of exceptions
+     *     }
+     * }
+     * 
+ * + * @param throwable The Throwable object to check + * @param tag tag object + * @return true if the throwable has the specified tag, + * otherwise false + */ + public static boolean isTaggedWith(Throwable throwable, Object tag) { + return tag != null + && throwable instanceof TaggedIOException + && tag.equals(((TaggedIOException) throwable).tag); + } + + /** + * Throws the original {@link IOException} if the given throwable is + * a {@link TaggedIOException} decorator the given tag. Does nothing + * if the given throwable is of a different type or if it is tagged + * with some other tag. + *

+ * This method is typically used in a catch block to + * selectively rethrow tagged exceptions. + *

+     * Serializable tag = ...;
+     * try {
+     *     ...;
+     * } catch (Throwable t) {
+     *     TaggedIOExcepton.throwCauseIfTagged(t, tag);
+     *     // handle other kinds of exceptions
+     * }
+     * 
+ * + * @param throwable an exception + * @param tag tag object + * @throws IOException original exception from the tagged decorator, if any + */ + public static void throwCauseIfTaggedWith(Throwable throwable, Object tag) + throws IOException { + if (isTaggedWith(throwable, tag)) { + throw ((TaggedIOException) throwable).getCause(); + } + } + + /** + * The tag of this exception. + */ + private final Serializable tag; + + /** + * Creates a tagged wrapper for the given exception. + * + * @param original the exception to be tagged + * @param tag tag of this exception + */ + public TaggedIOException(IOException original, Serializable tag) { + super(original.getMessage(), original); + this.tag = tag; + } + + /** + * Returns the serializable tag object. + * + * @return tag object + */ + public Serializable getTag() { + return tag; + } + + /** + * Returns the wrapped exception. The only difference to the overridden + * {@link Throwable#getCause()} method is the narrower return type. + * + * @return wrapped exception + */ + @Override + public IOException getCause() { + return (IOException) super.getCause(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/ThreadMonitor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/ThreadMonitor.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/ThreadMonitor.java 1 Oct 2012 13:03:03 -0000 1.1 @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +/** + * Monitors a thread, interrupting it of it reaches the specified timout. + *

+ * This works by sleeping until the specified timout amount and then + * interrupting the thread being monitored. If the thread being monitored + * completes its work before being interrupted, it should interrupt() + * the monitor thread. + *

+ * + *

+ *       long timeoutInMillis = 1000;
+ *       try {
+ *           Thread monitor = ThreadMonitor.start(timeoutInMillis);
+ *           // do some work here
+ *           ThreadMonitor.stop(monitor);
+ *       } catch (InterruptedException e) {
+ *           // timed amount was reached
+ *       }
+ * 
+ * + * @version $Id: ThreadMonitor.java,v 1.1 2012/10/01 13:03:03 marcin Exp $ + */ +class ThreadMonitor implements Runnable { + + private final Thread thread; + private final long timeout; + + /** + * Start monitoring the current thread. + * + * @param timeout The timout amount in milliseconds + * or no timeout if the value is zero or less + * @return The monitor thread or null + * if the timout amount is not greater than zero + */ + public static Thread start(long timeout) { + return start(Thread.currentThread(), timeout); + } + + /** + * Start monitoring the specified thread. + * + * @param thread The thread The thread to monitor + * @param timeout The timout amount in milliseconds + * or no timeout if the value is zero or less + * @return The monitor thread or null + * if the timout amount is not greater than zero + */ + public static Thread start(Thread thread, long timeout) { + Thread monitor = null; + if (timeout > 0) { + ThreadMonitor timout = new ThreadMonitor(thread, timeout); + monitor = new Thread(timout, ThreadMonitor.class.getSimpleName()); + monitor.setDaemon(true); + monitor.start(); + } + return monitor; + } + + /** + * Stop monitoring the specified thread. + * + * @param thread The monitor thread, may be null + */ + public static void stop(Thread thread) { + if (thread != null) { + thread.interrupt(); + } + } + + /** + * Construct and new monitor. + * + * @param thread The thread to monitor + * @param timeout The timout amount in milliseconds + */ + private ThreadMonitor(Thread thread, long timeout) { + this.thread = thread; + this.timeout = timeout; + } + + /** + * Sleep until the specified timout amount and then + * interrupt the thread being monitored. + * + * @see Runnable#run() + */ + public void run() { + try { + Thread.sleep(timeout); + thread.interrupt(); + } catch (InterruptedException e) { + // timeout not reached + } + } +} \ No newline at end of file Index: 3rdParty_sources/commons-io/org/apache/commons/io/overview.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/overview.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/overview.html 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,32 @@ + + + + +

+The commons-io component contains utility classes, +filters, streams, readers and writers. +

+

+These classes aim to add to the standard JDK IO classes. +The utilities provide convenience wrappers around the JDK, simplifying +various operations into pre-tested units of code. +The filters and streams provide useful implementations that perhaps should +be in the JDK itself. +

+ + Index: 3rdParty_sources/commons-io/org/apache/commons/io/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/package.html 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,47 @@ + + + + +

+This package defines utility classes for working with streams, readers, +writers and files. The most commonly used classes are described here: +

+

+IOUtils is the most frequently used class. +It provides operations to read, write, copy and close streams. +

+

+FileUtils provides operations based around the JDK File class. +These include reading, writing, copying, comparing and deleting. +

+

+FilenameUtils provides utilities based on filenames. +This utility class manipulates filenames without using File objects. +It aims to simplify the transition between Windows and Unix. +Before using this class however, you should consider whether you should +be using File objects. +

+

+FileSystemUtils allows access to the filing system in ways the JDK +does not support. At present this allows you to get the free space on a drive. +

+

+EndianUtils swaps data between Big-Endian and Little-Endian formats. +

+ + Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/AbstractFileComparator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/comparator/AbstractFileComparator.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/AbstractFileComparator.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.comparator; + +import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * Abstract file {@link Comparator} which provides sorting for file arrays and lists. + * + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:02:59 $ + * @since Commons IO 2.0 + */ +abstract class AbstractFileComparator implements Comparator { + + /** + * Sort an array of files. + *

+ * This method uses {@link Arrays#sort(Object[], Comparator)} + * and returns the original array. + * + * @param files The files to sort, may be null + * @return The sorted array + * @since Commons IO 2.0 + */ + public File[] sort(File... files) { + if (files != null) { + Arrays.sort(files, this); + } + return files; + } + + /** + * Sort a List of files. + *

+ * This method uses {@link Collections#sort(List, Comparator)} + * and returns the original list. + * + * @param files The files to sort, may be null + * @return The sorted list + * @since Commons IO 2.0 + */ + public List sort(List files) { + if (files != null) { + Collections.sort(files, this); + } + return files; + } + + /** + * String representation of this file comparator. + * + * @return String representation of this file comparator + */ + @Override + public String toString() { + return getClass().getSimpleName(); + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/CompositeFileComparator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/comparator/CompositeFileComparator.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/CompositeFileComparator.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.comparator; + +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +/** + * Compare two files using a set of delegate file {@link Comparator}. + *

+ * This comparator can be used to sort lists or arrays of files + * by combining a number other comparators. + *

+ * Example of sorting a list of files by type (i.e. directory or file) + * and then by name: + *

+ *       CompositeFileComparator comparator =
+ *                       new CompositeFileComparator(
+ *                                   DirectoryFileComparator.DIRECTORY_COMPARATOR,
+ *                                   NameFileComparator.NAME_COMPARATOR);
+ *       List<File> list = ...
+ *       comparator.sort(list);
+ * 
+ * + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:02:59 $ + * @since Commons IO 2.0 + */ +public class CompositeFileComparator extends AbstractFileComparator implements Serializable { + + private static final Comparator[] NO_COMPARATORS = {}; + private final Comparator[] delegates; + + /** + * Create a composite comparator for the set of delegate comparators. + * + * @param delegates The delegate file comparators + */ + @SuppressWarnings("unchecked") // casts 1 & 2 must be OK because types are already correct + public CompositeFileComparator(Comparator... delegates) { + if (delegates == null) { + this.delegates = (Comparator[]) NO_COMPARATORS;//1 + } else { + this.delegates = (Comparator[]) new Comparator[delegates.length];//2 + System.arraycopy(delegates, 0, this.delegates, 0, delegates.length); + } + } + + /** + * Create a composite comparator for the set of delegate comparators. + * + * @param delegates The delegate file comparators + */ + @SuppressWarnings("unchecked") // casts 1 & 2 must be OK because types are already correct + public CompositeFileComparator(Iterable> delegates) { + if (delegates == null) { + this.delegates = (Comparator[]) NO_COMPARATORS; //1 + } else { + List> list = new ArrayList>(); + for (Comparator comparator : delegates) { + list.add(comparator); + } + this.delegates = (Comparator[]) list.toArray(new Comparator[list.size()]); //2 + } + } + + /** + * Compare the two files using delegate comparators. + * + * @param file1 The first file to compare + * @param file2 The second file to compare + * @return the first non-zero result returned from + * the delegate comparators or zero. + */ + public int compare(File file1, File file2) { + int result = 0; + for (Comparator delegate : delegates) { + result = delegate.compare(file1, file2); + if (result != 0) { + break; + } + } + return result; + } + + /** + * String representation of this file comparator. + * + * @return String representation of this file comparator + */ + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(super.toString()); + builder.append('{'); + for (int i = 0; i < delegates.length; i++) { + if (i > 0) { + builder.append(','); + } + builder.append(delegates[i]); + } + builder.append('}'); + return builder.toString(); + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/DefaultFileComparator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/comparator/DefaultFileComparator.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/DefaultFileComparator.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.comparator; + +import java.io.File; +import java.io.Serializable; +import java.util.Comparator; + +/** + * Compare two files using the default {@link File#compareTo(File)} method. + *

+ * This comparator can be used to sort lists or arrays of files + * by using the default file comparison. + *

+ * Example of sorting a list of files using the + * {@link #DEFAULT_COMPARATOR} singleton instance: + *

+ *       List<File> list = ...
+ *       DefaultFileComparator.DEFAULT_COMPARATOR.sort(list);
+ * 
+ *

+ * Example of doing a reverse sort of an array of files using the + * {@link #DEFAULT_REVERSE} singleton instance: + *

+ *       File[] array = ...
+ *       DefaultFileComparator.DEFAULT_REVERSE.sort(array);
+ * 
+ *

+ * + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:02:59 $ + * @since Commons IO 1.4 + */ +public class DefaultFileComparator extends AbstractFileComparator implements Serializable { + + /** Singleton default comparator instance */ + public static final Comparator DEFAULT_COMPARATOR = new DefaultFileComparator(); + + /** Singleton reverse default comparator instance */ + public static final Comparator DEFAULT_REVERSE = new ReverseComparator(DEFAULT_COMPARATOR); + + /** + * Compare the two files using the {@link File#compareTo(File)} method. + * + * @param file1 The first file to compare + * @param file2 The second file to compare + * @return the result of calling file1's + * {@link File#compareTo(File)} with file2 as the parameter. + */ + public int compare(File file1, File file2) { + return file1.compareTo(file2); + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/DirectoryFileComparator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/comparator/DirectoryFileComparator.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/DirectoryFileComparator.java 1 Oct 2012 13:02:58 -0000 1.1 @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.comparator; + +import java.io.File; +import java.io.Serializable; +import java.util.Comparator; + +/** + * Compare two files using the {@link File#isDirectory()} method. + *

+ * This comparator can be used to sort lists or arrays by directories and files. + *

+ * Example of sorting a list of files/directories using the + * {@link #DIRECTORY_COMPARATOR} singleton instance: + *

+ *       List<File> list = ...
+ *       DirectoryFileComparator.DIRECTORY_COMPARATOR.sort(list);
+ * 
+ *

+ * Example of doing a reverse sort of an array of files/directories using the + * {@link #DIRECTORY_REVERSE} singleton instance: + *

+ *       File[] array = ...
+ *       DirectoryFileComparator.DIRECTORY_REVERSE.sort(array);
+ * 
+ *

+ * + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:02:58 $ + * @since Commons IO 2.0 + */ +public class DirectoryFileComparator extends AbstractFileComparator implements Serializable { + + /** Singleton default comparator instance */ + public static final Comparator DIRECTORY_COMPARATOR = new DirectoryFileComparator(); + + /** Singleton reverse default comparator instance */ + public static final Comparator DIRECTORY_REVERSE = new ReverseComparator(DIRECTORY_COMPARATOR); + + /** + * Compare the two files using the {@link File#isDirectory()} method. + * + * @param file1 The first file to compare + * @param file2 The second file to compare + * @return the result of calling file1's + * {@link File#compareTo(File)} with file2 as the parameter. + */ + public int compare(File file1, File file2) { + return (getType(file1) - getType(file2)); + } + + /** + * Convert type to numeric value. + * + * @param file The file + * @return 1 for directories and 2 for files + */ + private int getType(File file) { + if (file.isDirectory()) { + return 1; + } else { + return 2; + } + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/ExtensionFileComparator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/comparator/ExtensionFileComparator.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/ExtensionFileComparator.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.comparator; + +import java.io.File; +import java.io.Serializable; +import java.util.Comparator; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOCase; + +/** + * Compare the file name extensions for order + * (see {@link FilenameUtils#getExtension(String)}). + *

+ * This comparator can be used to sort lists or arrays of files + * by their file extension either in a case-sensitive, case-insensitive or + * system dependant case sensitive way. A number of singleton instances + * are provided for the various case sensitivity options (using {@link IOCase}) + * and the reverse of those options. + *

+ * Example of a case-sensitive file extension sort using the + * {@link #EXTENSION_COMPARATOR} singleton instance: + *

+ *       List<File> list = ...
+ *       ExtensionFileComparator.EXTENSION_COMPARATOR.sort(list);
+ * 
+ *

+ * Example of a reverse case-insensitive file extension sort using the + * {@link #EXTENSION_INSENSITIVE_REVERSE} singleton instance: + *

+ *       File[] array = ...
+ *       ExtensionFileComparator.EXTENSION_INSENSITIVE_REVERSE.sort(array);
+ * 
+ *

+ * + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:02:59 $ + * @since Commons IO 1.4 + */ +public class ExtensionFileComparator extends AbstractFileComparator implements Serializable { + + /** Case-sensitive extension comparator instance (see {@link IOCase#SENSITIVE}) */ + public static final Comparator EXTENSION_COMPARATOR = new ExtensionFileComparator(); + + /** Reverse case-sensitive extension comparator instance (see {@link IOCase#SENSITIVE}) */ + public static final Comparator EXTENSION_REVERSE = new ReverseComparator(EXTENSION_COMPARATOR); + + /** Case-insensitive extension comparator instance (see {@link IOCase#INSENSITIVE}) */ + public static final Comparator EXTENSION_INSENSITIVE_COMPARATOR + = new ExtensionFileComparator(IOCase.INSENSITIVE); + + /** Reverse case-insensitive extension comparator instance (see {@link IOCase#INSENSITIVE}) */ + public static final Comparator EXTENSION_INSENSITIVE_REVERSE + = new ReverseComparator(EXTENSION_INSENSITIVE_COMPARATOR); + + /** System sensitive extension comparator instance (see {@link IOCase#SYSTEM}) */ + public static final Comparator EXTENSION_SYSTEM_COMPARATOR = new ExtensionFileComparator(IOCase.SYSTEM); + + /** Reverse system sensitive path comparator instance (see {@link IOCase#SYSTEM}) */ + public static final Comparator EXTENSION_SYSTEM_REVERSE = new ReverseComparator(EXTENSION_SYSTEM_COMPARATOR); + + /** Whether the comparison is case sensitive. */ + private final IOCase caseSensitivity; + + /** + * Construct a case sensitive file extension comparator instance. + */ + public ExtensionFileComparator() { + this.caseSensitivity = IOCase.SENSITIVE; + } + + /** + * Construct a file extension comparator instance with the specified case-sensitivity. + * + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + */ + public ExtensionFileComparator(IOCase caseSensitivity) { + this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity; + } + + /** + * Compare the extensions of two files the specified case sensitivity. + * + * @param file1 The first file to compare + * @param file2 The second file to compare + * @return a negative value if the first file's extension + * is less than the second, zero if the extensions are the + * same and a positive value if the first files extension + * is greater than the second file. + * + */ + public int compare(File file1, File file2) { + String suffix1 = FilenameUtils.getExtension(file1.getName()); + String suffix2 = FilenameUtils.getExtension(file2.getName()); + return caseSensitivity.checkCompareTo(suffix1, suffix2); + } + + /** + * String representation of this file comparator. + * + * @return String representation of this file comparator + */ + @Override + public String toString() { + return super.toString() + "[caseSensitivity=" + caseSensitivity + "]"; + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/LastModifiedFileComparator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/comparator/LastModifiedFileComparator.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/LastModifiedFileComparator.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.comparator; + +import java.io.File; +import java.io.Serializable; +import java.util.Comparator; + +/** + * Compare the last modified date/time of two files for order + * (see {@link File#lastModified()}). + *

+ * This comparator can be used to sort lists or arrays of files + * by their last modified date/time. + *

+ * Example of sorting a list of files using the + * {@link #LASTMODIFIED_COMPARATOR} singleton instance: + *

+ *       List<File> list = ...
+ *       LastModifiedFileComparator.LASTMODIFIED_COMPARATOR.sort(list);
+ * 
+ *

+ * Example of doing a reverse sort of an array of files using the + * {@link #LASTMODIFIED_REVERSE} singleton instance: + *

+ *       File[] array = ...
+ *       LastModifiedFileComparator.LASTMODIFIED_REVERSE.sort(array);
+ * 
+ *

+ * + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:02:59 $ + * @since Commons IO 1.4 + */ +public class LastModifiedFileComparator extends AbstractFileComparator implements Serializable { + + /** Last modified comparator instance */ + public static final Comparator LASTMODIFIED_COMPARATOR = new LastModifiedFileComparator(); + + /** Reverse last modified comparator instance */ + public static final Comparator LASTMODIFIED_REVERSE = new ReverseComparator(LASTMODIFIED_COMPARATOR); + + /** + * Compare the last the last modified date/time of two files. + * + * @param file1 The first file to compare + * @param file2 The second file to compare + * @return a negative value if the first file's lastmodified date/time + * is less than the second, zero if the lastmodified date/time are the + * same and a positive value if the first files lastmodified date/time + * is greater than the second file. + * + */ + public int compare(File file1, File file2) { + long result = file1.lastModified() - file2.lastModified(); + if (result < 0) { + return -1; + } else if (result > 0) { + return 1; + } else { + return 0; + } + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/NameFileComparator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/comparator/NameFileComparator.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/NameFileComparator.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.comparator; + +import java.io.File; +import java.io.Serializable; +import java.util.Comparator; + +import org.apache.commons.io.IOCase; + +/** + * Compare the names of two files for order (see {@link File#getName()}). + *

+ * This comparator can be used to sort lists or arrays of files + * by their name either in a case-sensitive, case-insensitive or + * system dependant case sensitive way. A number of singleton instances + * are provided for the various case sensitivity options (using {@link IOCase}) + * and the reverse of those options. + *

+ * Example of a case-sensitive file name sort using the + * {@link #NAME_COMPARATOR} singleton instance: + *

+ *       List<File> list = ...
+ *       NameFileComparator.NAME_COMPARATOR.sort(list);
+ * 
+ *

+ * Example of a reverse case-insensitive file name sort using the + * {@link #NAME_INSENSITIVE_REVERSE} singleton instance: + *

+ *       File[] array = ...
+ *       NameFileComparator.NAME_INSENSITIVE_REVERSE.sort(array);
+ * 
+ *

+ * + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:02:59 $ + * @since Commons IO 1.4 + */ +public class NameFileComparator extends AbstractFileComparator implements Serializable { + + /** Case-sensitive name comparator instance (see {@link IOCase#SENSITIVE}) */ + public static final Comparator NAME_COMPARATOR = new NameFileComparator(); + + /** Reverse case-sensitive name comparator instance (see {@link IOCase#SENSITIVE}) */ + public static final Comparator NAME_REVERSE = new ReverseComparator(NAME_COMPARATOR); + + /** Case-insensitive name comparator instance (see {@link IOCase#INSENSITIVE}) */ + public static final Comparator NAME_INSENSITIVE_COMPARATOR = new NameFileComparator(IOCase.INSENSITIVE); + + /** Reverse case-insensitive name comparator instance (see {@link IOCase#INSENSITIVE}) */ + public static final Comparator NAME_INSENSITIVE_REVERSE = new ReverseComparator(NAME_INSENSITIVE_COMPARATOR); + + /** System sensitive name comparator instance (see {@link IOCase#SYSTEM}) */ + public static final Comparator NAME_SYSTEM_COMPARATOR = new NameFileComparator(IOCase.SYSTEM); + + /** Reverse system sensitive name comparator instance (see {@link IOCase#SYSTEM}) */ + public static final Comparator NAME_SYSTEM_REVERSE = new ReverseComparator(NAME_SYSTEM_COMPARATOR); + + /** Whether the comparison is case sensitive. */ + private final IOCase caseSensitivity; + + /** + * Construct a case sensitive file name comparator instance. + */ + public NameFileComparator() { + this.caseSensitivity = IOCase.SENSITIVE; + } + + /** + * Construct a file name comparator instance with the specified case-sensitivity. + * + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + */ + public NameFileComparator(IOCase caseSensitivity) { + this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity; + } + + /** + * Compare the names of two files with the specified case sensitivity. + * + * @param file1 The first file to compare + * @param file2 The second file to compare + * @return a negative value if the first file's name + * is less than the second, zero if the names are the + * same and a positive value if the first files name + * is greater than the second file. + */ + public int compare(File file1, File file2) { + return caseSensitivity.checkCompareTo(file1.getName(), file2.getName()); + } + + /** + * String representation of this file comparator. + * + * @return String representation of this file comparator + */ + @Override + public String toString() { + return super.toString() + "[caseSensitivity=" + caseSensitivity + "]"; + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/PathFileComparator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/comparator/PathFileComparator.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/PathFileComparator.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.comparator; + +import java.io.File; +import java.io.Serializable; +import java.util.Comparator; + +import org.apache.commons.io.IOCase; + +/** + * Compare the path of two files for order (see {@link File#getPath()}). + *

+ * This comparator can be used to sort lists or arrays of files + * by their path either in a case-sensitive, case-insensitive or + * system dependant case sensitive way. A number of singleton instances + * are provided for the various case sensitivity options (using {@link IOCase}) + * and the reverse of those options. + *

+ * Example of a case-sensitive file path sort using the + * {@link #PATH_COMPARATOR} singleton instance: + *

+ *       List<File> list = ...
+ *       PathFileComparator.PATH_COMPARATOR.sort(list);
+ * 
+ *

+ * Example of a reverse case-insensitive file path sort using the + * {@link #PATH_INSENSITIVE_REVERSE} singleton instance: + *

+ *       File[] array = ...
+ *       PathFileComparator.PATH_INSENSITIVE_REVERSE.sort(array);
+ * 
+ *

+ * + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:02:59 $ + * @since Commons IO 1.4 + */ +public class PathFileComparator extends AbstractFileComparator implements Serializable { + + /** Case-sensitive path comparator instance (see {@link IOCase#SENSITIVE}) */ + public static final Comparator PATH_COMPARATOR = new PathFileComparator(); + + /** Reverse case-sensitive path comparator instance (see {@link IOCase#SENSITIVE}) */ + public static final Comparator PATH_REVERSE = new ReverseComparator(PATH_COMPARATOR); + + /** Case-insensitive path comparator instance (see {@link IOCase#INSENSITIVE}) */ + public static final Comparator PATH_INSENSITIVE_COMPARATOR = new PathFileComparator(IOCase.INSENSITIVE); + + /** Reverse case-insensitive path comparator instance (see {@link IOCase#INSENSITIVE}) */ + public static final Comparator PATH_INSENSITIVE_REVERSE = new ReverseComparator(PATH_INSENSITIVE_COMPARATOR); + + /** System sensitive path comparator instance (see {@link IOCase#SYSTEM}) */ + public static final Comparator PATH_SYSTEM_COMPARATOR = new PathFileComparator(IOCase.SYSTEM); + + /** Reverse system sensitive path comparator instance (see {@link IOCase#SYSTEM}) */ + public static final Comparator PATH_SYSTEM_REVERSE = new ReverseComparator(PATH_SYSTEM_COMPARATOR); + + /** Whether the comparison is case sensitive. */ + private final IOCase caseSensitivity; + + /** + * Construct a case sensitive file path comparator instance. + */ + public PathFileComparator() { + this.caseSensitivity = IOCase.SENSITIVE; + } + + /** + * Construct a file path comparator instance with the specified case-sensitivity. + * + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + */ + public PathFileComparator(IOCase caseSensitivity) { + this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity; + } + + /** + * Compare the paths of two files the specified case sensitivity. + * + * @param file1 The first file to compare + * @param file2 The second file to compare + * @return a negative value if the first file's path + * is less than the second, zero if the paths are the + * same and a positive value if the first files path + * is greater than the second file. + * + */ + public int compare(File file1, File file2) { + return caseSensitivity.checkCompareTo(file1.getPath(), file2.getPath()); + } + + /** + * String representation of this file comparator. + * + * @return String representation of this file comparator + */ + @Override + public String toString() { + return super.toString() + "[caseSensitivity=" + caseSensitivity + "]"; + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/ReverseComparator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/comparator/ReverseComparator.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/ReverseComparator.java 1 Oct 2012 13:02:58 -0000 1.1 @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.comparator; + +import java.io.File; +import java.io.Serializable; +import java.util.Comparator; + +/** + * Reverses the result of comparing two objects using + * the delegate {@link Comparator}. + * + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:02:58 $ + * @since Commons IO 1.4 + */ +class ReverseComparator extends AbstractFileComparator implements Serializable { + + private final Comparator delegate; + + /** + * Construct an instance with the sepecified delegate {@link Comparator}. + * + * @param delegate The comparator to delegate to + */ + public ReverseComparator(Comparator delegate) { + if (delegate == null) { + throw new IllegalArgumentException("Delegate comparator is missing"); + } + this.delegate = delegate; + } + + /** + * Compare using the delegate Comparator, but reversing the result. + * + * @param file1 The first file to compare + * @param file2 The second file to compare + * @return the result from the delegate {@link Comparator#compare(Object, Object)} + * reversing the value (i.e. positive becomes negative and vice versa) + */ + public int compare(File file1, File file2) { + return delegate.compare(file2, file1); // parameters switched round + } + + /** + * String representation of this file comparator. + * + * @return String representation of this file comparator + */ + @Override + public String toString() { + return super.toString() + "[" + delegate.toString() + "]"; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/SizeFileComparator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/comparator/SizeFileComparator.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/SizeFileComparator.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.comparator; + +import java.io.File; +import java.io.Serializable; +import java.util.Comparator; + +import org.apache.commons.io.FileUtils; + +/** + * Compare the length/size of two files for order (see + * {@link File#length()} and {@link FileUtils#sizeOfDirectory(File)}). + *

+ * This comparator can be used to sort lists or arrays of files + * by their length/size. + *

+ * Example of sorting a list of files using the + * {@link #SIZE_COMPARATOR} singleton instance: + *

+ *       List<File> list = ...
+ *       SizeFileComparator.SIZE_COMPARATOR.sort(list);
+ * 
+ *

+ * Example of doing a reverse sort of an array of files using the + * {@link #SIZE_REVERSE} singleton instance: + *

+ *       File[] array = ...
+ *       SizeFileComparator.SIZE_REVERSE.sort(array);
+ * 
+ *

+ * N.B. Directories are treated as zero size unless + * sumDirectoryContents is true. + * + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:02:59 $ + * @since Commons IO 1.4 + */ +public class SizeFileComparator extends AbstractFileComparator implements Serializable { + + /** Size comparator instance - directories are treated as zero size */ + public static final Comparator SIZE_COMPARATOR = new SizeFileComparator(); + + /** Reverse size comparator instance - directories are treated as zero size */ + public static final Comparator SIZE_REVERSE = new ReverseComparator(SIZE_COMPARATOR); + + /** + * Size comparator instance which sums the size of a directory's contents + * using {@link FileUtils#sizeOfDirectory(File)} + */ + public static final Comparator SIZE_SUMDIR_COMPARATOR = new SizeFileComparator(true); + + /** + * Reverse size comparator instance which sums the size of a directory's contents + * using {@link FileUtils#sizeOfDirectory(File)} + */ + public static final Comparator SIZE_SUMDIR_REVERSE = new ReverseComparator(SIZE_SUMDIR_COMPARATOR); + + /** Whether the sum of the directory's contents should be calculated. */ + private final boolean sumDirectoryContents; + + /** + * Construct a file size comparator instance (directories treated as zero size). + */ + public SizeFileComparator() { + this.sumDirectoryContents = false; + } + + /** + * Construct a file size comparator instance specifying whether the size of + * the directory contents should be aggregated. + *

+ * If the sumDirectoryContents is true The size of + * directories is calculated using {@link FileUtils#sizeOfDirectory(File)}. + * + * @param sumDirectoryContents true if the sum of the directoryies contents + * should be calculated, otherwise false if directories should be treated + * as size zero (see {@link FileUtils#sizeOfDirectory(File)}). + */ + public SizeFileComparator(boolean sumDirectoryContents) { + this.sumDirectoryContents = sumDirectoryContents; + } + + /** + * Compare the length of two files. + * + * @param file1 The first file to compare + * @param file2 The second file to compare + * @return a negative value if the first file's length + * is less than the second, zero if the lengths are the + * same and a positive value if the first files length + * is greater than the second file. + * + */ + public int compare(File file1, File file2) { + long size1 = 0; + if (file1.isDirectory()) { + size1 = sumDirectoryContents && file1.exists() ? FileUtils.sizeOfDirectory(file1) : 0; + } else { + size1 = file1.length(); + } + long size2 = 0; + if (file2.isDirectory()) { + size2 = sumDirectoryContents && file2.exists() ? FileUtils.sizeOfDirectory(file2) : 0; + } else { + size2 = file2.length(); + } + long result = size1 - size2; + if (result < 0) { + return -1; + } else if (result > 0) { + return 1; + } else { + return 0; + } + } + + /** + * String representation of this file comparator. + * + * @return String representation of this file comparator + */ + @Override + public String toString() { + return super.toString() + "[sumDirectoryContents=" + sumDirectoryContents + "]"; + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/comparator/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/package.html 1 Oct 2012 13:02:58 -0000 1.1 @@ -0,0 +1,188 @@ + + + + +

This package provides various {@link java.util.Comparator} implementations +for {@link java.io.File}s. +

+

Sorting

+

+ All the compartors include convenience utility sort(File...) and + sort(List) methods. +

+

+ For example, to sort the files in a directory by name: +

+
+        File[] files = dir.listFiles();
+        NameFileComparator.NAME_COMPARATOR.sort(files);
+  
+

+ ...alternatively you can do this in one line: +

+

+

+        File[] files = NameFileComparator.NAME_COMPARATOR.sort(dir.listFiles());
+  
+

+ +

Composite Comparator

+

+ The CompositeFileComparator can be used + to compare (and sort lists or arrays of files) by combining a number other comparators. +

+

+ For example, to sort an array of files by type (i.e. directory or file) + and then by name: +

+

+

+        CompositeFileComparator comparator =
+                        new CompositeFileComparator(
+                                    DirectoryFileComparator.DIRECTORY_COMPARATOR,
+                                    NameFileComparator.NAME_COMPARATOR);
+        File[] files = dir.listFiles();
+        comparator.sort(files);
+  
+

+ +

Singleton Instances (thread-safe)

+

+ The {@link java.util.Comparator} implementations have some convenience + singleton(thread-safe) instances ready to use: +

+

+ + + Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AbstractFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AbstractFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AbstractFileFilter.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; + +/** + * An abstract class which implements the Java FileFilter and FilenameFilter + * interfaces via the IOFileFilter interface. + *

+ * Note that a subclass must override one of the accept methods, + * otherwise your class will infinitely loop. + * + * @since Commons IO 1.0 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:01 $ + * + * @author Stephen Colebourne + */ +public abstract class AbstractFileFilter implements IOFileFilter { + + /** + * Checks to see if the File should be accepted by this filter. + * + * @param file the File to check + * @return true if this file matches the test + */ + public boolean accept(File file) { + return accept(file.getParentFile(), file.getName()); + } + + /** + * Checks to see if the File should be accepted by this filter. + * + * @param dir the directory File to check + * @param name the filename within the directory to check + * @return true if this file matches the test + */ + public boolean accept(File dir, String name) { + return accept(new File(dir, name)); + } + + /** + * Provide a String representaion of this file filter. + * + * @return a String representaion + */ + @Override + public String toString() { + return getClass().getSimpleName(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AgeFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AgeFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AgeFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,158 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.util.Date; + +import org.apache.commons.io.FileUtils; + +/** + * Filters files based on a cutoff time, can filter either newer + * files or files equal to or older. + *

+ * For example, to print all files and directories in the + * current directory older than one day: + * + *

+ * File dir = new File(".");
+ * // We are interested in files older than one day
+ * long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
+ * String[] files = dir.list( new AgeFileFilter(cutoff) );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + * @author Rahul Akolkar + * @version $Id: AgeFileFilter.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + * @see FileFilterUtils#ageFileFilter(Date) + * @see FileFilterUtils#ageFileFilter(File) + * @see FileFilterUtils#ageFileFilter(long) + * @see FileFilterUtils#ageFileFilter(Date, boolean) + * @see FileFilterUtils#ageFileFilter(File, boolean) + * @see FileFilterUtils#ageFileFilter(long, boolean) + * @since Commons IO 1.2 + */ +public class AgeFileFilter extends AbstractFileFilter implements Serializable { + + /** The cutoff time threshold. */ + private final long cutoff; + /** Whether the files accepted will be older or newer. */ + private final boolean acceptOlder; + + /** + * Constructs a new age file filter for files equal to or older than + * a certain cutoff + * + * @param cutoff the threshold age of the files + */ + public AgeFileFilter(long cutoff) { + this(cutoff, true); + } + + /** + * Constructs a new age file filter for files on any one side + * of a certain cutoff. + * + * @param cutoff the threshold age of the files + * @param acceptOlder if true, older files (at or before the cutoff) + * are accepted, else newer ones (after the cutoff). + */ + public AgeFileFilter(long cutoff, boolean acceptOlder) { + this.acceptOlder = acceptOlder; + this.cutoff = cutoff; + } + + /** + * Constructs a new age file filter for files older than (at or before) + * a certain cutoff date. + * + * @param cutoffDate the threshold age of the files + */ + public AgeFileFilter(Date cutoffDate) { + this(cutoffDate, true); + } + + /** + * Constructs a new age file filter for files on any one side + * of a certain cutoff date. + * + * @param cutoffDate the threshold age of the files + * @param acceptOlder if true, older files (at or before the cutoff) + * are accepted, else newer ones (after the cutoff). + */ + public AgeFileFilter(Date cutoffDate, boolean acceptOlder) { + this(cutoffDate.getTime(), acceptOlder); + } + + /** + * Constructs a new age file filter for files older than (at or before) + * a certain File (whose last modification time will be used as reference). + * + * @param cutoffReference the file whose last modification + * time is usesd as the threshold age of the files + */ + public AgeFileFilter(File cutoffReference) { + this(cutoffReference, true); + } + + /** + * Constructs a new age file filter for files on any one side + * of a certain File (whose last modification time will be used as + * reference). + * + * @param cutoffReference the file whose last modification + * time is usesd as the threshold age of the files + * @param acceptOlder if true, older files (at or before the cutoff) + * are accepted, else newer ones (after the cutoff). + */ + public AgeFileFilter(File cutoffReference, boolean acceptOlder) { + this(cutoffReference.lastModified(), acceptOlder); + } + + //----------------------------------------------------------------------- + /** + * Checks to see if the last modification of the file matches cutoff + * favorably. + *

+ * If last modification time equals cutoff and newer files are required, + * file IS NOT selected. + * If last modification time equals cutoff and older files are required, + * file IS selected. + * + * @param file the File to check + * @return true if the filename matches + */ + @Override + public boolean accept(File file) { + boolean newer = FileUtils.isFileNewer(file, cutoff); + return acceptOlder ? !newer : newer; + } + + /** + * Provide a String representaion of this file filter. + * + * @return a String representaion + */ + @Override + public String toString() { + String condition = acceptOlder ? "<=" : ">"; + return super.toString() + "(" + condition + cutoff + ")"; + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AndFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AndFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AndFileFilter.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * A {@link java.io.FileFilter} providing conditional AND logic across a list of + * file filters. This filter returns true if all filters in the + * list return true. Otherwise, it returns false. + * Checking of the file filter list stops when the first filter returns + * false. + * + * @since Commons IO 1.0 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:01 $ + * + * @author Steven Caswell + * @see FileFilterUtils#and(IOFileFilter...) + */ +public class AndFileFilter + extends AbstractFileFilter + implements ConditionalFileFilter, Serializable { + + /** The list of file filters. */ + private final List fileFilters; + + /** + * Constructs a new instance of AndFileFilter. + * + * @since Commons IO 1.1 + */ + public AndFileFilter() { + this.fileFilters = new ArrayList(); + } + + /** + * Constructs a new instance of AndFileFilter + * with the specified list of filters. + * + * @param fileFilters a List of IOFileFilter instances, copied, null ignored + * @since Commons IO 1.1 + */ + public AndFileFilter(final List fileFilters) { + if (fileFilters == null) { + this.fileFilters = new ArrayList(); + } else { + this.fileFilters = new ArrayList(fileFilters); + } + } + + /** + * Constructs a new file filter that ANDs the result of two other filters. + * + * @param filter1 the first filter, must not be null + * @param filter2 the second filter, must not be null + * @throws IllegalArgumentException if either filter is null + */ + public AndFileFilter(IOFileFilter filter1, IOFileFilter filter2) { + if (filter1 == null || filter2 == null) { + throw new IllegalArgumentException("The filters must not be null"); + } + this.fileFilters = new ArrayList(2); + addFileFilter(filter1); + addFileFilter(filter2); + } + + /** + * {@inheritDoc} + */ + public void addFileFilter(final IOFileFilter ioFileFilter) { + this.fileFilters.add(ioFileFilter); + } + + /** + * {@inheritDoc} + */ + public List getFileFilters() { + return Collections.unmodifiableList(this.fileFilters); + } + + /** + * {@inheritDoc} + */ + public boolean removeFileFilter(final IOFileFilter ioFileFilter) { + return this.fileFilters.remove(ioFileFilter); + } + + /** + * {@inheritDoc} + */ + public void setFileFilters(final List fileFilters) { + this.fileFilters.clear(); + this.fileFilters.addAll(fileFilters); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean accept(final File file) { + if (this.fileFilters.size() == 0) { + return false; + } + for (IOFileFilter fileFilter : fileFilters) { + if (!fileFilter.accept(file)) { + return false; + } + } + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean accept(final File file, final String name) { + if (this.fileFilters.size() == 0) { + return false; + } + for (IOFileFilter fileFilter : fileFilters) { + if (!fileFilter.accept(file, name)) { + return false; + } + } + return true; + } + + /** + * Provide a String representaion of this file filter. + * + * @return a String representaion + */ + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append(super.toString()); + buffer.append("("); + if (fileFilters != null) { + for (int i = 0; i < fileFilters.size(); i++) { + if (i > 0) { + buffer.append(","); + } + Object filter = fileFilters.get(i); + buffer.append(filter == null ? "null" : filter.toString()); + } + } + buffer.append(")"); + return buffer.toString(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanReadFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanReadFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanReadFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; + +/** + * This filter accepts Files that can be read. + *

+ * Example, showing how to print out a list of the + * current directory's readable files: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( CanReadFileFilter.CAN_READ );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + *

+ * Example, showing how to print out a list of the + * current directory's un-readable files: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( CanReadFileFilter.CANNOT_READ );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + *

+ * Example, showing how to print out a list of the + * current directory's read-only files: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( CanReadFileFilter.READ_ONLY );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + * @since Commons IO 1.3 + * @version $Revision: 1.1 $ + */ +public class CanReadFileFilter extends AbstractFileFilter implements Serializable { + + /** Singleton instance of readable filter */ + public static final IOFileFilter CAN_READ = new CanReadFileFilter(); + + /** Singleton instance of not readable filter */ + public static final IOFileFilter CANNOT_READ = new NotFileFilter(CAN_READ); + + /** Singleton instance of read-only filter */ + public static final IOFileFilter READ_ONLY = new AndFileFilter(CAN_READ, + CanWriteFileFilter.CANNOT_WRITE); + + /** + * Restrictive consructor. + */ + protected CanReadFileFilter() { + } + + /** + * Checks to see if the file can be read. + * + * @param file the File to check. + * @return true if the file can be + * read, otherwise false. + */ + @Override + public boolean accept(File file) { + return file.canRead(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanWriteFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanWriteFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanWriteFileFilter.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; + +/** + * This filter accepts Files that can be written to. + *

+ * Example, showing how to print out a list of the + * current directory's writable files: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( CanWriteFileFilter.CAN_WRITE );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + *

+ * Example, showing how to print out a list of the + * current directory's un-writable files: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( CanWriteFileFilter.CANNOT_WRITE );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + *

+ * N.B. For read-only files, use + * CanReadFileFilter.READ_ONLY. + * + * @since Commons IO 1.3 + * @version $Revision: 1.1 $ + */ +public class CanWriteFileFilter extends AbstractFileFilter implements Serializable { + + /** Singleton instance of writable filter */ + public static final IOFileFilter CAN_WRITE = new CanWriteFileFilter(); + + /** Singleton instance of not writable filter */ + public static final IOFileFilter CANNOT_WRITE = new NotFileFilter(CAN_WRITE); + + /** + * Restrictive consructor. + */ + protected CanWriteFileFilter() { + } + + /** + * Checks to see if the file can be written to. + * + * @param file the File to check + * @return true if the file can be + * written to, otherwise false. + */ + @Override + public boolean accept(File file) { + return file.canWrite(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/ConditionalFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/ConditionalFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/ConditionalFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.util.List; + +/** + * Defines operations for conditional file filters. + * + * @since Commons IO 1.1 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:02 $ + * + * @author Steven Caswell + */ +public interface ConditionalFileFilter { + + /** + * Adds the specified file filter to the list of file filters at the end of + * the list. + * + * @param ioFileFilter the filter to be added + * @since Commons IO 1.1 + */ + void addFileFilter(IOFileFilter ioFileFilter); + + /** + * Returns this conditional file filter's list of file filters. + * + * @return the file filter list + * @since Commons IO 1.1 + */ + List getFileFilters(); + + /** + * Removes the specified file filter. + * + * @param ioFileFilter filter to be removed + * @return true if the filter was found in the list, + * false otherwise + * @since Commons IO 1.1 + */ + boolean removeFileFilter(IOFileFilter ioFileFilter); + + /** + * Sets the list of file filters, replacing any previously configured + * file filters on this filter. + * + * @param fileFilters the list of filters + * @since Commons IO 1.1 + */ + void setFileFilters(List fileFilters); + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/DelegateFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/DelegateFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/DelegateFileFilter.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.FileFilter; +import java.io.FilenameFilter; +import java.io.Serializable; + +/** + * This class turns a Java FileFilter or FilenameFilter into an IO FileFilter. + * + * @since Commons IO 1.0 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:01 $ + * + * @author Stephen Colebourne + * @see FileFilterUtils#asFileFilter(FileFilter) + * @see FileFilterUtils#asFileFilter(FilenameFilter) + */ +public class DelegateFileFilter extends AbstractFileFilter implements Serializable { + + /** The Filename filter */ + private final FilenameFilter filenameFilter; + /** The File filter */ + private final FileFilter fileFilter; + + /** + * Constructs a delegate file filter around an existing FilenameFilter. + * + * @param filter the filter to decorate + */ + public DelegateFileFilter(FilenameFilter filter) { + if (filter == null) { + throw new IllegalArgumentException("The FilenameFilter must not be null"); + } + this.filenameFilter = filter; + this.fileFilter = null; + } + + /** + * Constructs a delegate file filter around an existing FileFilter. + * + * @param filter the filter to decorate + */ + public DelegateFileFilter(FileFilter filter) { + if (filter == null) { + throw new IllegalArgumentException("The FileFilter must not be null"); + } + this.fileFilter = filter; + this.filenameFilter = null; + } + + /** + * Checks the filter. + * + * @param file the file to check + * @return true if the filter matches + */ + @Override + public boolean accept(File file) { + if (fileFilter != null) { + return fileFilter.accept(file); + } else { + return super.accept(file); + } + } + + /** + * Checks the filter. + * + * @param dir the directory + * @param name the filename in the directory + * @return true if the filter matches + */ + @Override + public boolean accept(File dir, String name) { + if (filenameFilter != null) { + return filenameFilter.accept(dir, name); + } else { + return super.accept(dir, name); + } + } + + /** + * Provide a String representaion of this file filter. + * + * @return a String representaion + */ + @Override + public String toString() { + String delegate = (fileFilter != null ? fileFilter.toString() : filenameFilter.toString()); + return super.toString() + "(" + delegate + ")"; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/DirectoryFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/DirectoryFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/DirectoryFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; + +/** + * This filter accepts Files that are directories. + *

+ * For example, here is how to print out a list of the + * current directory's subdirectories: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( DirectoryFileFilter.INSTANCE );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + * @since Commons IO 1.0 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:02 $ + * + * @author Stephen Colebourne + * @author Peter Donald + * @see FileFilterUtils#directoryFileFilter() + */ +public class DirectoryFileFilter extends AbstractFileFilter implements Serializable { + + /** + * Singleton instance of directory filter. + * @since Commons IO 1.3 + */ + public static final IOFileFilter DIRECTORY = new DirectoryFileFilter(); + /** + * Singleton instance of directory filter. + * Please use the identical DirectoryFileFilter.DIRECTORY constant. + * The new name is more JDK 1.5 friendly as it doesn't clash with other + * values when using static imports. + */ + public static final IOFileFilter INSTANCE = DIRECTORY; + + /** + * Restrictive consructor. + */ + protected DirectoryFileFilter() { + } + + /** + * Checks to see if the file is a directory. + * + * @param file the File to check + * @return true if the file is a directory + */ + @Override + public boolean accept(File file) { + return file.isDirectory(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/EmptyFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/EmptyFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/EmptyFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; + +/** + * This filter accepts files or directories that are empty. + *

+ * If the File is a directory it checks that + * it contains no files. + *

+ * Example, showing how to print out a list of the + * current directory's empty files/directories: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( EmptyFileFilter.EMPTY );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + *

+ * Example, showing how to print out a list of the + * current directory's non-empty files/directories: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( EmptyFileFilter.NOT_EMPTY );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + * @since Commons IO 1.3 + * @version $Revision: 1.1 $ + */ +public class EmptyFileFilter extends AbstractFileFilter implements Serializable { + + /** Singleton instance of empty filter */ + public static final IOFileFilter EMPTY = new EmptyFileFilter(); + + /** Singleton instance of not-empty filter */ + public static final IOFileFilter NOT_EMPTY = new NotFileFilter(EMPTY); + + /** + * Restrictive consructor. + */ + protected EmptyFileFilter() { + } + + /** + * Checks to see if the file is empty. + * + * @param file the file or directory to check + * @return true if the file or directory + * is empty, otherwise false. + */ + @Override + public boolean accept(File file) { + if (file.isDirectory()) { + File[] files = file.listFiles(); + return (files == null || files.length == 0); + } else { + return (file.length() == 0); + } + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/FalseFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/FalseFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/FalseFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; + +/** + * A file filter that always returns false. + * + * @since Commons IO 1.0 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:02 $ + * + * @author Stephen Colebourne + * @see FileFilterUtils#falseFileFilter() + */ +public class FalseFileFilter implements IOFileFilter, Serializable { + + /** + * Singleton instance of false filter. + * @since Commons IO 1.3 + */ + public static final IOFileFilter FALSE = new FalseFileFilter(); + /** + * Singleton instance of false filter. + * Please use the identical FalseFileFilter.FALSE constant. + * The new name is more JDK 1.5 friendly as it doesn't clash with other + * values when using static imports. + */ + public static final IOFileFilter INSTANCE = FALSE; + + /** + * Restrictive consructor. + */ + protected FalseFileFilter() { + } + + /** + * Returns false. + * + * @param file the file to check + * @return false + */ + public boolean accept(File file) { + return false; + } + + /** + * Returns false. + * + * @param dir the directory to check + * @param name the filename + * @return false + */ + public boolean accept(File dir, String name) { + return false; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/FileFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/FileFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/FileFileFilter.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; + +/** + * This filter accepts Files that are files (not directories). + *

+ * For example, here is how to print out a list of the real files + * within the current directory: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( FileFileFilter.FILE );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + * @since Commons IO 1.3 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:01 $ + * @see FileFilterUtils#fileFileFilter() + */ +public class FileFileFilter extends AbstractFileFilter implements Serializable { + + /** Singleton instance of file filter */ + public static final IOFileFilter FILE = new FileFileFilter(); + + /** + * Restrictive consructor. + */ + protected FileFileFilter() { + } + + /** + * Checks to see if the file is a file. + * + * @param file the File to check + * @return true if the file is a file + */ + @Override + public boolean accept(File file) { + return file.isFile(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/FileFilterUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/FileFilterUtils.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/FileFilterUtils.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,801 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.FileFilter; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.io.IOCase; + +/** + * Useful utilities for working with file filters. It provides access to all + * file filter implementations in this package so you don't have to import + * every class you use. + * + * @since Commons IO 1.0 + * @version $Id: FileFilterUtils.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + * + * @author Stephen Colebourne + * @author Jeremias Maerki + * @author Masato Tezuka + * @author Rahul Akolkar + */ +public class FileFilterUtils { + + /** + * FileFilterUtils is not normally instantiated. + */ + public FileFilterUtils() { + } + + //----------------------------------------------------------------------- + + /** + *

+ * Applies an {@link IOFileFilter} to the provided {@link File} + * objects. The resulting array is a subset of the original file list that + * matches the provided filter. + *

+ * + *

+ * The {@link Set} returned by this method is not guaranteed to be thread safe. + *

+ * + *
+     * Set<File> allFiles = ...
+     * Set<File> javaFiles = FileFilterUtils.filterSet(allFiles,
+     *     FileFilterUtils.suffixFileFilter(".java"));
+     * 
+ * @param filter the filter to apply to the set of files. + * @param files the array of files to apply the filter to. + * + * @return a subset of files that is accepted by the + * file filter. + * @throws IllegalArgumentException if the filter is null + * or files contains a null value. + * + * @since Commons IO 2.0 + */ + public static File[] filter(IOFileFilter filter, File... files) { + if (filter == null) { + throw new IllegalArgumentException("file filter is null"); + } + if (files == null) { + return new File[0]; + } + List acceptedFiles = new ArrayList(); + for (File file : files) { + if (file == null) { + throw new IllegalArgumentException("file array contains null"); + } + if (filter.accept(file)) { + acceptedFiles.add(file); + } + } + return acceptedFiles.toArray(new File[acceptedFiles.size()]); + } + + /** + *

+ * Applies an {@link IOFileFilter} to the provided {@link File} + * objects. The resulting array is a subset of the original file list that + * matches the provided filter. + *

+ * + *

+ * The {@link Set} returned by this method is not guaranteed to be thread safe. + *

+ * + *
+     * Set<File> allFiles = ...
+     * Set<File> javaFiles = FileFilterUtils.filterSet(allFiles,
+     *     FileFilterUtils.suffixFileFilter(".java"));
+     * 
+ * @param filter the filter to apply to the set of files. + * @param files the array of files to apply the filter to. + * + * @return a subset of files that is accepted by the + * file filter. + * @throws IllegalArgumentException if the filter is null + * or files contains a null value. + * + * @since Commons IO 2.0 + */ + public static File[] filter(IOFileFilter filter, Iterable files) { + List acceptedFiles = filterList(filter, files); + return acceptedFiles.toArray(new File[acceptedFiles.size()]); + } + + /** + *

+ * Applies an {@link IOFileFilter} to the provided {@link File} + * objects. The resulting list is a subset of the original files that + * matches the provided filter. + *

+ * + *

+ * The {@link List} returned by this method is not guaranteed to be thread safe. + *

+ * + *
+     * List<File> filesAndDirectories = ...
+     * List<File> directories = FileFilterUtils.filterList(filesAndDirectories,
+     *     FileFilterUtils.directoryFileFilter());
+     * 
+ * @param filter the filter to apply to each files in the list. + * @param files the collection of files to apply the filter to. + * + * @return a subset of files that is accepted by the + * file filter. + * @throws IllegalArgumentException if the filter is null + * or files contains a null value. + * @since Commons IO 2.0 + */ + public static List filterList(IOFileFilter filter, Iterable files) { + return filter(filter, files, new ArrayList()); + } + + /** + *

+ * Applies an {@link IOFileFilter} to the provided {@link File} + * objects. The resulting list is a subset of the original files that + * matches the provided filter. + *

+ * + *

+ * The {@link List} returned by this method is not guaranteed to be thread safe. + *

+ * + *
+     * List<File> filesAndDirectories = ...
+     * List<File> directories = FileFilterUtils.filterList(filesAndDirectories,
+     *     FileFilterUtils.directoryFileFilter());
+     * 
+ * @param filter the filter to apply to each files in the list. + * @param files the collection of files to apply the filter to. + * + * @return a subset of files that is accepted by the + * file filter. + * @throws IllegalArgumentException if the filter is null + * or files contains a null value. + * @since Commons IO 2.0 + */ + public static List filterList(IOFileFilter filter, File... files) { + File[] acceptedFiles = filter(filter, files); + return Arrays.asList(acceptedFiles); + } + + /** + *

+ * Applies an {@link IOFileFilter} to the provided {@link File} + * objects. The resulting set is a subset of the original file list that + * matches the provided filter. + *

+ * + *

+ * The {@link Set} returned by this method is not guaranteed to be thread safe. + *

+ * + *
+     * Set<File> allFiles = ...
+     * Set<File> javaFiles = FileFilterUtils.filterSet(allFiles,
+     *     FileFilterUtils.suffixFileFilter(".java"));
+     * 
+ * @param filter the filter to apply to the set of files. + * @param files the collection of files to apply the filter to. + * + * @return a subset of files that is accepted by the + * file filter. + * @throws IllegalArgumentException if the filter is null + * or files contains a null value. + * + * @since Commons IO 2.0 + */ + public static Set filterSet(IOFileFilter filter, File... files) { + File[] acceptedFiles = filter(filter, files); + return new HashSet(Arrays.asList(acceptedFiles)); + } + + /** + *

+ * Applies an {@link IOFileFilter} to the provided {@link File} + * objects. The resulting set is a subset of the original file list that + * matches the provided filter. + *

+ * + *

+ * The {@link Set} returned by this method is not guaranteed to be thread safe. + *

+ * + *
+     * Set<File> allFiles = ...
+     * Set<File> javaFiles = FileFilterUtils.filterSet(allFiles,
+     *     FileFilterUtils.suffixFileFilter(".java"));
+     * 
+ * @param filter the filter to apply to the set of files. + * @param files the collection of files to apply the filter to. + * + * @return a subset of files that is accepted by the + * file filter. + * @throws IllegalArgumentException if the filter is null + * or files contains a null value. + * + * @since Commons IO 2.0 + */ + public static Set filterSet(IOFileFilter filter, Iterable files) { + return filter(filter, files, new HashSet()); + } + + /** + *

+ * Applies an {@link IOFileFilter} to the provided {@link File} + * objects and appends the accepted files to the other supplied collection. + *

+ * + *
+     * List<File> files = ...
+     * List<File> directories = FileFilterUtils.filterList(files,
+     *     FileFilterUtils.sizeFileFilter(FileUtils.FIFTY_MB), 
+     *         new ArrayList<File>());
+     * 
+ * @param filter the filter to apply to the collection of files. + * @param files the collection of files to apply the filter to. + * @param acceptedFiles the list of files to add accepted files to. + * + * @param the type of the file collection. + * @return a subset of files that is accepted by the + * file filter. + * @throws IllegalArgumentException if the filter is null + * or files contains a null value. + */ + private static > T filter(IOFileFilter filter, + Iterable files, T acceptedFiles) { + if (filter == null) { + throw new IllegalArgumentException("file filter is null"); + } + if (files != null) { + for (File file : files) { + if (file == null) { + throw new IllegalArgumentException("file collection contains null"); + } + if (filter.accept(file)) { + acceptedFiles.add(file); + } + } + } + return acceptedFiles; + } + + /** + * Returns a filter that returns true if the filename starts with the specified text. + * + * @param prefix the filename prefix + * @return a prefix checking filter + * @see PrefixFileFilter + */ + public static IOFileFilter prefixFileFilter(String prefix) { + return new PrefixFileFilter(prefix); + } + + /** + * Returns a filter that returns true if the filename starts with the specified text. + * + * @param prefix the filename prefix + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @return a prefix checking filter + * @see PrefixFileFilter + * @since Commons IO 2.0 + */ + public static IOFileFilter prefixFileFilter(String prefix, IOCase caseSensitivity) { + return new PrefixFileFilter(prefix, caseSensitivity); + } + + /** + * Returns a filter that returns true if the filename ends with the specified text. + * + * @param suffix the filename suffix + * @return a suffix checking filter + * @see SuffixFileFilter + */ + public static IOFileFilter suffixFileFilter(String suffix) { + return new SuffixFileFilter(suffix); + } + + /** + * Returns a filter that returns true if the filename ends with the specified text. + * + * @param suffix the filename suffix + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @return a suffix checking filter + * @see SuffixFileFilter + * @since Commons IO 2.0 + */ + public static IOFileFilter suffixFileFilter(String suffix, IOCase caseSensitivity) { + return new SuffixFileFilter(suffix, caseSensitivity); + } + + /** + * Returns a filter that returns true if the filename matches the specified text. + * + * @param name the filename + * @return a name checking filter + * @see NameFileFilter + */ + public static IOFileFilter nameFileFilter(String name) { + return new NameFileFilter(name); + } + + /** + * Returns a filter that returns true if the filename matches the specified text. + * + * @param name the filename + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @return a name checking filter + * @see NameFileFilter + * @since Commons IO 2.0 + */ + public static IOFileFilter nameFileFilter(String name, IOCase caseSensitivity) { + return new NameFileFilter(name, caseSensitivity); + } + + /** + * Returns a filter that checks if the file is a directory. + * + * @return file filter that accepts only directories and not files + * @see DirectoryFileFilter#DIRECTORY + */ + public static IOFileFilter directoryFileFilter() { + return DirectoryFileFilter.DIRECTORY; + } + + /** + * Returns a filter that checks if the file is a file (and not a directory). + * + * @return file filter that accepts only files and not directories + * @see FileFileFilter#FILE + */ + public static IOFileFilter fileFileFilter() { + return FileFileFilter.FILE; + } + + //----------------------------------------------------------------------- + /** + * Returns a filter that ANDs the two specified filters. + * + * @param filter1 the first filter + * @param filter2 the second filter + * @return a filter that ANDs the two specified filters + * @see #and(IOFileFilter...) + * @see AndFileFilter + * @deprecated use {@link #and(IOFileFilter...)} + */ + @Deprecated + public static IOFileFilter andFileFilter(IOFileFilter filter1, IOFileFilter filter2) { + return new AndFileFilter(filter1, filter2); + } + + /** + * Returns a filter that ORs the two specified filters. + * + * @param filter1 the first filter + * @param filter2 the second filter + * @return a filter that ORs the two specified filters + * @see #or(IOFileFilter...) + * @see OrFileFilter + * @deprecated use {@link #or(IOFileFilter...)} + */ + @Deprecated + public static IOFileFilter orFileFilter(IOFileFilter filter1, IOFileFilter filter2) { + return new OrFileFilter(filter1, filter2); + } + + /** + * Returns a filter that ANDs the specified filters. + * + * @param filters the IOFileFilters that will be ANDed together. + * @return a filter that ANDs the specified filters + * + * @throws IllegalArgumentException if the filters are null or contain a + * null value. + * @see AndFileFilter + * @since Commons IO 2.0 + */ + public static IOFileFilter and(IOFileFilter... filters) { + return new AndFileFilter(toList(filters)); + } + + /** + * Returns a filter that ORs the specified filters. + * + * @param filters the IOFileFilters that will be ORed together. + * @return a filter that ORs the specified filters + * + * @throws IllegalArgumentException if the filters are null or contain a + * null value. + * @see OrFileFilter + * @since Commons IO 2.0 + */ + public static IOFileFilter or(IOFileFilter... filters) { + return new OrFileFilter(toList(filters)); + } + + /** + * Create a List of file filters. + * + * @param filters The file filters + * @return The list of file filters + * @throws IllegalArgumentException if the filters are null or contain a + * null value. + * @since Commons IO 2.0 + */ + public static List toList(IOFileFilter... filters) { + if (filters == null) { + throw new IllegalArgumentException("The filters must not be null"); + } + List list = new ArrayList(filters.length); + for (int i = 0; i < filters.length; i++) { + if (filters[i] == null) { + throw new IllegalArgumentException("The filter[" + i + "] is null"); + } + list.add(filters[i]); + } + return list; + } + + /** + * Returns a filter that NOTs the specified filter. + * + * @param filter the filter to invert + * @return a filter that NOTs the specified filter + * @see NotFileFilter + */ + public static IOFileFilter notFileFilter(IOFileFilter filter) { + return new NotFileFilter(filter); + } + + //----------------------------------------------------------------------- + /** + * Returns a filter that always returns true. + * + * @return a true filter + * @see TrueFileFilter#TRUE + */ + public static IOFileFilter trueFileFilter() { + return TrueFileFilter.TRUE; + } + + /** + * Returns a filter that always returns false. + * + * @return a false filter + * @see FalseFileFilter#FALSE + */ + public static IOFileFilter falseFileFilter() { + return FalseFileFilter.FALSE; + } + + //----------------------------------------------------------------------- + /** + * Returns an IOFileFilter that wraps the + * FileFilter instance. + * + * @param filter the filter to be wrapped + * @return a new filter that implements IOFileFilter + * @see DelegateFileFilter + */ + public static IOFileFilter asFileFilter(FileFilter filter) { + return new DelegateFileFilter(filter); + } + + /** + * Returns an IOFileFilter that wraps the + * FilenameFilter instance. + * + * @param filter the filter to be wrapped + * @return a new filter that implements IOFileFilter + * @see DelegateFileFilter + */ + public static IOFileFilter asFileFilter(FilenameFilter filter) { + return new DelegateFileFilter(filter); + } + + //----------------------------------------------------------------------- + /** + * Returns a filter that returns true if the file was last modified after + * the specified cutoff time. + * + * @param cutoff the time threshold + * @return an appropriately configured age file filter + * @see AgeFileFilter + * @since Commons IO 1.2 + */ + public static IOFileFilter ageFileFilter(long cutoff) { + return new AgeFileFilter(cutoff); + } + + /** + * Returns a filter that filters files based on a cutoff time. + * + * @param cutoff the time threshold + * @param acceptOlder if true, older files get accepted, if false, newer + * @return an appropriately configured age file filter + * @see AgeFileFilter + * @since Commons IO 1.2 + */ + public static IOFileFilter ageFileFilter(long cutoff, boolean acceptOlder) { + return new AgeFileFilter(cutoff, acceptOlder); + } + + /** + * Returns a filter that returns true if the file was last modified after + * the specified cutoff date. + * + * @param cutoffDate the time threshold + * @return an appropriately configured age file filter + * @see AgeFileFilter + * @since Commons IO 1.2 + */ + public static IOFileFilter ageFileFilter(Date cutoffDate) { + return new AgeFileFilter(cutoffDate); + } + + /** + * Returns a filter that filters files based on a cutoff date. + * + * @param cutoffDate the time threshold + * @param acceptOlder if true, older files get accepted, if false, newer + * @return an appropriately configured age file filter + * @see AgeFileFilter + * @since Commons IO 1.2 + */ + public static IOFileFilter ageFileFilter(Date cutoffDate, boolean acceptOlder) { + return new AgeFileFilter(cutoffDate, acceptOlder); + } + + /** + * Returns a filter that returns true if the file was last modified after + * the specified reference file. + * + * @param cutoffReference the file whose last modification + * time is usesd as the threshold age of the files + * @return an appropriately configured age file filter + * @see AgeFileFilter + * @since Commons IO 1.2 + */ + public static IOFileFilter ageFileFilter(File cutoffReference) { + return new AgeFileFilter(cutoffReference); + } + + /** + * Returns a filter that filters files based on a cutoff reference file. + * + * @param cutoffReference the file whose last modification + * time is usesd as the threshold age of the files + * @param acceptOlder if true, older files get accepted, if false, newer + * @return an appropriately configured age file filter + * @see AgeFileFilter + * @since Commons IO 1.2 + */ + public static IOFileFilter ageFileFilter(File cutoffReference, boolean acceptOlder) { + return new AgeFileFilter(cutoffReference, acceptOlder); + } + + //----------------------------------------------------------------------- + /** + * Returns a filter that returns true if the file is bigger than a certain size. + * + * @param threshold the file size threshold + * @return an appropriately configured SizeFileFilter + * @see SizeFileFilter + * @since Commons IO 1.2 + */ + public static IOFileFilter sizeFileFilter(long threshold) { + return new SizeFileFilter(threshold); + } + + /** + * Returns a filter that filters based on file size. + * + * @param threshold the file size threshold + * @param acceptLarger if true, larger files get accepted, if false, smaller + * @return an appropriately configured SizeFileFilter + * @see SizeFileFilter + * @since Commons IO 1.2 + */ + public static IOFileFilter sizeFileFilter(long threshold, boolean acceptLarger) { + return new SizeFileFilter(threshold, acceptLarger); + } + + /** + * Returns a filter that accepts files whose size is >= minimum size + * and <= maximum size. + * + * @param minSizeInclusive the minimum file size (inclusive) + * @param maxSizeInclusive the maximum file size (inclusive) + * @return an appropriately configured IOFileFilter + * @see SizeFileFilter + * @since Commons IO 1.3 + */ + public static IOFileFilter sizeRangeFileFilter(long minSizeInclusive, long maxSizeInclusive ) { + IOFileFilter minimumFilter = new SizeFileFilter(minSizeInclusive, true); + IOFileFilter maximumFilter = new SizeFileFilter(maxSizeInclusive + 1L, false); + return new AndFileFilter(minimumFilter, maximumFilter); + } + + /** + * Returns a filter that accepts files that begin with the provided magic + * number. + * + * @param magicNumber the magic number (byte sequence) to match at the + * beginning of each file. + * + * @return an IOFileFilter that accepts files beginning with the provided + * magic number. + * + * @throws IllegalArgumentException if magicNumber is + * null or the empty String. + * @see MagicNumberFileFilter + * @since Commons IO 2.0 + */ + public static IOFileFilter magicNumberFileFilter(String magicNumber) { + return new MagicNumberFileFilter(magicNumber); + } + + /** + * Returns a filter that accepts files that contains the provided magic + * number at a specified offset within the file. + * + * @param magicNumber the magic number (byte sequence) to match at the + * provided offset in each file. + * @param offset the offset within the files to look for the magic number. + * + * @return an IOFileFilter that accepts files containing the magic number + * at the specified offset. + * + * @throws IllegalArgumentException if magicNumber is + * null or the empty String, or if offset is a + * negative number. + * @see MagicNumberFileFilter + * @since Commons IO 2.0 + */ + public static IOFileFilter magicNumberFileFilter(String magicNumber, long offset) { + return new MagicNumberFileFilter(magicNumber, offset); + } + + /** + * Returns a filter that accepts files that begin with the provided magic + * number. + * + * @param magicNumber the magic number (byte sequence) to match at the + * beginning of each file. + * + * @return an IOFileFilter that accepts files beginning with the provided + * magic number. + * + * @throws IllegalArgumentException if magicNumber is + * null or is of length zero. + * @see MagicNumberFileFilter + * @since Commons IO 2.0 + */ + public static IOFileFilter magicNumberFileFilter(byte[] magicNumber) { + return new MagicNumberFileFilter(magicNumber); + } + + /** + * Returns a filter that accepts files that contains the provided magic + * number at a specified offset within the file. + * + * @param magicNumber the magic number (byte sequence) to match at the + * provided offset in each file. + * @param offset the offset within the files to look for the magic number. + * + * @return an IOFileFilter that accepts files containing the magic number + * at the specified offset. + * + * @throws IllegalArgumentException if magicNumber is + * null, or contains no bytes, or offset + * is a negative number. + * @see MagicNumberFileFilter + * @since Commons IO 2.0 + */ + public static IOFileFilter magicNumberFileFilter(byte[] magicNumber, long offset) { + return new MagicNumberFileFilter(magicNumber, offset); + } + + //----------------------------------------------------------------------- + /* Constructed on demand and then cached */ + private static final IOFileFilter cvsFilter = notFileFilter( + and(directoryFileFilter(), nameFileFilter("CVS"))); + + /* Constructed on demand and then cached */ + private static final IOFileFilter svnFilter = notFileFilter( + and(directoryFileFilter(), nameFileFilter(".svn"))); + + /** + * Decorates a filter to make it ignore CVS directories. + * Passing in null will return a filter that accepts everything + * except CVS directories. + * + * @param filter the filter to decorate, null means an unrestricted filter + * @return the decorated filter, never null + * @since Commons IO 1.1 (method existed but had bug in 1.0) + */ + public static IOFileFilter makeCVSAware(IOFileFilter filter) { + if (filter == null) { + return cvsFilter; + } else { + return and(filter, cvsFilter); + } + } + + /** + * Decorates a filter to make it ignore SVN directories. + * Passing in null will return a filter that accepts everything + * except SVN directories. + * + * @param filter the filter to decorate, null means an unrestricted filter + * @return the decorated filter, never null + * @since Commons IO 1.1 + */ + public static IOFileFilter makeSVNAware(IOFileFilter filter) { + if (filter == null) { + return svnFilter; + } else { + return and(filter, svnFilter); + } + } + + //----------------------------------------------------------------------- + /** + * Decorates a filter so that it only applies to directories and not to files. + * + * @param filter the filter to decorate, null means an unrestricted filter + * @return the decorated filter, never null + * @see DirectoryFileFilter#DIRECTORY + * @since Commons IO 1.3 + */ + public static IOFileFilter makeDirectoryOnly(IOFileFilter filter) { + if (filter == null) { + return DirectoryFileFilter.DIRECTORY; + } + return new AndFileFilter(DirectoryFileFilter.DIRECTORY, filter); + } + + /** + * Decorates a filter so that it only applies to files and not to directories. + * + * @param filter the filter to decorate, null means an unrestricted filter + * @return the decorated filter, never null + * @see FileFileFilter#FILE + * @since Commons IO 1.3 + */ + public static IOFileFilter makeFileOnly(IOFileFilter filter) { + if (filter == null) { + return FileFileFilter.FILE; + } + return new AndFileFilter(FileFileFilter.FILE, filter); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/HiddenFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/HiddenFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/HiddenFileFilter.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; + +/** + * This filter accepts Files that are hidden. + *

+ * Example, showing how to print out a list of the + * current directory's hidden files: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( HiddenFileFilter.HIDDEN );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + *

+ * Example, showing how to print out a list of the + * current directory's visible (i.e. not hidden) files: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( HiddenFileFilter.VISIBLE );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + * @since Commons IO 1.3 + * @version $Revision: 1.1 $ + */ +public class HiddenFileFilter extends AbstractFileFilter implements Serializable { + + /** Singleton instance of hidden filter */ + public static final IOFileFilter HIDDEN = new HiddenFileFilter(); + + /** Singleton instance of visible filter */ + public static final IOFileFilter VISIBLE = new NotFileFilter(HIDDEN); + + /** + * Restrictive consructor. + */ + protected HiddenFileFilter() { + } + + /** + * Checks to see if the file is hidden. + * + * @param file the File to check + * @return true if the file is + * hidden, otherwise false. + */ + @Override + public boolean accept(File file) { + return file.isHidden(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/IOFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/IOFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/IOFileFilter.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.FileFilter; +import java.io.FilenameFilter; + +/** + * An interface which brings the FileFilter and FilenameFilter + * interfaces together. + * + * @since Commons IO 1.0 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:01 $ + * + * @author Stephen Colebourne + */ +public interface IOFileFilter extends FileFilter, FilenameFilter { + + /** + * Checks to see if the File should be accepted by this filter. + *

+ * Defined in {@link java.io.FileFilter}. + * + * @param file the File to check + * @return true if this file matches the test + */ + boolean accept(File file); + + /** + * Checks to see if the File should be accepted by this filter. + *

+ * Defined in {@link java.io.FilenameFilter}. + * + * @param dir the directory File to check + * @param name the filename within the directory to check + * @return true if this file matches the test + */ + boolean accept(File dir, String name); + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/MagicNumberFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/MagicNumberFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/MagicNumberFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,276 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.io.Serializable; +import java.util.Arrays; + +import org.apache.commons.io.IOUtils; + +/** + *

+ * File filter for matching files containing a "magic number". A magic number + * is a unique series of bytes common to all files of a specific file format. + * For instance, all Java class files begin with the bytes + * 0xCAFEBABE. + *

+ * + *
+ * File dir = new File(".");
+ * MagicNumberFileFilter javaClassFileFilter =
+ *     MagicNumberFileFilter(new byte[] {(byte) 0xCA, (byte) 0xFE, 
+ *       (byte) 0xBA, (byte) 0xBE}); 
+ * String[] javaClassFiles = dir.list(javaClassFileFilter);
+ * for (String javaClassFile : javaClassFiles) {
+ *     System.out.println(javaClassFile);
+ * }
+ * 
+ * + *

+ * Sometimes, such as in the case of TAR files, the + * magic number will be offset by a certain number of bytes in the file. In the + * case of TAR archive files, this offset is 257 bytes. + *

+ * + *
+ * File dir = new File(".");
+ * MagicNumberFileFilter tarFileFilter = 
+ *     MagicNumberFileFilter("ustar", 257); 
+ * String[] tarFiles = dir.list(tarFileFilter);
+ * for (String tarFile : tarFiles) {
+ *     System.out.println(tarFile);
+ * }
+ * 
+ * @since Commons IO 2.0 + * @see FileFilterUtils#magicNumberFileFilter(byte[]) + * @see FileFilterUtils#magicNumberFileFilter(String) + * @see FileFilterUtils#magicNumberFileFilter(byte[], long) + * @see FileFilterUtils#magicNumberFileFilter(String, long) + */ +public class MagicNumberFileFilter extends AbstractFileFilter implements + Serializable { + + /** + * The serialization version unique identifier. + */ + private static final long serialVersionUID = -547733176983104172L; + + /** + * The magic number to compare against the file's bytes at the provided + * offset. + */ + private final byte[] magicNumbers; + + /** + * The offset (in bytes) within the files that the magic number's bytes + * should appear. + */ + private final long byteOffset; + + /** + *

+ * Constructs a new MagicNumberFileFilter and associates it with the magic + * number to test for in files. This constructor assumes a starting offset + * of 0. + *

+ * + *

+ * It is important to note that the array is not cloned and that + * any changes to the magic number array after construction will affect the + * behavior of this file filter. + *

+ * + *
+     * MagicNumberFileFilter javaClassFileFilter =
+     *     MagicNumberFileFilter(new byte[] {(byte) 0xCA, (byte) 0xFE, 
+     *       (byte) 0xBA, (byte) 0xBE}); 
+     * 
+ * + * @param magicNumber the magic number to look for in the file. + * + * @throws IllegalArgumentException if magicNumber is + * null, or contains no bytes. + */ + public MagicNumberFileFilter(byte[] magicNumber) { + this(magicNumber, 0); + } + + /** + *

+ * Constructs a new MagicNumberFileFilter and associates it with the magic + * number to test for in files. This constructor assumes a starting offset + * of 0. + *

+ * + * Example usage: + *
+     * {@code
+     * MagicNumberFileFilter xmlFileFilter = 
+     *     MagicNumberFileFilter("
+     * 
+     * @param magicNumber the magic number to look for in the file.
+     *        The string is converted to bytes using the platform default charset.
+     *
+     * @throws IllegalArgumentException if magicNumber is 
+     *         null or the empty String.
+     */
+    public MagicNumberFileFilter(String magicNumber) {
+        this(magicNumber, 0);
+    }
+    
+    /**
+     * 

+ * Constructs a new MagicNumberFileFilter and associates it with the magic + * number to test for in files and the byte offset location in the file to + * to look for that magic number. + *

+ * + *
+     * MagicNumberFileFilter tarFileFilter = 
+     *     MagicNumberFileFilter("ustar", 257); 
+     * 
+ * + * @param magicNumber the magic number to look for in the file. + * The string is converted to bytes using the platform default charset. + * @param offset the byte offset in the file to start comparing bytes. + * + * @throws IllegalArgumentException if magicNumber is + * null or the empty String, or offset is + * a negative number. + */ + public MagicNumberFileFilter(String magicNumber, long offset) { + if (magicNumber == null) { + throw new IllegalArgumentException("The magic number cannot be null"); + } + if (magicNumber.length() == 0) { + throw new IllegalArgumentException("The magic number must contain at least one byte"); + } + if (offset < 0) { + throw new IllegalArgumentException("The offset cannot be negative"); + } + + this.magicNumbers = magicNumber.getBytes(); // uses the platform default charset + this.byteOffset = offset; + } + + /** + *

+ * Constructs a new MagicNumberFileFilter and associates it with the magic + * number to test for in files and the byte offset location in the file to + * to look for that magic number. + *

+ * + *

+ * It is important to note that the array is not cloned and that + * any changes to the magic number array after construction will affect the + * behavior of this file filter. + *

+ * + *
+     * MagicNumberFileFilter tarFileFilter =
+     *     MagicNumberFileFilter(new byte[] {0x75, 0x73, 0x74, 0x61, 0x72}, 257); 
+     * 
+ * + *
+     * MagicNumberFileFilter javaClassFileFilter =
+     *     MagicNumberFileFilter(new byte[] {0xCA, 0xFE, 0xBA, 0xBE}, 0); 
+     * 
+ * + * @param magicNumber the magic number to look for in the file. + * @param offset the byte offset in the file to start comparing bytes. + * + * @throws IllegalArgumentException if magicNumber is + * null, or contains no bytes, or offset + * is a negative number. + */ + public MagicNumberFileFilter(byte[] magicNumber, long offset) { + if (magicNumber == null) { + throw new IllegalArgumentException("The magic number cannot be null"); + } + if (magicNumber.length == 0) { + throw new IllegalArgumentException("The magic number must contain at least one byte"); + } + if (offset < 0) { + throw new IllegalArgumentException("The offset cannot be negative"); + } + + this.magicNumbers = new byte[magicNumber.length]; + System.arraycopy(magicNumber, 0, this.magicNumbers, 0, magicNumber.length); + this.byteOffset = offset; + } + + /** + *

+ * Accepts the provided file if the file contains the file filter's magic + * number at the specified offset. + *

+ * + *

+ * If any {@link IOException}s occur while reading the file, the file will + * be rejected. + *

+ * + * @param file the file to accept or reject. + * + * @return true if the file contains the filter's magic number + * at the specified offset, false otherwise. + */ + @Override + public boolean accept(File file) { + if (file != null && file.isFile() && file.canRead()) { + RandomAccessFile randomAccessFile = null; + try { + byte[] fileBytes = new byte[this.magicNumbers.length]; + randomAccessFile = new RandomAccessFile(file, "r"); + randomAccessFile.seek(byteOffset); + int read = randomAccessFile.read(fileBytes); + if (read != magicNumbers.length) { + return false; + } + return Arrays.equals(this.magicNumbers, fileBytes); + } catch (IOException ioe) { + // Do nothing, fall through and do not accept file + } finally { + IOUtils.closeQuietly(randomAccessFile); + } + } + + return false; + } + + /** + * Returns a String representation of the file filter, which includes the + * magic number bytes and byte offset. + * + * @return a String representation of the file filter. + */ + @Override + public String toString() { + StringBuilder builder = new StringBuilder(super.toString()); + builder.append("("); + builder.append(new String(magicNumbers));// TODO perhaps use hex if value is not printable + builder.append(","); + builder.append(this.byteOffset); + builder.append(")"); + return builder.toString(); + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/NameFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/NameFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/NameFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,197 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.util.List; + +import org.apache.commons.io.IOCase; + +/** + * Filters filenames for a certain name. + *

+ * For example, to print all files and directories in the + * current directory whose name is Test: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( new NameFileFilter("Test") );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + * @since Commons IO 1.0 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:02 $ + * + * @author Stephen Colebourne + * @author Federico Barbieri + * @author Serge Knystautas + * @author Peter Donald + * @see FileFilterUtils#nameFileFilter(String) + * @see FileFilterUtils#nameFileFilter(String, IOCase) + */ +public class NameFileFilter extends AbstractFileFilter implements Serializable { + + /** The filenames to search for */ + private final String[] names; + /** Whether the comparison is case sensitive. */ + private final IOCase caseSensitivity; + + /** + * Constructs a new case-sensitive name file filter for a single name. + * + * @param name the name to allow, must not be null + * @throws IllegalArgumentException if the name is null + */ + public NameFileFilter(String name) { + this(name, null); + } + + /** + * Construct a new name file filter specifying case-sensitivity. + * + * @param name the name to allow, must not be null + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the name is null + */ + public NameFileFilter(String name, IOCase caseSensitivity) { + if (name == null) { + throw new IllegalArgumentException("The wildcard must not be null"); + } + this.names = new String[] {name}; + this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity); + } + + /** + * Constructs a new case-sensitive name file filter for an array of names. + *

+ * The array is not cloned, so could be changed after constructing the + * instance. This would be inadvisable however. + * + * @param names the names to allow, must not be null + * @throws IllegalArgumentException if the names array is null + */ + public NameFileFilter(String[] names) { + this(names, null); + } + + /** + * Constructs a new name file filter for an array of names specifying case-sensitivity. + *

+ * The array is not cloned, so could be changed after constructing the + * instance. This would be inadvisable however. + * + * @param names the names to allow, must not be null + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the names array is null + */ + public NameFileFilter(String[] names, IOCase caseSensitivity) { + if (names == null) { + throw new IllegalArgumentException("The array of names must not be null"); + } + this.names = new String[names.length]; + System.arraycopy(names, 0, this.names, 0, names.length); + this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity); + } + + /** + * Constructs a new case-sensitive name file filter for a list of names. + * + * @param names the names to allow, must not be null + * @throws IllegalArgumentException if the name list is null + * @throws ClassCastException if the list does not contain Strings + */ + public NameFileFilter(List names) { + this(names, null); + } + + /** + * Constructs a new name file filter for a list of names specifying case-sensitivity. + * + * @param names the names to allow, must not be null + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the name list is null + * @throws ClassCastException if the list does not contain Strings + */ + public NameFileFilter(List names, IOCase caseSensitivity) { + if (names == null) { + throw new IllegalArgumentException("The list of names must not be null"); + } + this.names = names.toArray(new String[names.size()]); + this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity); + } + + //----------------------------------------------------------------------- + /** + * Checks to see if the filename matches. + * + * @param file the File to check + * @return true if the filename matches + */ + @Override + public boolean accept(File file) { + String name = file.getName(); + for (String name2 : this.names) { + if (caseSensitivity.checkEquals(name, name2)) { + return true; + } + } + return false; + } + + /** + * Checks to see if the filename matches. + * + * @param file the File directory + * @param name the filename + * @return true if the filename matches + */ + @Override + public boolean accept(File file, String name) { + for (String name2 : names) { + if (caseSensitivity.checkEquals(name, name2)) { + return true; + } + } + return false; + } + + /** + * Provide a String representaion of this file filter. + * + * @return a String representaion + */ + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append(super.toString()); + buffer.append("("); + if (names != null) { + for (int i = 0; i < names.length; i++) { + if (i > 0) { + buffer.append(","); + } + buffer.append(names[i]); + } + } + buffer.append(")"); + return buffer.toString(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/NotFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/NotFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/NotFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; + +/** + * This filter produces a logical NOT of the filters specified. + * + * @since Commons IO 1.0 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:02 $ + * + * @author Stephen Colebourne + * @see FileFilterUtils#notFileFilter(IOFileFilter) + */ +public class NotFileFilter extends AbstractFileFilter implements Serializable { + + /** The filter */ + private final IOFileFilter filter; + + /** + * Constructs a new file filter that NOTs the result of another filter. + * + * @param filter the filter, must not be null + * @throws IllegalArgumentException if the filter is null + */ + public NotFileFilter(IOFileFilter filter) { + if (filter == null) { + throw new IllegalArgumentException("The filter must not be null"); + } + this.filter = filter; + } + + /** + * Returns the logical NOT of the underlying filter's return value for the same File. + * + * @param file the File to check + * @return true if the filter returns false + */ + @Override + public boolean accept(File file) { + return ! filter.accept(file); + } + + /** + * Returns the logical NOT of the underlying filter's return value for the same arguments. + * + * @param file the File directory + * @param name the filename + * @return true if the filter returns false + */ + @Override + public boolean accept(File file, String name) { + return ! filter.accept(file, name); + } + + /** + * Provide a String representaion of this file filter. + * + * @return a String representaion + */ + @Override + public String toString() { + return super.toString() + "(" + filter.toString() + ")"; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/OrFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/OrFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/OrFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,163 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * A {@link java.io.FileFilter} providing conditional OR logic across a list of + * file filters. This filter returns true if any filters in the + * list return true. Otherwise, it returns false. + * Checking of the file filter list stops when the first filter returns + * true. + * + * @since Commons IO 1.0 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:02 $ + * + * @author Steven Caswell + * @see FileFilterUtils#or(IOFileFilter...) + */ +public class OrFileFilter + extends AbstractFileFilter + implements ConditionalFileFilter, Serializable { + + /** The list of file filters. */ + private final List fileFilters; + + /** + * Constructs a new instance of OrFileFilter. + * + * @since Commons IO 1.1 + */ + public OrFileFilter() { + this.fileFilters = new ArrayList(); + } + + /** + * Constructs a new instance of OrFileFilter + * with the specified filters. + * + * @param fileFilters the file filters for this filter, copied, null ignored + * @since Commons IO 1.1 + */ + public OrFileFilter(final List fileFilters) { + if (fileFilters == null) { + this.fileFilters = new ArrayList(); + } else { + this.fileFilters = new ArrayList(fileFilters); + } + } + + /** + * Constructs a new file filter that ORs the result of two other filters. + * + * @param filter1 the first filter, must not be null + * @param filter2 the second filter, must not be null + * @throws IllegalArgumentException if either filter is null + */ + public OrFileFilter(IOFileFilter filter1, IOFileFilter filter2) { + if (filter1 == null || filter2 == null) { + throw new IllegalArgumentException("The filters must not be null"); + } + this.fileFilters = new ArrayList(2); + addFileFilter(filter1); + addFileFilter(filter2); + } + + /** + * {@inheritDoc} + */ + public void addFileFilter(final IOFileFilter ioFileFilter) { + this.fileFilters.add(ioFileFilter); + } + + /** + * {@inheritDoc} + */ + public List getFileFilters() { + return Collections.unmodifiableList(this.fileFilters); + } + + /** + * {@inheritDoc} + */ + public boolean removeFileFilter(IOFileFilter ioFileFilter) { + return this.fileFilters.remove(ioFileFilter); + } + + /** + * {@inheritDoc} + */ + public void setFileFilters(final List fileFilters) { + this.fileFilters.clear(); + this.fileFilters.addAll(fileFilters); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean accept(final File file) { + for (IOFileFilter fileFilter : fileFilters) { + if (fileFilter.accept(file)) { + return true; + } + } + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean accept(final File file, final String name) { + for (IOFileFilter fileFilter : fileFilters) { + if (fileFilter.accept(file, name)) { + return true; + } + } + return false; + } + + /** + * Provide a String representaion of this file filter. + * + * @return a String representaion + */ + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append(super.toString()); + buffer.append("("); + if (fileFilters != null) { + for (int i = 0; i < fileFilters.size(); i++) { + if (i > 0) { + buffer.append(","); + } + Object filter = fileFilters.get(i); + buffer.append(filter == null ? "null" : filter.toString()); + } + } + buffer.append(")"); + return buffer.toString(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/PrefixFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/PrefixFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/PrefixFileFilter.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,203 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.util.List; + +import org.apache.commons.io.IOCase; + +/** + * Filters filenames for a certain prefix. + *

+ * For example, to print all files and directories in the + * current directory whose name starts with Test: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( new PrefixFileFilter("Test") );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + * @since Commons IO 1.0 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:01 $ + * + * @author Stephen Colebourne + * @author Federico Barbieri + * @author Serge Knystautas + * @author Peter Donald + * @see FileFilterUtils#prefixFileFilter(String) + * @see FileFilterUtils#prefixFileFilter(String, IOCase) + */ +public class PrefixFileFilter extends AbstractFileFilter implements Serializable { + + /** The filename prefixes to search for */ + private final String[] prefixes; + + /** Whether the comparison is case sensitive. */ + private final IOCase caseSensitivity; + + /** + * Constructs a new Prefix file filter for a single prefix. + * + * @param prefix the prefix to allow, must not be null + * @throws IllegalArgumentException if the prefix is null + */ + public PrefixFileFilter(String prefix) { + this(prefix, IOCase.SENSITIVE); + } + + /** + * Constructs a new Prefix file filter for a single prefix + * specifying case-sensitivity. + * + * @param prefix the prefix to allow, must not be null + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the prefix is null + * @since Commons IO 1.4 + */ + public PrefixFileFilter(String prefix, IOCase caseSensitivity) { + if (prefix == null) { + throw new IllegalArgumentException("The prefix must not be null"); + } + this.prefixes = new String[] {prefix}; + this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity); + } + + /** + * Constructs a new Prefix file filter for any of an array of prefixes. + *

+ * The array is not cloned, so could be changed after constructing the + * instance. This would be inadvisable however. + * + * @param prefixes the prefixes to allow, must not be null + * @throws IllegalArgumentException if the prefix array is null + */ + public PrefixFileFilter(String[] prefixes) { + this(prefixes, IOCase.SENSITIVE); + } + + /** + * Constructs a new Prefix file filter for any of an array of prefixes + * specifying case-sensitivity. + *

+ * The array is not cloned, so could be changed after constructing the + * instance. This would be inadvisable however. + * + * @param prefixes the prefixes to allow, must not be null + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the prefix is null + * @since Commons IO 1.4 + */ + public PrefixFileFilter(String[] prefixes, IOCase caseSensitivity) { + if (prefixes == null) { + throw new IllegalArgumentException("The array of prefixes must not be null"); + } + this.prefixes = new String[prefixes.length]; + System.arraycopy(prefixes, 0, this.prefixes, 0, prefixes.length); + this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity); + } + + /** + * Constructs a new Prefix file filter for a list of prefixes. + * + * @param prefixes the prefixes to allow, must not be null + * @throws IllegalArgumentException if the prefix list is null + * @throws ClassCastException if the list does not contain Strings + */ + public PrefixFileFilter(List prefixes) { + this(prefixes, IOCase.SENSITIVE); + } + + /** + * Constructs a new Prefix file filter for a list of prefixes + * specifying case-sensitivity. + * + * @param prefixes the prefixes to allow, must not be null + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the prefix list is null + * @throws ClassCastException if the list does not contain Strings + * @since Commons IO 1.4 + */ + public PrefixFileFilter(List prefixes, IOCase caseSensitivity) { + if (prefixes == null) { + throw new IllegalArgumentException("The list of prefixes must not be null"); + } + this.prefixes = prefixes.toArray(new String[prefixes.size()]); + this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity); + } + + /** + * Checks to see if the filename starts with the prefix. + * + * @param file the File to check + * @return true if the filename starts with one of our prefixes + */ + @Override + public boolean accept(File file) { + String name = file.getName(); + for (String prefix : this.prefixes) { + if (caseSensitivity.checkStartsWith(name, prefix)) { + return true; + } + } + return false; + } + + /** + * Checks to see if the filename starts with the prefix. + * + * @param file the File directory + * @param name the filename + * @return true if the filename starts with one of our prefixes + */ + @Override + public boolean accept(File file, String name) { + for (String prefix : prefixes) { + if (caseSensitivity.checkStartsWith(name, prefix)) { + return true; + } + } + return false; + } + + /** + * Provide a String representaion of this file filter. + * + * @return a String representaion + */ + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append(super.toString()); + buffer.append("("); + if (prefixes != null) { + for (int i = 0; i < prefixes.length; i++) { + if (i > 0) { + buffer.append(","); + } + buffer.append(prefixes[i]); + } + } + buffer.append(")"); + return buffer.toString(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/RegexFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/RegexFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/RegexFileFilter.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.util.regex.Pattern; + +import org.apache.commons.io.IOCase; + +/** + * Filters files using supplied regular expression(s). + *

+ * See java.util.regex.Pattern for regex matching rules + *

+ * + *

+ * e.g. + *

+ * File dir = new File(".");
+ * FileFilter fileFilter = new RegexFileFilter("^.*[tT]est(-\\d+)?\\.java$");
+ * File[] files = dir.listFiles(fileFilter);
+ * for (int i = 0; i < files.length; i++) {
+ *   System.out.println(files[i]);
+ * }
+ * 
+ * + * @author Oliver Siegmar + * @version $Revision: 1.1 $ + * @since Commons IO 1.4 + */ +public class RegexFileFilter extends AbstractFileFilter implements Serializable { + + /** The regular expression pattern that will be used to match filenames */ + private final Pattern pattern; + + /** + * Construct a new regular expression filter. + * + * @param pattern regular string expression to match + * @throws IllegalArgumentException if the pattern is null + */ + public RegexFileFilter(String pattern) { + if (pattern == null) { + throw new IllegalArgumentException("Pattern is missing"); + } + + this.pattern = Pattern.compile(pattern); + } + + /** + * Construct a new regular expression filter with the specified flags case sensitivity. + * + * @param pattern regular string expression to match + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the pattern is null + */ + public RegexFileFilter(String pattern, IOCase caseSensitivity) { + if (pattern == null) { + throw new IllegalArgumentException("Pattern is missing"); + } + int flags = 0; + if (caseSensitivity != null && !caseSensitivity.isCaseSensitive()) { + flags = Pattern.CASE_INSENSITIVE; + } + this.pattern = Pattern.compile(pattern, flags); + } + + /** + * Construct a new regular expression filter with the specified flags. + * + * @param pattern regular string expression to match + * @param flags pattern flags - e.g. {@link Pattern#CASE_INSENSITIVE} + * @throws IllegalArgumentException if the pattern is null + */ + public RegexFileFilter(String pattern, int flags) { + if (pattern == null) { + throw new IllegalArgumentException("Pattern is missing"); + } + this.pattern = Pattern.compile(pattern, flags); + } + + /** + * Construct a new regular expression filter for a compiled regular expression + * + * @param pattern regular expression to match + * @throws IllegalArgumentException if the pattern is null + */ + public RegexFileFilter(Pattern pattern) { + if (pattern == null) { + throw new IllegalArgumentException("Pattern is missing"); + } + + this.pattern = pattern; + } + + /** + * Checks to see if the filename matches one of the regular expressions. + * + * @param dir the file directory + * @param name the filename + * @return true if the filename matches one of the regular expressions + */ + @Override + public boolean accept(File dir, String name) { + return (pattern.matcher(name).matches()); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/SizeFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/SizeFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/SizeFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; + +/** + * Filters files based on size, can filter either smaller files or + * files equal to or larger than a given threshold. + *

+ * For example, to print all files and directories in the + * current directory whose size is greater than 1 MB: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( new SizeFileFilter(1024 * 1024) );
+ * for ( int i = 0; i < files.length; i++ ) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + * @author Rahul Akolkar + * @version $Id: SizeFileFilter.java,v 1.1 2012/10/01 13:03:02 marcin Exp $ + * @since Commons IO 1.2 + * @see FileFilterUtils#sizeFileFilter(long) + * @see FileFilterUtils#sizeFileFilter(long, boolean) + * @see FileFilterUtils#sizeRangeFileFilter(long, long) + */ +public class SizeFileFilter extends AbstractFileFilter implements Serializable { + + /** The size threshold. */ + private final long size; + /** Whether the files accepted will be larger or smaller. */ + private final boolean acceptLarger; + + /** + * Constructs a new size file filter for files equal to or + * larger than a certain size. + * + * @param size the threshold size of the files + * @throws IllegalArgumentException if the size is negative + */ + public SizeFileFilter(long size) { + this(size, true); + } + + /** + * Constructs a new size file filter for files based on a certain size + * threshold. + * + * @param size the threshold size of the files + * @param acceptLarger if true, files equal to or larger are accepted, + * otherwise smaller ones (but not equal to) + * @throws IllegalArgumentException if the size is negative + */ + public SizeFileFilter(long size, boolean acceptLarger) { + if (size < 0) { + throw new IllegalArgumentException("The size must be non-negative"); + } + this.size = size; + this.acceptLarger = acceptLarger; + } + + //----------------------------------------------------------------------- + /** + * Checks to see if the size of the file is favorable. + *

+ * If size equals threshold and smaller files are required, + * file IS NOT selected. + * If size equals threshold and larger files are required, + * file IS selected. + * + * @param file the File to check + * @return true if the filename matches + */ + @Override + public boolean accept(File file) { + boolean smaller = file.length() < size; + return acceptLarger ? !smaller : smaller; + } + + /** + * Provide a String representaion of this file filter. + * + * @return a String representaion + */ + @Override + public String toString() { + String condition = acceptLarger ? ">=" : "<"; + return super.toString() + "(" + condition + size + ")"; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/SuffixFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/SuffixFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/SuffixFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.util.List; + +import org.apache.commons.io.IOCase; + +/** + * Filters files based on the suffix (what the filename ends with). + * This is used in retrieving all the files of a particular type. + *

+ * For example, to retrieve and print all *.java files + * in the current directory: + * + *

+ * File dir = new File(".");
+ * String[] files = dir.list( new SuffixFileFilter(".java") );
+ * for (int i = 0; i < files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * 
+ * + * @since Commons IO 1.0 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:02 $ + * + * @author Stephen Colebourne + * @author Federico Barbieri + * @author Serge Knystautas + * @author Peter Donald + * @see FileFilterUtils#suffixFileFilter(String) + * @see FileFilterUtils#suffixFileFilter(String, IOCase) + */ +public class SuffixFileFilter extends AbstractFileFilter implements Serializable { + + /** The filename suffixes to search for */ + private final String[] suffixes; + + /** Whether the comparison is case sensitive. */ + private final IOCase caseSensitivity; + + /** + * Constructs a new Suffix file filter for a single extension. + * + * @param suffix the suffix to allow, must not be null + * @throws IllegalArgumentException if the suffix is null + */ + public SuffixFileFilter(String suffix) { + this(suffix, IOCase.SENSITIVE); + } + + /** + * Constructs a new Suffix file filter for a single extension + * specifying case-sensitivity. + * + * @param suffix the suffix to allow, must not be null + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the suffix is null + * @since Commons IO 1.4 + */ + public SuffixFileFilter(String suffix, IOCase caseSensitivity) { + if (suffix == null) { + throw new IllegalArgumentException("The suffix must not be null"); + } + this.suffixes = new String[] {suffix}; + this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity); + } + + /** + * Constructs a new Suffix file filter for an array of suffixs. + *

+ * The array is not cloned, so could be changed after constructing the + * instance. This would be inadvisable however. + * + * @param suffixes the suffixes to allow, must not be null + * @throws IllegalArgumentException if the suffix array is null + */ + public SuffixFileFilter(String[] suffixes) { + this(suffixes, IOCase.SENSITIVE); + } + + /** + * Constructs a new Suffix file filter for an array of suffixs + * specifying case-sensitivity. + *

+ * The array is not cloned, so could be changed after constructing the + * instance. This would be inadvisable however. + * + * @param suffixes the suffixes to allow, must not be null + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the suffix array is null + * @since Commons IO 1.4 + */ + public SuffixFileFilter(String[] suffixes, IOCase caseSensitivity) { + if (suffixes == null) { + throw new IllegalArgumentException("The array of suffixes must not be null"); + } + this.suffixes = new String[suffixes.length]; + System.arraycopy(suffixes, 0, this.suffixes, 0, suffixes.length); + this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity); + } + + /** + * Constructs a new Suffix file filter for a list of suffixes. + * + * @param suffixes the suffixes to allow, must not be null + * @throws IllegalArgumentException if the suffix list is null + * @throws ClassCastException if the list does not contain Strings + */ + public SuffixFileFilter(List suffixes) { + this(suffixes, IOCase.SENSITIVE); + } + + /** + * Constructs a new Suffix file filter for a list of suffixes + * specifying case-sensitivity. + * + * @param suffixes the suffixes to allow, must not be null + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the suffix list is null + * @throws ClassCastException if the list does not contain Strings + * @since Commons IO 1.4 + */ + public SuffixFileFilter(List suffixes, IOCase caseSensitivity) { + if (suffixes == null) { + throw new IllegalArgumentException("The list of suffixes must not be null"); + } + this.suffixes = suffixes.toArray(new String[suffixes.size()]); + this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity); + } + + /** + * Checks to see if the filename ends with the suffix. + * + * @param file the File to check + * @return true if the filename ends with one of our suffixes + */ + @Override + public boolean accept(File file) { + String name = file.getName(); + for (String suffix : this.suffixes) { + if (caseSensitivity.checkEndsWith(name, suffix)) { + return true; + } + } + return false; + } + + /** + * Checks to see if the filename ends with the suffix. + * + * @param file the File directory + * @param name the filename + * @return true if the filename ends with one of our suffixes + */ + @Override + public boolean accept(File file, String name) { + for (String suffix : this.suffixes) { + if (caseSensitivity.checkEndsWith(name, suffix)) { + return true; + } + } + return false; + } + + /** + * Provide a String representaion of this file filter. + * + * @return a String representaion + */ + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append(super.toString()); + buffer.append("("); + if (suffixes != null) { + for (int i = 0; i < suffixes.length; i++) { + if (i > 0) { + buffer.append(","); + } + buffer.append(suffixes[i]); + } + } + buffer.append(")"); + return buffer.toString(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/TrueFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/TrueFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/TrueFileFilter.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; + +/** + * A file filter that always returns true. + * + * @since Commons IO 1.0 + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:01 $ + * + * @author Stephen Colebourne + * @see FileFilterUtils#trueFileFilter() + */ +public class TrueFileFilter implements IOFileFilter, Serializable { + + /** + * Singleton instance of true filter. + * @since Commons IO 1.3 + */ + public static final IOFileFilter TRUE = new TrueFileFilter(); + /** + * Singleton instance of true filter. + * Please use the identical TrueFileFilter.TRUE constant. + * The new name is more JDK 1.5 friendly as it doesn't clash with other + * values when using static imports. + */ + public static final IOFileFilter INSTANCE = TRUE; + + /** + * Restrictive consructor. + */ + protected TrueFileFilter() { + } + + /** + * Returns true. + * + * @param file the file to check + * @return true + */ + public boolean accept(File file) { + return true; + } + + /** + * Returns true. + * + * @param dir the directory to check + * @param name the filename + * @return true + */ + public boolean accept(File dir, String name) { + return true; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/WildcardFileFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/WildcardFileFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/WildcardFileFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,200 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.util.List; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOCase; + +/** + * Filters files using the supplied wildcards. + *

+ * This filter selects files and directories based on one or more wildcards. + * Testing is case-sensitive by default, but this can be configured. + *

+ * The wildcard matcher uses the characters '?' and '*' to represent a + * single or multiple wildcard characters. + * This is the same as often found on Dos/Unix command lines. + * The extension check is case-sensitive by . + * See {@link FilenameUtils#wildcardMatchOnSystem} for more information. + *

+ * For example: + *

+ * File dir = new File(".");
+ * FileFilter fileFilter = new WildcardFileFilter("*test*.java~*~");
+ * File[] files = dir.listFiles(fileFilter);
+ * for (int i = 0; i < files.length; i++) {
+ *   System.out.println(files[i]);
+ * }
+ * 
+ * + * @author Jason Anderson + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:02 $ + * @since Commons IO 1.3 + */ +public class WildcardFileFilter extends AbstractFileFilter implements Serializable { + + /** The wildcards that will be used to match filenames. */ + private final String[] wildcards; + /** Whether the comparison is case sensitive. */ + private final IOCase caseSensitivity; + + /** + * Construct a new case-sensitive wildcard filter for a single wildcard. + * + * @param wildcard the wildcard to match + * @throws IllegalArgumentException if the pattern is null + */ + public WildcardFileFilter(String wildcard) { + this(wildcard, null); + } + + /** + * Construct a new wildcard filter for a single wildcard specifying case-sensitivity. + * + * @param wildcard the wildcard to match, not null + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the pattern is null + */ + public WildcardFileFilter(String wildcard, IOCase caseSensitivity) { + if (wildcard == null) { + throw new IllegalArgumentException("The wildcard must not be null"); + } + this.wildcards = new String[] { wildcard }; + this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity); + } + + /** + * Construct a new case-sensitive wildcard filter for an array of wildcards. + *

+ * The array is not cloned, so could be changed after constructing the + * instance. This would be inadvisable however. + * + * @param wildcards the array of wildcards to match + * @throws IllegalArgumentException if the pattern array is null + */ + public WildcardFileFilter(String[] wildcards) { + this(wildcards, null); + } + + /** + * Construct a new wildcard filter for an array of wildcards specifying case-sensitivity. + *

+ * The array is not cloned, so could be changed after constructing the + * instance. This would be inadvisable however. + * + * @param wildcards the array of wildcards to match, not null + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the pattern array is null + */ + public WildcardFileFilter(String[] wildcards, IOCase caseSensitivity) { + if (wildcards == null) { + throw new IllegalArgumentException("The wildcard array must not be null"); + } + this.wildcards = new String[wildcards.length]; + System.arraycopy(wildcards, 0, this.wildcards, 0, wildcards.length); + this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity); + } + + /** + * Construct a new case-sensitive wildcard filter for a list of wildcards. + * + * @param wildcards the list of wildcards to match, not null + * @throws IllegalArgumentException if the pattern list is null + * @throws ClassCastException if the list does not contain Strings + */ + public WildcardFileFilter(List wildcards) { + this(wildcards, null); + } + + /** + * Construct a new wildcard filter for a list of wildcards specifying case-sensitivity. + * + * @param wildcards the list of wildcards to match, not null + * @param caseSensitivity how to handle case sensitivity, null means case-sensitive + * @throws IllegalArgumentException if the pattern list is null + * @throws ClassCastException if the list does not contain Strings + */ + public WildcardFileFilter(List wildcards, IOCase caseSensitivity) { + if (wildcards == null) { + throw new IllegalArgumentException("The wildcard list must not be null"); + } + this.wildcards = wildcards.toArray(new String[wildcards.size()]); + this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity); + } + + //----------------------------------------------------------------------- + /** + * Checks to see if the filename matches one of the wildcards. + * + * @param dir the file directory + * @param name the filename + * @return true if the filename matches one of the wildcards + */ + @Override + public boolean accept(File dir, String name) { + for (String wildcard : wildcards) { + if (FilenameUtils.wildcardMatch(name, wildcard, caseSensitivity)) { + return true; + } + } + return false; + } + + /** + * Checks to see if the filename matches one of the wildcards. + * + * @param file the file to check + * @return true if the filename matches one of the wildcards + */ + @Override + public boolean accept(File file) { + String name = file.getName(); + for (String wildcard : wildcards) { + if (FilenameUtils.wildcardMatch(name, wildcard, caseSensitivity)) { + return true; + } + } + return false; + } + + /** + * Provide a String representaion of this file filter. + * + * @return a String representaion + */ + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append(super.toString()); + buffer.append("("); + if (wildcards != null) { + for (int i = 0; i < wildcards.length; i++) { + if (i > 0) { + buffer.append(","); + } + buffer.append(wildcards[i]); + } + } + buffer.append(")"); + return buffer.toString(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/WildcardFilter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/WildcardFilter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/WildcardFilter.java 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.io.Serializable; +import java.util.List; + +import org.apache.commons.io.FilenameUtils; + +/** + * Filters files using the supplied wildcards. + *

+ * This filter selects files, but not directories, based on one or more wildcards + * and using case-sensitive comparison. + *

+ * The wildcard matcher uses the characters '?' and '*' to represent a + * single or multiple wildcard characters. + * This is the same as often found on Dos/Unix command lines. + * The extension check is case-sensitive. + * See {@link FilenameUtils#wildcardMatch(String, String)} for more information. + *

+ * For example: + *

+ * File dir = new File(".");
+ * FileFilter fileFilter = new WildcardFilter("*test*.java~*~");
+ * File[] files = dir.listFiles(fileFilter);
+ * for (int i = 0; i < files.length; i++) {
+ *   System.out.println(files[i]);
+ * }
+ * 
+ * + * @author Jason Anderson + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:02 $ + * @since Commons IO 1.1 + * @deprecated Use WilcardFileFilter. Deprecated as this class performs directory + * filtering which it shouldn't do, but that can't be removed due to compatability. + */ +@Deprecated +public class WildcardFilter extends AbstractFileFilter implements Serializable { + + /** The wildcards that will be used to match filenames. */ + private final String[] wildcards; + + /** + * Construct a new case-sensitive wildcard filter for a single wildcard. + * + * @param wildcard the wildcard to match + * @throws IllegalArgumentException if the pattern is null + */ + public WildcardFilter(String wildcard) { + if (wildcard == null) { + throw new IllegalArgumentException("The wildcard must not be null"); + } + this.wildcards = new String[] { wildcard }; + } + + /** + * Construct a new case-sensitive wildcard filter for an array of wildcards. + * + * @param wildcards the array of wildcards to match + * @throws IllegalArgumentException if the pattern array is null + */ + public WildcardFilter(String[] wildcards) { + if (wildcards == null) { + throw new IllegalArgumentException("The wildcard array must not be null"); + } + this.wildcards = new String[wildcards.length]; + System.arraycopy(wildcards, 0, this.wildcards, 0, wildcards.length); + } + + /** + * Construct a new case-sensitive wildcard filter for a list of wildcards. + * + * @param wildcards the list of wildcards to match + * @throws IllegalArgumentException if the pattern list is null + * @throws ClassCastException if the list does not contain Strings + */ + public WildcardFilter(List wildcards) { + if (wildcards == null) { + throw new IllegalArgumentException("The wildcard list must not be null"); + } + this.wildcards = wildcards.toArray(new String[wildcards.size()]); + } + + //----------------------------------------------------------------------- + /** + * Checks to see if the filename matches one of the wildcards. + * + * @param dir the file directory + * @param name the filename + * @return true if the filename matches one of the wildcards + */ + @Override + public boolean accept(File dir, String name) { + if (dir != null && new File(dir, name).isDirectory()) { + return false; + } + + for (String wildcard : wildcards) { + if (FilenameUtils.wildcardMatch(name, wildcard)) { + return true; + } + } + + return false; + } + + /** + * Checks to see if the filename matches one of the wildcards. + * + * @param file the file to check + * @return true if the filename matches one of the wildcards + */ + @Override + public boolean accept(File file) { + if (file.isDirectory()) { + return false; + } + + for (String wildcard : wildcards) { + if (FilenameUtils.wildcardMatch(file.getName(), wildcard)) { + return true; + } + } + + return false; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/filefilter/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/package.html 1 Oct 2012 13:03:02 -0000 1.1 @@ -0,0 +1,143 @@ + + + + +

This package defines an interface (IOFileFilter) that combines both +{@link java.io.FileFilter} and {@link java.io.FilenameFilter}. Besides +that the package offers a series of ready-to-use implementations of the +IOFileFilter interface including implementation that allow you to combine +other such filters.

+

These filter can be used to list files or in {@link java.awt.FileDialog}, +for example.

+ +

There are a number of 'primitive' filters:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DirectoryFilterOnly accept directories
PrefixFileFilterFilter based on a prefix
SuffixFileFilterFilter based on a suffix
NameFileFilterFilter based on a filename
WildcardFileFilterFilter based on wildcards
AgeFileFilterFilter based on last modified time of file
SizeFileFilterFilter based on file size
+ +

And there are five 'boolean' filters:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
TrueFileFilterAccept all files
FalseFileFilterAccept no files
NotFileFilterApplies a logical NOT to an existing filter
AndFileFilterCombines two filters using a logical AND
OrFileFilterCombines two filter using a logical OR
+ +

These boolean FilenameFilters can be nested, to allow arbitrary expressions. +For example, here is how one could print all non-directory files in the +current directory, starting with "A", and ending in ".java" or ".class":

+ +
+  File dir = new File(".");
+  String[] files = dir.list( 
+    new AndFileFilter(
+      new AndFileFilter(
+        new PrefixFileFilter("A"),
+        new OrFileFilter(
+          new SuffixFileFilter(".class"),
+          new SuffixFileFilter(".java")
+        )
+      ),
+      new NotFileFilter(
+        new DirectoryFileFilter()
+      )
+    )
+  );
+  for ( int i=0; i<files.length; i++ ) {
+    System.out.println(files[i]);
+  }
+
+ +

This package also contains a utility class: +FileFilterUtils. It allows you to use all +file filters without having to put them in the import section. Here's how the +above example will look using FileFilterUtils:

+
+  File dir = new File(".");
+  String[] files = dir.list( 
+    FileFilterUtils.andFileFilter(
+      FileFilterUtils.andFileFilter(
+        FileFilterUtils.prefixFileFilter("A"),
+        FileFilterUtils.orFileFilter(
+          FileFilterUtils.suffixFileFilter(".class"),
+          FileFilterUtils.suffixFileFilter(".java")
+        )
+      ),
+      FileFilterUtils.notFileFilter(
+        FileFilterUtils.directoryFileFilter()
+      )
+    )
+  );
+  for ( int i=0; i<files.length; i++ ) {
+    System.out.println(files[i]);
+  }
+
+

There are a few other goodies in that class so please have a look at the +documentation in detail.

+ + Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/AutoCloseInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/AutoCloseInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/AutoCloseInputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Proxy stream that closes and discards the underlying stream as soon as the + * end of input has been reached or when the stream is explicitly closed. + * Not even a reference to the underlying stream is kept after it has been + * closed, so any allocated in-memory buffers can be freed even if the + * client application still keeps a reference to the proxy stream. + *

+ * This class is typically used to release any resources related to an open + * stream as soon as possible even if the client application (by not explicitly + * closing the stream when no longer needed) or the underlying stream (by not + * releasing resources once the last byte has been read) do not do that. + * + * @version $Id: AutoCloseInputStream.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + * @since Commons IO 1.4 + */ +public class AutoCloseInputStream extends ProxyInputStream { + + /** + * Creates an automatically closing proxy for the given input stream. + * + * @param in underlying input stream + */ + public AutoCloseInputStream(InputStream in) { + super(in); + } + + /** + * Closes the underlying input stream and replaces the reference to it + * with a {@link ClosedInputStream} instance. + *

+ * This method is automatically called by the read methods when the end + * of input has been reached. + *

+ * Note that it is safe to call this method any number of times. The original + * underlying input stream is closed and discarded only once when this + * method is first called. + * + * @throws IOException if the underlying input stream can not be closed + */ + @Override + public void close() throws IOException { + in.close(); + in = new ClosedInputStream(); + } + + /** + * Automatically closes the stream if the end of stream was reached. + * + * @param n number of bytes read, or -1 if no more bytes are available + * @throws IOException if the stream could not be closed + * @since Commons IO 2.0 + */ + @Override + protected void afterRead(int n) throws IOException { + if (n == -1) { + close(); + } + } + + /** + * Ensures that the stream is closed before it gets garbage-collected. + * As mentioned in {@link #close()}, this is a no-op if the stream has + * already been closed. + * @throws Throwable if an error occurs + */ + @Override + protected void finalize() throws Throwable { + close(); + super.finalize(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/BOMInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/BOMInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/BOMInputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,342 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.io.ByteOrderMark; + +/** + * This class is used to wrap a stream that includes an encoded + * {@link ByteOrderMark} as its first bytes. + * + * This class detects these bytes and, if required, can automatically skip them + * and return the subsequent byte as the first byte in the stream. + * + * The {@link ByteOrderMark} implementation has the following pre-defined BOMs: + *

    + *
  • UTF-8 - {@link ByteOrderMark#UTF_8}
  • + *
  • UTF-16BE - {@link ByteOrderMark#UTF_16LE}
  • + *
  • UTF-16LE - {@link ByteOrderMark#UTF_16BE}
  • + *
+ * + * + *

Example 1 - Detect and exclude a UTF-8 BOM

+ *
+ *      BOMInputStream bomIn = new BOMInputStream(in);
+ *      if (bomIn.hasBOM()) {
+ *          // has a UTF-8 BOM
+ *      }
+ * 
+ * + *

Example 2 - Detect a UTF-8 BOM (but don't exclude it)

+ *
+ *      boolean include = true;
+ *      BOMInputStream bomIn = new BOMInputStream(in, include);
+ *      if (bomIn.hasBOM()) {
+ *          // has a UTF-8 BOM
+ *      }
+ * 
+ * + *

Example 3 - Detect Multiple BOMs

+ *
+ *      BOMInputStream bomIn = new BOMInputStream(in, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE);
+ *      if (bomIn.hasBOM() == false) {
+ *          // No BOM found
+ *      } else if (bomIn.hasBOM(ByteOrderMark.UTF_16LE)) {
+ *          // has a UTF-16LE BOM
+ *      } else if (bomIn.hasBOM(ByteOrderMark.UTF_16BE)) {
+ *          // has a UTF-16BE BOM
+ *      }
+ * 
+ * + * @see org.apache.commons.io.ByteOrderMark + * @see Wikipedia - Byte Order Mark + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:00 $ + * @since Commons IO 2.0 + */ +public class BOMInputStream extends ProxyInputStream { + private final boolean include; + private final List boms; + private ByteOrderMark byteOrderMark; + private int[] firstBytes; + private int fbLength; + private int fbIndex; + private int markFbIndex; + private boolean markedAtStart; + + /** + * Constructs a new BOM InputStream that excludes + * a {@link ByteOrderMark#UTF_8} BOM. + * @param delegate the InputStream to delegate to + */ + public BOMInputStream(InputStream delegate) { + this(delegate, false, ByteOrderMark.UTF_8); + } + + /** + * Constructs a new BOM InputStream that detects a + * a {@link ByteOrderMark#UTF_8} and optionally includes it. + * @param delegate the InputStream to delegate to + * @param include true to include the UTF-8 BOM or + * false to exclude it + */ + public BOMInputStream(InputStream delegate, boolean include) { + this(delegate, include, ByteOrderMark.UTF_8); + } + + /** + * Constructs a new BOM InputStream that excludes + * the specified BOMs. + * @param delegate the InputStream to delegate to + * @param boms The BOMs to detect and exclude + */ + public BOMInputStream(InputStream delegate, ByteOrderMark... boms) { + this(delegate, false, boms); + } + + /** + * Constructs a new BOM InputStream that detects the + * specified BOMs and optionally includes them. + * @param delegate the InputStream to delegate to + * @param include true to include the specified BOMs or + * false to exclude them + * @param boms The BOMs to detect and optionally exclude + */ + public BOMInputStream(InputStream delegate, boolean include, ByteOrderMark... boms) { + super(delegate); + if (boms == null || boms.length == 0) { + throw new IllegalArgumentException("No BOMs specified"); + } + this.include = include; + this.boms = Arrays.asList(boms); + } + + /** + * Indicates whether the stream contains one of the specified BOMs. + * + * @return true if the stream has one of the specified BOMs, otherwise false + * if it does not + * @throws IOException if an error reading the first bytes of the stream occurs + */ + public boolean hasBOM() throws IOException { + return (getBOM() != null); + } + + /** + * Indicates whether the stream contains the specified BOM. + * + * @param bom The BOM to check for + * @return true if the stream has the specified BOM, otherwise false + * if it does not + * @throws IllegalArgumentException if the BOM is not one the stream + * is configured to detect + * @throws IOException if an error reading the first bytes of the stream occurs + */ + public boolean hasBOM(ByteOrderMark bom) throws IOException { + if (!boms.contains(bom)) { + throw new IllegalArgumentException("Stream not configure to detect " + bom); + } + return (byteOrderMark != null && getBOM().equals(bom)); + } + + /** + * Return the BOM (Byte Order Mark). + * + * @return The BOM or null if none + * @throws IOException if an error reading the first bytes of the stream occurs + */ + public ByteOrderMark getBOM() throws IOException { + if (firstBytes == null) { + int max = 0; + for (ByteOrderMark bom : boms) { + max = Math.max(max, bom.length()); + } + firstBytes = new int[max]; + for (int i = 0; i < firstBytes.length; i++) { + firstBytes[i] = in.read(); + fbLength++; + if (firstBytes[i] < 0) { + break; + } + + byteOrderMark = find(); + if (byteOrderMark != null) { + if (!include) { + fbLength = 0; + } + break; + } + } + } + return byteOrderMark; + } + + /** + * Return the BOM charset Name - {@link ByteOrderMark#getCharsetName()}. + * + * @return The BOM charset Name or null if no BOM found + * @throws IOException if an error reading the first bytes of the stream occurs + * + */ + public String getBOMCharsetName() throws IOException { + getBOM(); + return (byteOrderMark == null ? null : byteOrderMark.getCharsetName()); + } + + /** + * This method reads and either preserves or skips the first bytes in the + * stream. It behaves like the single-byte read() method, + * either returning a valid byte or -1 to indicate that the initial bytes + * have been processed already. + * @return the byte read (excluding BOM) or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + private int readFirstBytes() throws IOException { + getBOM(); + return (fbIndex < fbLength) ? firstBytes[fbIndex++] : -1; + } + + /** + * Find a BOM with the specified bytes. + * + * @return The matched BOM or null if none matched + */ + private ByteOrderMark find() { + for (ByteOrderMark bom : boms) { + if (matches(bom)) { + return bom; + } + } + return null; + } + + /** + * Check if the bytes match a BOM. + * + * @param bom The BOM + * @return true if the bytes match the bom, otherwise false + */ + private boolean matches(ByteOrderMark bom) { + if (bom.length() != fbLength) { + return false; + } + for (int i = 0; i < bom.length(); i++) { + if (bom.get(i) != firstBytes[i]) { + return false; + } + } + return true; + } + + //---------------------------------------------------------------------------- + // Implementation of InputStream + //---------------------------------------------------------------------------- + + /** + * Invokes the delegate's read() method, detecting and + * optionally skipping BOM. + * @return the byte read (excluding BOM) or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + @Override + public int read() throws IOException { + int b = readFirstBytes(); + return (b >= 0) ? b : in.read(); + } + + /** + * Invokes the delegate's read(byte[], int, int) method, detecting + * and optionally skipping BOM. + * @param buf the buffer to read the bytes into + * @param off The start offset + * @param len The number of bytes to read (excluding BOM) + * @return the number of bytes read or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + @Override + public int read(byte[] buf, int off, int len) throws IOException { + int firstCount = 0; + int b = 0; + while ((len > 0) && (b >= 0)) { + b = readFirstBytes(); + if (b >= 0) { + buf[off++] = (byte) (b & 0xFF); + len--; + firstCount++; + } + } + int secondCount = in.read(buf, off, len); + return (secondCount < 0) ? (firstCount > 0 ? firstCount : -1) : firstCount + secondCount; + } + + /** + * Invokes the delegate's read(byte[]) method, detecting and + * optionally skipping BOM. + * @param buf the buffer to read the bytes into + * @return the number of bytes read (excluding BOM) + * or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + @Override + public int read(byte[] buf) throws IOException { + return read(buf, 0, buf.length); + } + + /** + * Invokes the delegate's mark(int) method. + * @param readlimit read ahead limit + */ + @Override + public synchronized void mark(int readlimit) { + markFbIndex = fbIndex; + markedAtStart = (firstBytes == null); + in.mark(readlimit); + } + + /** + * Invokes the delegate's reset() method. + * @throws IOException if an I/O error occurs + */ + @Override + public synchronized void reset() throws IOException { + fbIndex = markFbIndex; + if (markedAtStart) { + firstBytes = null; + } + + in.reset(); + } + + /** + * Invokes the delegate's skip(long) method, detecting + * and optionallyskipping BOM. + * @param n the number of bytes to skip + * @return the number of bytes to skipped or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + @Override + public long skip(long n) throws IOException { + while ((n > 0) && (readFirstBytes() >= 0)) { + n--; + } + return in.skip(n); + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/BoundedInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/BoundedInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/BoundedInputStream.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,230 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.IOException; +import java.io.InputStream; + +/** + * This is a stream that will only supply bytes up to a certain length - if its + * position goes above that, it will stop. + *

+ * This is useful to wrap ServletInputStreams. The ServletInputStream will block + * if you try to read content from it that isn't there, because it doesn't know + * whether the content hasn't arrived yet or whether the content has finished. + * So, one of these, initialized with the Content-length sent in the + * ServletInputStream's header, will stop it blocking, providing it's been sent + * with a correct content length. + * + * @version $Id: BoundedInputStream.java,v 1.1 2012/10/01 13:03:01 marcin Exp $ + * @since Commons IO 2.0 + */ +public class BoundedInputStream extends InputStream { + + /** the wrapped input stream */ + private final InputStream in; + + /** the max length to provide */ + private final long max; + + /** the number of bytes already returned */ + private long pos = 0; + + /** the marked position */ + private long mark = -1; + + /** flag if close shoud be propagated */ + private boolean propagateClose = true; + + /** + * Creates a new BoundedInputStream that wraps the given input + * stream and limits it to a certain size. + * + * @param in The wrapped input stream + * @param size The maximum number of bytes to return + */ + public BoundedInputStream(InputStream in, long size) { + // Some badly designed methods - eg the servlet API - overload length + // such that "-1" means stream finished + this.max = size; + this.in = in; + } + + /** + * Creates a new BoundedInputStream that wraps the given input + * stream and is unlimited. + * + * @param in The wrapped input stream + */ + public BoundedInputStream(InputStream in) { + this(in, -1); + } + + /** + * Invokes the delegate's read() method if + * the current position is less than the limit. + * @return the byte read or -1 if the end of stream or + * the limit has been reached. + * @throws IOException if an I/O error occurs + */ + @Override + public int read() throws IOException { + if (max>=0 && pos==max) { + return -1; + } + int result = in.read(); + pos++; + return result; + } + + /** + * Invokes the delegate's read(byte[]) method. + * @param b the buffer to read the bytes into + * @return the number of bytes read or -1 if the end of stream or + * the limit has been reached. + * @throws IOException if an I/O error occurs + */ + @Override + public int read(byte[] b) throws IOException { + return this.read(b, 0, b.length); + } + + /** + * Invokes the delegate's read(byte[], int, int) method. + * @param b the buffer to read the bytes into + * @param off The start offset + * @param len The number of bytes to read + * @return the number of bytes read or -1 if the end of stream or + * the limit has been reached. + * @throws IOException if an I/O error occurs + */ + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (max>=0 && pos>=max) { + return -1; + } + long maxRead = max>=0 ? Math.min(len, max-pos) : len; + int bytesRead = in.read(b, off, (int)maxRead); + + if (bytesRead==-1) { + return -1; + } + + pos+=bytesRead; + return bytesRead; + } + + /** + * Invokes the delegate's skip(long) method. + * @param n the number of bytes to skip + * @return the actual number of bytes skipped + * @throws IOException if an I/O error occurs + */ + @Override + public long skip(long n) throws IOException { + long toSkip = max>=0 ? Math.min(n, max-pos) : n; + long skippedBytes = in.skip(toSkip); + pos+=skippedBytes; + return skippedBytes; + } + + /** + * {@inheritDoc} + */ + @Override + public int available() throws IOException { + if (max>=0 && pos>=max) { + return 0; + } + return in.available(); + } + + /** + * Invokes the delegate's toString() method. + * @return the delegate's toString() + */ + @Override + public String toString() { + return in.toString(); + } + + /** + * Invokes the delegate's close() method + * if {@link #isPropagateClose()} is true. + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + if (propagateClose) { + in.close(); + } + } + + /** + * Invokes the delegate's reset() method. + * @throws IOException if an I/O error occurs + */ + @Override + public synchronized void reset() throws IOException { + in.reset(); + pos = mark; + } + + /** + * Invokes the delegate's mark(int) method. + * @param readlimit read ahead limit + */ + @Override + public synchronized void mark(int readlimit) { + in.mark(readlimit); + mark = pos; + } + + /** + * Invokes the delegate's markSupported() method. + * @return true if mark is supported, otherwise false + */ + @Override + public boolean markSupported() { + return in.markSupported(); + } + + /** + * Indicates whether the {@link #close()} method + * should propagate to the underling {@link InputStream}. + * + * @return true if calling {@link #close()} + * propagates to the close() method of the + * underlying stream or false if it does not. + */ + public boolean isPropagateClose() { + return propagateClose; + } + + /** + * Set whether the {@link #close()} method + * should propagate to the underling {@link InputStream}. + * + * @param propagateClose true if calling + * {@link #close()} propagates to the close() + * method of the underlying stream or + * false if it does not. + */ + public void setPropagateClose(boolean propagateClose) { + this.propagateClose = propagateClose; + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/BrokenInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/BrokenInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/BrokenInputStream.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Broken input stream. This stream always throws an {@link IOException} from + * all the {@link InputStream} methods where the exception is declared. + *

+ * This class is mostly useful for testing error handling in code that uses an + * input stream. + * + * @since Commons IO 2.0 + */ +public class BrokenInputStream extends InputStream { + + /** + * The exception that is thrown by all methods of this class. + */ + private final IOException exception; + + /** + * Creates a new stream that always throws the given exception. + * + * @param exception the exception to be thrown + */ + public BrokenInputStream(IOException exception) { + this.exception = exception; + } + + /** + * Creates a new stream that always throws an {@link IOException} + */ + public BrokenInputStream() { + this(new IOException("Broken input stream")); + } + + /** + * Throws the configured exception. + * + * @return nothing + * @throws IOException always thrown + */ + @Override + public int read() throws IOException { + throw exception; + } + + /** + * Throws the configured exception. + * + * @return nothing + * @throws IOException always thrown + */ + @Override + public int available() throws IOException { + throw exception; + } + + /** + * Throws the configured exception. + * + * @param n ignored + * @return nothing + * @throws IOException always thrown + */ + @Override + public long skip(long n) throws IOException { + throw exception; + } + + /** + * Throws the configured exception. + * + * @throws IOException always thrown + */ + @Override + public void reset() throws IOException { + throw exception; + } + + /** + * Throws the configured exception. + * + * @throws IOException always thrown + */ + @Override + public void close() throws IOException { + throw exception; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/CharSequenceReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/CharSequenceReader.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/CharSequenceReader.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,163 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.Reader; +import java.io.Serializable; + +/** + * {@link Reader} implementation that can read from String, StringBuffer, + * StringBuilder or CharBuffer. + *

+ * Note: Supports {@link #mark(int)} and {@link #reset()}. + * + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:01 $ + * @since Commons IO 1.4 + */ +public class CharSequenceReader extends Reader implements Serializable { + + private final CharSequence charSequence; + private int idx; + private int mark; + + /** + * Construct a new instance with the specified character sequence. + * + * @param charSequence The character sequence, may be null + */ + public CharSequenceReader(CharSequence charSequence) { + this.charSequence = (charSequence != null ? charSequence : ""); + } + + /** + * Close resets the file back to the start and removes any marked position. + */ + @Override + public void close() { + idx = 0; + mark = 0; + } + + /** + * Mark the current position. + * + * @param readAheadLimit ignored + */ + @Override + public void mark(int readAheadLimit) { + mark = idx; + } + + /** + * Mark is supported (returns true). + * + * @return true + */ + @Override + public boolean markSupported() { + return true; + } + + /** + * Read a single character. + * + * @return the next character from the character sequence + * or -1 if the end has been reached. + */ + @Override + public int read() { + if (idx >= charSequence.length()) { + return -1; + } else { + return charSequence.charAt(idx++); + } + } + + /** + * Read the sepcified number of characters into the array. + * + * @param array The array to store the characters in + * @param offset The starting position in the array to store + * @param length The maximum number of characters to read + * @return The number of characters read or -1 if there are + * no more + */ + @Override + public int read(char[] array, int offset, int length) { + if (idx >= charSequence.length()) { + return -1; + } + if (array == null) { + throw new NullPointerException("Character array is missing"); + } + if (length < 0 || (offset + length) > array.length) { + throw new IndexOutOfBoundsException("Array Size=" + array.length + + ", offset=" + offset + ", length=" + length); + } + int count = 0; + for (int i = 0; i < length; i++) { + int c = read(); + if (c == -1) { + return count; + } + array[offset + i] = (char)c; + count++; + } + return count; + } + + /** + * Reset the reader to the last marked position (or the beginning if + * mark has not been called). + */ + @Override + public void reset() { + idx = mark; + } + + /** + * Skip the specified number of characters. + * + * @param n The number of characters to skip + * @return The actual number of characters skipped + */ + @Override + public long skip(long n) { + if (n < 0) { + throw new IllegalArgumentException( + "Number of characters to skip is less than zero: " + n); + } + if (idx >= charSequence.length()) { + return -1; + } + int dest = (int)Math.min(charSequence.length(), (idx + n)); + int count = dest - idx; + idx = dest; + return count; + } + + /** + * Return a String representation of the underlying + * character sequence. + * + * @return The contents of the character sequence + */ + @Override + public String toString() { + return charSequence.toString(); + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/ClassLoaderObjectInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/ClassLoaderObjectInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/ClassLoaderObjectInputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectStreamClass; +import java.io.StreamCorruptedException; +import java.lang.reflect.Proxy; + +/** + * A special ObjectInputStream that loads a class based on a specified + * ClassLoader rather than the system default. + *

+ * This is useful in dynamic container environments. + * + * @author Paul Hammant + * @version $Id: ClassLoaderObjectInputStream.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + * @since Commons IO 1.1 + */ +public class ClassLoaderObjectInputStream extends ObjectInputStream { + + /** The class loader to use. */ + private final ClassLoader classLoader; + + /** + * Constructs a new ClassLoaderObjectInputStream. + * + * @param classLoader the ClassLoader from which classes should be loaded + * @param inputStream the InputStream to work on + * @throws IOException in case of an I/O error + * @throws StreamCorruptedException if the stream is corrupted + */ + public ClassLoaderObjectInputStream( + ClassLoader classLoader, InputStream inputStream) + throws IOException, StreamCorruptedException { + super(inputStream); + this.classLoader = classLoader; + } + + /** + * Resolve a class specified by the descriptor using the + * specified ClassLoader or the super ClassLoader. + * + * @param objectStreamClass descriptor of the class + * @return the Class object described by the ObjectStreamClass + * @throws IOException in case of an I/O error + * @throws ClassNotFoundException if the Class cannot be found + */ + @Override + protected Class resolveClass(ObjectStreamClass objectStreamClass) + throws IOException, ClassNotFoundException { + + Class clazz = Class.forName(objectStreamClass.getName(), false, classLoader); + + if (clazz != null) { + // the classloader knows of the class + return clazz; + } else { + // classloader knows not of class, let the super classloader do it + return super.resolveClass(objectStreamClass); + } + } + + /** + * Create a proxy class that implements the specified interfaces using + * the specified ClassLoader or the super ClassLoader. + * + * @param interfaces the interfaces to implement + * @return a proxy class implementing the interfaces + * @throws IOException in case of an I/O error + * @throws ClassNotFoundException if the Class cannot be found + * @see java.io.ObjectInputStream#resolveProxyClass(java.lang.String[]) + * @since Commons IO 2.1 + */ + @Override + protected Class resolveProxyClass(String[] interfaces) throws IOException, + ClassNotFoundException { + Class[] interfaceClasses = new Class[interfaces.length]; + for (int i = 0; i < interfaces.length; i++) { + interfaceClasses[i] = Class.forName(interfaces[i], false, classLoader); + } + try { + return Proxy.getProxyClass(classLoader, interfaceClasses); + } catch (IllegalArgumentException e) { + return super.resolveProxyClass(interfaces); + } + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/CloseShieldInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/CloseShieldInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/CloseShieldInputStream.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.InputStream; + +/** + * Proxy stream that prevents the underlying input stream from being closed. + *

+ * This class is typically used in cases where an input stream needs to be + * passed to a component that wants to explicitly close the stream even if + * more input would still be available to other components. + * + * @version $Id: CloseShieldInputStream.java,v 1.1 2012/10/01 13:03:01 marcin Exp $ + * @since Commons IO 1.4 + */ +public class CloseShieldInputStream extends ProxyInputStream { + + /** + * Creates a proxy that shields the given input stream from being + * closed. + * + * @param in underlying input stream + */ + public CloseShieldInputStream(InputStream in) { + super(in); + } + + /** + * Replaces the underlying input stream with a {@link ClosedInputStream} + * sentinel. The original input stream will remain open, but this proxy + * will appear closed. + */ + @Override + public void close() { + in = new ClosedInputStream(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/ClosedInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/ClosedInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/ClosedInputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.InputStream; + +/** + * Closed input stream. This stream returns -1 to all attempts to read + * something from the stream. + *

+ * Typically uses of this class include testing for corner cases in methods + * that accept input streams and acting as a sentinel value instead of a + * null input stream. + * + * @version $Id: ClosedInputStream.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + * @since Commons IO 1.4 + */ +public class ClosedInputStream extends InputStream { + + /** + * A singleton. + */ + public static final ClosedInputStream CLOSED_INPUT_STREAM = new ClosedInputStream(); + + /** + * Returns -1 to indicate that the stream is closed. + * + * @return always -1 + */ + @Override + public int read() { + return -1; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/CountingInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/CountingInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/CountingInputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.IOException; +import java.io.InputStream; + +/** + * A decorating input stream that counts the number of bytes that have passed + * through the stream so far. + *

+ * A typical use case would be during debugging, to ensure that data is being + * read as expected. + * + * @author Marcelo Liberato + * @version $Id: CountingInputStream.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + */ +public class CountingInputStream extends ProxyInputStream { + + /** The count of bytes that have passed. */ + private long count; + + /** + * Constructs a new CountingInputStream. + * + * @param in the InputStream to delegate to + */ + public CountingInputStream(InputStream in) { + super(in); + } + + //----------------------------------------------------------------------- + + /** + * Skips the stream over the specified number of bytes, adding the skipped + * amount to the count. + * + * @param length the number of bytes to skip + * @return the actual number of bytes skipped + * @throws IOException if an I/O error occurs + * @see java.io.InputStream#skip(long) + */ + @Override + public synchronized long skip(final long length) throws IOException { + final long skip = super.skip(length); + this.count += skip; + return skip; + } + + /** + * Adds the number of read bytes to the count. + * + * @param n number of bytes read, or -1 if no more bytes are available + * @since Commons IO 2.0 + */ + @Override + protected synchronized void afterRead(int n) { + if (n != -1) { + this.count += n; + } + } + + //----------------------------------------------------------------------- + /** + * The number of bytes that have passed through this stream. + *

+ * NOTE: From v1.3 this method throws an ArithmeticException if the + * count is greater than can be expressed by an int. + * See {@link #getByteCount()} for a method using a long. + * + * @return the number of bytes accumulated + * @throws ArithmeticException if the byte count is too large + */ + public int getCount() { + long result = getByteCount(); + if (result > Integer.MAX_VALUE) { + throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int"); + } + return (int) result; + } + + /** + * Set the byte count back to 0. + *

+ * NOTE: From v1.3 this method throws an ArithmeticException if the + * count is greater than can be expressed by an int. + * See {@link #resetByteCount()} for a method using a long. + * + * @return the count previous to resetting + * @throws ArithmeticException if the byte count is too large + */ + public int resetCount() { + long result = resetByteCount(); + if (result > Integer.MAX_VALUE) { + throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int"); + } + return (int) result; + } + + /** + * The number of bytes that have passed through this stream. + *

+ * NOTE: This method is an alternative for getCount() + * and was added because that method returns an integer which will + * result in incorrect count for files over 2GB. + * + * @return the number of bytes accumulated + * @since Commons IO 1.3 + */ + public synchronized long getByteCount() { + return this.count; + } + + /** + * Set the byte count back to 0. + *

+ * NOTE: This method is an alternative for resetCount() + * and was added because that method returns an integer which will + * result in incorrect count for files over 2GB. + * + * @return the count previous to resetting + * @since Commons IO 1.3 + */ + public synchronized long resetByteCount() { + long tmp = this.count; + this.count = 0; + return tmp; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/DemuxInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/DemuxInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/DemuxInputStream.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Data written to this stream is forwarded to a stream that has been associated + * with this thread. + * + * @author Peter Donald + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:01 $ + */ +public class DemuxInputStream + extends InputStream +{ + private final InheritableThreadLocal m_streams = new InheritableThreadLocal(); + + /** + * Bind the specified stream to the current thread. + * + * @param input the stream to bind + * @return the InputStream that was previously active + */ + public InputStream bindStream( InputStream input ) + { + InputStream oldValue = m_streams.get(); + m_streams.set( input ); + return oldValue; + } + + /** + * Closes stream associated with current thread. + * + * @throws IOException if an error occurs + */ + @Override + public void close() + throws IOException + { + InputStream input = m_streams.get(); + if( null != input ) + { + input.close(); + } + } + + /** + * Read byte from stream associated with current thread. + * + * @return the byte read from stream + * @throws IOException if an error occurs + */ + @Override + public int read() + throws IOException + { + InputStream input = m_streams.get(); + if( null != input ) + { + return input.read(); + } + else + { + return -1; + } + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/NullInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/NullInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/NullInputStream.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,338 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; + +/** + * A functional, light weight {@link InputStream} that emulates + * a stream of a specified size. + *

+ * This implementation provides a light weight + * object for testing with an {@link InputStream} + * where the contents don't matter. + *

+ * One use case would be for testing the handling of + * large {@link InputStream} as it can emulate that + * scenario without the overhead of actually processing + * large numbers of bytes - significantly speeding up + * test execution times. + *

+ * This implementation returns zero from the method that + * reads a byte and leaves the array unchanged in the read + * methods that are passed a byte array. + * If alternative data is required the processByte() and + * processBytes() methods can be implemented to generate + * data, for example: + * + *

+ *  public class TestInputStream extends NullInputStream {
+ *      public TestInputStream(int size) {
+ *          super(size);
+ *      }
+ *      protected int processByte() {
+ *          return ... // return required value here
+ *      }
+ *      protected void processBytes(byte[] bytes, int offset, int length) {
+ *          for (int i = offset; i < length; i++) {
+ *              bytes[i] = ... // set array value here
+ *          }
+ *      }
+ *  }
+ * 
+ * + * @since Commons IO 1.3 + * @version $Revision: 1.1 $ + */ +public class NullInputStream extends InputStream { + + private final long size; + private long position; + private long mark = -1; + private long readlimit; + private boolean eof; + private final boolean throwEofException; + private final boolean markSupported; + + /** + * Create an {@link InputStream} that emulates a specified size + * which supports marking and does not throw EOFException. + * + * @param size The size of the input stream to emulate. + */ + public NullInputStream(long size) { + this(size, true, false); + } + + /** + * Create an {@link InputStream} that emulates a specified + * size with option settings. + * + * @param size The size of the input stream to emulate. + * @param markSupported Whether this instance will support + * the mark() functionality. + * @param throwEofException Whether this implementation + * will throw an {@link EOFException} or return -1 when the + * end of file is reached. + */ + public NullInputStream(long size, boolean markSupported, boolean throwEofException) { + this.size = size; + this.markSupported = markSupported; + this.throwEofException = throwEofException; + } + + /** + * Return the current position. + * + * @return the current position. + */ + public long getPosition() { + return position; + } + + /** + * Return the size this {@link InputStream} emulates. + * + * @return The size of the input stream to emulate. + */ + public long getSize() { + return size; + } + + /** + * Return the number of bytes that can be read. + * + * @return The number of bytes that can be read. + */ + @Override + public int available() { + long avail = size - position; + if (avail <= 0) { + return 0; + } else if (avail > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } else { + return (int)avail; + } + } + + /** + * Close this input stream - resets the internal state to + * the initial values. + * + * @throws IOException If an error occurs. + */ + @Override + public void close() throws IOException { + eof = false; + position = 0; + mark = -1; + } + + /** + * Mark the current position. + * + * @param readlimit The number of bytes before this marked position + * is invalid. + * @throws UnsupportedOperationException if mark is not supported. + */ + @Override + public synchronized void mark(int readlimit) { + if (!markSupported) { + throw new UnsupportedOperationException("Mark not supported"); + } + mark = position; + this.readlimit = readlimit; + } + + /** + * Indicates whether mark is supported. + * + * @return Whether mark is supported or not. + */ + @Override + public boolean markSupported() { + return markSupported; + } + + /** + * Read a byte. + * + * @return Either The byte value returned by processByte() + * or -1 if the end of file has been reached and + * throwEofException is set to false. + * @throws EOFException if the end of file is reached and + * throwEofException is set to true. + * @throws IOException if trying to read past the end of file. + */ + @Override + public int read() throws IOException { + if (eof) { + throw new IOException("Read after end of file"); + } + if (position == size) { + return doEndOfFile(); + } + position++; + return processByte(); + } + + /** + * Read some bytes into the specified array. + * + * @param bytes The byte array to read into + * @return The number of bytes read or -1 + * if the end of file has been reached and + * throwEofException is set to false. + * @throws EOFException if the end of file is reached and + * throwEofException is set to true. + * @throws IOException if trying to read past the end of file. + */ + @Override + public int read(byte[] bytes) throws IOException { + return read(bytes, 0, bytes.length); + } + + /** + * Read the specified number bytes into an array. + * + * @param bytes The byte array to read into. + * @param offset The offset to start reading bytes into. + * @param length The number of bytes to read. + * @return The number of bytes read or -1 + * if the end of file has been reached and + * throwEofException is set to false. + * @throws EOFException if the end of file is reached and + * throwEofException is set to true. + * @throws IOException if trying to read past the end of file. + */ + @Override + public int read(byte[] bytes, int offset, int length) throws IOException { + if (eof) { + throw new IOException("Read after end of file"); + } + if (position == size) { + return doEndOfFile(); + } + position += length; + int returnLength = length; + if (position > size) { + returnLength = length - (int)(position - size); + position = size; + } + processBytes(bytes, offset, returnLength); + return returnLength; + } + + /** + * Reset the stream to the point when mark was last called. + * + * @throws UnsupportedOperationException if mark is not supported. + * @throws IOException If no position has been marked + * or the read limit has been exceed since the last position was + * marked. + */ + @Override + public synchronized void reset() throws IOException { + if (!markSupported) { + throw new UnsupportedOperationException("Mark not supported"); + } + if (mark < 0) { + throw new IOException("No position has been marked"); + } + if (position > (mark + readlimit)) { + throw new IOException("Marked position [" + mark + + "] is no longer valid - passed the read limit [" + + readlimit + "]"); + } + position = mark; + eof = false; + } + + /** + * Skip a specified number of bytes. + * + * @param numberOfBytes The number of bytes to skip. + * @return The number of bytes skipped or -1 + * if the end of file has been reached and + * throwEofException is set to false. + * @throws EOFException if the end of file is reached and + * throwEofException is set to true. + * @throws IOException if trying to read past the end of file. + */ + @Override + public long skip(long numberOfBytes) throws IOException { + if (eof) { + throw new IOException("Skip after end of file"); + } + if (position == size) { + return doEndOfFile(); + } + position += numberOfBytes; + long returnLength = numberOfBytes; + if (position > size) { + returnLength = numberOfBytes - (position - size); + position = size; + } + return returnLength; + } + + /** + * Return a byte value for the read() method. + *

+ * This implementation returns zero. + * + * @return This implementation always returns zero. + */ + protected int processByte() { + // do nothing - overridable by subclass + return 0; + } + + /** + * Process the bytes for the read(byte[], offset, length) + * method. + *

+ * This implementation leaves the byte array unchanged. + * + * @param bytes The byte array + * @param offset The offset to start at. + * @param length The number of bytes. + */ + protected void processBytes(byte[] bytes, int offset, int length) { + // do nothing - overridable by subclass + } + + /** + * Handle End of File. + * + * @return -1 if throwEofException is + * set to false + * @throws EOFException if throwEofException is set + * to true. + */ + private int doEndOfFile() throws EOFException { + eof = true; + if (throwEofException) { + throw new EOFException(); + } + return -1; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/NullReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/NullReader.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/NullReader.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,321 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.EOFException; +import java.io.IOException; +import java.io.Reader; + +/** + * A functional, light weight {@link Reader} that emulates + * a reader of a specified size. + *

+ * This implementation provides a light weight + * object for testing with an {@link Reader} + * where the contents don't matter. + *

+ * One use case would be for testing the handling of + * large {@link Reader} as it can emulate that + * scenario without the overhead of actually processing + * large numbers of characters - significantly speeding up + * test execution times. + *

+ * This implementation returns a space from the method that + * reads a character and leaves the array unchanged in the read + * methods that are passed a character array. + * If alternative data is required the processChar() and + * processChars() methods can be implemented to generate + * data, for example: + * + *

+ *  public class TestReader extends NullReader {
+ *      public TestReader(int size) {
+ *          super(size);
+ *      }
+ *      protected char processChar() {
+ *          return ... // return required value here
+ *      }
+ *      protected void processChars(char[] chars, int offset, int length) {
+ *          for (int i = offset; i < length; i++) {
+ *              chars[i] = ... // set array value here
+ *          }
+ *      }
+ *  }
+ * 
+ * + * @since Commons IO 1.3 + * @version $Revision: 1.1 $ + */ +public class NullReader extends Reader { + + private final long size; + private long position; + private long mark = -1; + private long readlimit; + private boolean eof; + private final boolean throwEofException; + private final boolean markSupported; + + /** + * Create a {@link Reader} that emulates a specified size + * which supports marking and does not throw EOFException. + * + * @param size The size of the reader to emulate. + */ + public NullReader(long size) { + this(size, true, false); + } + + /** + * Create a {@link Reader} that emulates a specified + * size with option settings. + * + * @param size The size of the reader to emulate. + * @param markSupported Whether this instance will support + * the mark() functionality. + * @param throwEofException Whether this implementation + * will throw an {@link EOFException} or return -1 when the + * end of file is reached. + */ + public NullReader(long size, boolean markSupported, boolean throwEofException) { + this.size = size; + this.markSupported = markSupported; + this.throwEofException = throwEofException; + } + + /** + * Return the current position. + * + * @return the current position. + */ + public long getPosition() { + return position; + } + + /** + * Return the size this {@link Reader} emulates. + * + * @return The size of the reader to emulate. + */ + public long getSize() { + return size; + } + + /** + * Close this Reader - resets the internal state to + * the initial values. + * + * @throws IOException If an error occurs. + */ + @Override + public void close() throws IOException { + eof = false; + position = 0; + mark = -1; + } + + /** + * Mark the current position. + * + * @param readlimit The number of characters before this marked position + * is invalid. + * @throws UnsupportedOperationException if mark is not supported. + */ + @Override + public synchronized void mark(int readlimit) { + if (!markSupported) { + throw new UnsupportedOperationException("Mark not supported"); + } + mark = position; + this.readlimit = readlimit; + } + + /** + * Indicates whether mark is supported. + * + * @return Whether mark is supported or not. + */ + @Override + public boolean markSupported() { + return markSupported; + } + + /** + * Read a character. + * + * @return Either The character value returned by processChar() + * or -1 if the end of file has been reached and + * throwEofException is set to false. + * @throws EOFException if the end of file is reached and + * throwEofException is set to true. + * @throws IOException if trying to read past the end of file. + */ + @Override + public int read() throws IOException { + if (eof) { + throw new IOException("Read after end of file"); + } + if (position == size) { + return doEndOfFile(); + } + position++; + return processChar(); + } + + /** + * Read some characters into the specified array. + * + * @param chars The character array to read into + * @return The number of characters read or -1 + * if the end of file has been reached and + * throwEofException is set to false. + * @throws EOFException if the end of file is reached and + * throwEofException is set to true. + * @throws IOException if trying to read past the end of file. + */ + @Override + public int read(char[] chars) throws IOException { + return read(chars, 0, chars.length); + } + + /** + * Read the specified number characters into an array. + * + * @param chars The character array to read into. + * @param offset The offset to start reading characters into. + * @param length The number of characters to read. + * @return The number of characters read or -1 + * if the end of file has been reached and + * throwEofException is set to false. + * @throws EOFException if the end of file is reached and + * throwEofException is set to true. + * @throws IOException if trying to read past the end of file. + */ + @Override + public int read(char[] chars, int offset, int length) throws IOException { + if (eof) { + throw new IOException("Read after end of file"); + } + if (position == size) { + return doEndOfFile(); + } + position += length; + int returnLength = length; + if (position > size) { + returnLength = length - (int)(position - size); + position = size; + } + processChars(chars, offset, returnLength); + return returnLength; + } + + /** + * Reset the stream to the point when mark was last called. + * + * @throws UnsupportedOperationException if mark is not supported. + * @throws IOException If no position has been marked + * or the read limit has been exceed since the last position was + * marked. + */ + @Override + public synchronized void reset() throws IOException { + if (!markSupported) { + throw new UnsupportedOperationException("Mark not supported"); + } + if (mark < 0) { + throw new IOException("No position has been marked"); + } + if (position > (mark + readlimit)) { + throw new IOException("Marked position [" + mark + + "] is no longer valid - passed the read limit [" + + readlimit + "]"); + } + position = mark; + eof = false; + } + + /** + * Skip a specified number of characters. + * + * @param numberOfChars The number of characters to skip. + * @return The number of characters skipped or -1 + * if the end of file has been reached and + * throwEofException is set to false. + * @throws EOFException if the end of file is reached and + * throwEofException is set to true. + * @throws IOException if trying to read past the end of file. + */ + @Override + public long skip(long numberOfChars) throws IOException { + if (eof) { + throw new IOException("Skip after end of file"); + } + if (position == size) { + return doEndOfFile(); + } + position += numberOfChars; + long returnLength = numberOfChars; + if (position > size) { + returnLength = numberOfChars - (position - size); + position = size; + } + return returnLength; + } + + /** + * Return a character value for the read() method. + *

+ * This implementation returns zero. + * + * @return This implementation always returns zero. + */ + protected int processChar() { + // do nothing - overridable by subclass + return 0; + } + + /** + * Process the characters for the read(char[], offset, length) + * method. + *

+ * This implementation leaves the character array unchanged. + * + * @param chars The character array + * @param offset The offset to start at. + * @param length The number of characters. + */ + protected void processChars(char[] chars, int offset, int length) { + // do nothing - overridable by subclass + } + + /** + * Handle End of File. + * + * @return -1 if throwEofException is + * set to false + * @throws EOFException if throwEofException is set + * to true. + */ + private int doEndOfFile() throws EOFException { + eof = true; + if (throwEofException) { + throw new EOFException(); + } + return -1; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/ProxyInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/ProxyInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/ProxyInputStream.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * A Proxy stream which acts as expected, that is it passes the method + * calls on to the proxied stream and doesn't change which methods are + * being called. + *

+ * It is an alternative base class to FilterInputStream + * to increase reusability, because FilterInputStream changes the + * methods being called, such as read(byte[]) to read(byte[], int, int). + *

+ * See the protected methods for ways in which a subclass can easily decorate + * a stream with custom pre-, post- or error processing functionality. + * + * @author Stephen Colebourne + * @version $Id: ProxyInputStream.java,v 1.1 2012/10/01 13:03:01 marcin Exp $ + */ +public abstract class ProxyInputStream extends FilterInputStream { + + /** + * Constructs a new ProxyInputStream. + * + * @param proxy the InputStream to delegate to + */ + public ProxyInputStream(InputStream proxy) { + super(proxy); + // the proxy is stored in a protected superclass variable named 'in' + } + + /** + * Invokes the delegate's read() method. + * @return the byte read or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + @Override + public int read() throws IOException { + try { + beforeRead(1); + int b = in.read(); + afterRead(b != -1 ? 1 : -1); + return b; + } catch (IOException e) { + handleIOException(e); + return -1; + } + } + + /** + * Invokes the delegate's read(byte[]) method. + * @param bts the buffer to read the bytes into + * @return the number of bytes read or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + @Override + public int read(byte[] bts) throws IOException { + try { + beforeRead(bts != null ? bts.length : 0); + int n = in.read(bts); + afterRead(n); + return n; + } catch (IOException e) { + handleIOException(e); + return -1; + } + } + + /** + * Invokes the delegate's read(byte[], int, int) method. + * @param bts the buffer to read the bytes into + * @param off The start offset + * @param len The number of bytes to read + * @return the number of bytes read or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + @Override + public int read(byte[] bts, int off, int len) throws IOException { + try { + beforeRead(len); + int n = in.read(bts, off, len); + afterRead(n); + return n; + } catch (IOException e) { + handleIOException(e); + return -1; + } + } + + /** + * Invokes the delegate's skip(long) method. + * @param ln the number of bytes to skip + * @return the actual number of bytes skipped + * @throws IOException if an I/O error occurs + */ + @Override + public long skip(long ln) throws IOException { + try { + return in.skip(ln); + } catch (IOException e) { + handleIOException(e); + return 0; + } + } + + /** + * Invokes the delegate's available() method. + * @return the number of available bytes + * @throws IOException if an I/O error occurs + */ + @Override + public int available() throws IOException { + try { + return super.available(); + } catch (IOException e) { + handleIOException(e); + return 0; + } + } + + /** + * Invokes the delegate's close() method. + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + try { + in.close(); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's mark(int) method. + * @param readlimit read ahead limit + */ + @Override + public synchronized void mark(int readlimit) { + in.mark(readlimit); + } + + /** + * Invokes the delegate's reset() method. + * @throws IOException if an I/O error occurs + */ + @Override + public synchronized void reset() throws IOException { + try { + in.reset(); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's markSupported() method. + * @return true if mark is supported, otherwise false + */ + @Override + public boolean markSupported() { + return in.markSupported(); + } + + /** + * Invoked by the read methods before the call is proxied. The number + * of bytes that the caller wanted to read (1 for the {@link #read()} + * method, buffer length for {@link #read(byte[])}, etc.) is given as + * an argument. + *

+ * Subclasses can override this method to add common pre-processing + * functionality without having to override all the read methods. + * The default implementation does nothing. + *

+ * Note this method is not called from {@link #skip(long)} or + * {@link #reset()}. You need to explicitly override those methods if + * you want to add pre-processing steps also to them. + * + * @since Commons IO 2.0 + * @param n number of bytes that the caller asked to be read + * @throws IOException if the pre-processing fails + */ + protected void beforeRead(int n) throws IOException { + } + + /** + * Invoked by the read methods after the proxied call has returned + * successfully. The number of bytes returned to the caller (or -1 if + * the end of stream was reached) is given as an argument. + *

+ * Subclasses can override this method to add common post-processing + * functionality without having to override all the read methods. + * The default implementation does nothing. + *

+ * Note this method is not called from {@link #skip(long)} or + * {@link #reset()}. You need to explicitly override those methods if + * you want to add post-processing steps also to them. + * + * @since Commons IO 2.0 + * @param n number of bytes read, or -1 if the end of stream was reached + * @throws IOException if the post-processing fails + */ + protected void afterRead(int n) throws IOException { + } + + /** + * Handle any IOExceptions thrown. + *

+ * This method provides a point to implement custom exception + * handling. The default behaviour is to re-throw the exception. + * @param e The IOException thrown + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + protected void handleIOException(IOException e) throws IOException { + throw e; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/ProxyReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/ProxyReader.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/ProxyReader.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,260 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; +import java.nio.CharBuffer; + +/** + * A Proxy stream which acts as expected, that is it passes the method + * calls on to the proxied stream and doesn't change which methods are + * being called. + *

+ * It is an alternative base class to FilterReader + * to increase reusability, because FilterReader changes the + * methods being called, such as read(char[]) to read(char[], int, int). + * + * @author Stephen Colebourne + * @version $Id: ProxyReader.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + */ +public abstract class ProxyReader extends FilterReader { + + /** + * Constructs a new ProxyReader. + * + * @param proxy the Reader to delegate to + */ + public ProxyReader(Reader proxy) { + super(proxy); + // the proxy is stored in a protected superclass variable named 'in' + } + + /** + * Invokes the delegate's read() method. + * @return the character read or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + @Override + public int read() throws IOException { + try { + beforeRead(1); + int c = in.read(); + afterRead(c != -1 ? 1 : -1); + return c; + } catch (IOException e) { + handleIOException(e); + return -1; + } + } + + /** + * Invokes the delegate's read(char[]) method. + * @param chr the buffer to read the characters into + * @return the number of characters read or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + @Override + public int read(char[] chr) throws IOException { + try { + beforeRead(chr != null ? chr.length : 0); + int n = in.read(chr); + afterRead(n); + return n; + } catch (IOException e) { + handleIOException(e); + return -1; + } + } + + /** + * Invokes the delegate's read(char[], int, int) method. + * @param chr the buffer to read the characters into + * @param st The start offset + * @param len The number of bytes to read + * @return the number of characters read or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + @Override + public int read(char[] chr, int st, int len) throws IOException { + try { + beforeRead(len); + int n = in.read(chr, st, len); + afterRead(n); + return n; + } catch (IOException e) { + handleIOException(e); + return -1; + } + } + + /** + * Invokes the delegate's read(CharBuffer) method. + * @param target the char buffer to read the characters into + * @return the number of characters read or -1 if the end of stream + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + @Override + public int read(CharBuffer target) throws IOException { + try { + beforeRead(target != null ? target.length() : 0); + int n = in.read(target); + afterRead(n); + return n; + } catch (IOException e) { + handleIOException(e); + return -1; + } + } + + /** + * Invokes the delegate's skip(long) method. + * @param ln the number of bytes to skip + * @return the number of bytes to skipped or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + @Override + public long skip(long ln) throws IOException { + try { + return in.skip(ln); + } catch (IOException e) { + handleIOException(e); + return 0; + } + } + + /** + * Invokes the delegate's ready() method. + * @return true if the stream is ready to be read + * @throws IOException if an I/O error occurs + */ + @Override + public boolean ready() throws IOException { + try { + return in.ready(); + } catch (IOException e) { + handleIOException(e); + return false; + } + } + + /** + * Invokes the delegate's close() method. + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + try { + in.close(); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's mark(int) method. + * @param idx read ahead limit + * @throws IOException if an I/O error occurs + */ + @Override + public synchronized void mark(int idx) throws IOException { + try { + in.mark(idx); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's reset() method. + * @throws IOException if an I/O error occurs + */ + @Override + public synchronized void reset() throws IOException { + try { + in.reset(); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's markSupported() method. + * @return true if mark is supported, otherwise false + */ + @Override + public boolean markSupported() { + return in.markSupported(); + } + + /** + * Invoked by the read methods before the call is proxied. The number + * of chars that the caller wanted to read (1 for the {@link #read()} + * method, buffer length for {@link #read(char[])}, etc.) is given as + * an argument. + *

+ * Subclasses can override this method to add common pre-processing + * functionality without having to override all the read methods. + * The default implementation does nothing. + *

+ * Note this method is not called from {@link #skip(long)} or + * {@link #reset()}. You need to explicitly override those methods if + * you want to add pre-processing steps also to them. + * + * @since Commons IO 2.0 + * @param n number of chars that the caller asked to be read + * @throws IOException if the pre-processing fails + */ + protected void beforeRead(int n) throws IOException { + } + + /** + * Invoked by the read methods after the proxied call has returned + * successfully. The number of chars returned to the caller (or -1 if + * the end of stream was reached) is given as an argument. + *

+ * Subclasses can override this method to add common post-processing + * functionality without having to override all the read methods. + * The default implementation does nothing. + *

+ * Note this method is not called from {@link #skip(long)} or + * {@link #reset()}. You need to explicitly override those methods if + * you want to add post-processing steps also to them. + * + * @since Commons IO 2.0 + * @param n number of chars read, or -1 if the end of stream was reached + * @throws IOException if the post-processing fails + */ + protected void afterRead(int n) throws IOException { + } + + /** + * Handle any IOExceptions thrown. + *

+ * This method provides a point to implement custom exception + * handling. The default behaviour is to re-throw the exception. + * @param e The IOException thrown + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + protected void handleIOException(IOException e) throws IOException { + throw e; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/ReaderInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/ReaderInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/ReaderInputStream.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; + +/** + * {@link InputStream} implementation that reads a character stream from a {@link Reader} + * and transforms it to a byte stream using a specified charset encoding. The stream + * is transformed using a {@link CharsetEncoder} object, guaranteeing that all charset + * encodings supported by the JRE are handled correctly. In particular for charsets such as + * UTF-16, the implementation ensures that one and only one byte order marker + * is produced. + *

+ * Since in general it is not possible to predict the number of characters to be read from the + * {@link Reader} to satisfy a read request on the {@link ReaderInputStream}, all reads from + * the {@link Reader} are buffered. There is therefore no well defined correlation + * between the current position of the {@link Reader} and that of the {@link ReaderInputStream}. + * This also implies that in general there is no need to wrap the underlying {@link Reader} + * in a {@link java.io.BufferedReader}. + *

+ * {@link ReaderInputStream} implements the inverse transformation of {@link java.io.InputStreamReader}; + * in the following example, reading from in2 would return the same byte + * sequence as reading from in (provided that the initial byte sequence is legal + * with respect to the charset encoding): + *

+ * InputStream in = ...
+ * Charset cs = ...
+ * InputStreamReader reader = new InputStreamReader(in, cs);
+ * ReaderInputStream in2 = new ReaderInputStream(reader, cs);
+ * {@link ReaderInputStream} implements the same transformation as {@link java.io.OutputStreamWriter}, + * except that the control flow is reversed: both classes transform a character stream + * into a byte stream, but {@link java.io.OutputStreamWriter} pushes data to the underlying stream, + * while {@link ReaderInputStream} pulls it from the underlying stream. + *

+ * Note that while there are use cases where there is no alternative to using + * this class, very often the need to use this class is an indication of a flaw + * in the design of the code. This class is typically used in situations where an existing + * API only accepts an {@link InputStream}, but where the most natural way to produce the data + * is as a character stream, i.e. by providing a {@link Reader} instance. An example of a situation + * where this problem may appear is when implementing the {@link javax.activation.DataSource} + * interface from the Java Activation Framework. + *

+ * Given the fact that the {@link Reader} class doesn't provide any way to predict whether the next + * read operation will block or not, it is not possible to provide a meaningful + * implementation of the {@link InputStream#available()} method. A call to this method + * will always return 0. Also, this class doesn't support {@link InputStream#mark(int)}. + *

+ * Instances of {@link ReaderInputStream} are not thread safe. + * + * @see org.apache.commons.io.output.WriterOutputStream + * + * @author Andreas Veithen + * @since Commons IO 2.0 + */ +public class ReaderInputStream extends InputStream { + private static final int DEFAULT_BUFFER_SIZE = 1024; + + private final Reader reader; + private final CharsetEncoder encoder; + + /** + * CharBuffer used as input for the decoder. It should be reasonably + * large as we read data from the underlying Reader into this buffer. + */ + private final CharBuffer encoderIn; + + /** + * ByteBuffer used as output for the decoder. This buffer can be small + * as it is only used to transfer data from the decoder to the + * buffer provided by the caller. + */ + private final ByteBuffer encoderOut = ByteBuffer.allocate(128); + + private CoderResult lastCoderResult; + private boolean endOfInput; + + /** + * Construct a new {@link ReaderInputStream}. + * + * @param reader the target {@link Reader} + * @param encoder the charset encoder + * @since Commons IO 2.1 + */ + public ReaderInputStream(Reader reader, CharsetEncoder encoder) { + this(reader, encoder, DEFAULT_BUFFER_SIZE); + } + + /** + * Construct a new {@link ReaderInputStream}. + * + * @param reader the target {@link Reader} + * @param encoder the charset encoder + * @param bufferSize the size of the input buffer in number of characters + * @since Commons IO 2.1 + */ + public ReaderInputStream(Reader reader, CharsetEncoder encoder, int bufferSize) { + this.reader = reader; + this.encoder = encoder; + encoderIn = CharBuffer.allocate(bufferSize); + encoderIn.flip(); + } + + /** + * Construct a new {@link ReaderInputStream}. + * + * @param reader the target {@link Reader} + * @param charset the charset encoding + * @param bufferSize the size of the input buffer in number of characters + */ + public ReaderInputStream(Reader reader, Charset charset, int bufferSize) { + this(reader, + charset.newEncoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE), + bufferSize); + } + + /** + * Construct a new {@link ReaderInputStream} with a default input buffer size of + * 1024 characters. + * + * @param reader the target {@link Reader} + * @param charset the charset encoding + */ + public ReaderInputStream(Reader reader, Charset charset) { + this(reader, charset, DEFAULT_BUFFER_SIZE); + } + + /** + * Construct a new {@link ReaderInputStream}. + * + * @param reader the target {@link Reader} + * @param charsetName the name of the charset encoding + * @param bufferSize the size of the input buffer in number of characters + */ + public ReaderInputStream(Reader reader, String charsetName, int bufferSize) { + this(reader, Charset.forName(charsetName), bufferSize); + } + + /** + * Construct a new {@link ReaderInputStream} with a default input buffer size of + * 1024 characters. + * + * @param reader the target {@link Reader} + * @param charsetName the name of the charset encoding + */ + public ReaderInputStream(Reader reader, String charsetName) { + this(reader, charsetName, DEFAULT_BUFFER_SIZE); + } + + /** + * Construct a new {@link ReaderInputStream} that uses the default character encoding + * with a default input buffer size of 1024 characters. + * + * @param reader the target {@link Reader} + */ + public ReaderInputStream(Reader reader) { + this(reader, Charset.defaultCharset()); + } + + /** + * Read the specified number of bytes into an array. + * + * @param b the byte array to read into + * @param off the offset to start reading bytes into + * @param len the number of bytes to read + * @return the number of bytes read or -1 + * if the end of the stream has been reached + * @throws IOException if an I/O error occurs + */ + @Override + public int read(byte[] b, int off, int len) throws IOException { + int read = 0; + while (len > 0) { + if (encoderOut.position() > 0) { + encoderOut.flip(); + int c = Math.min(encoderOut.remaining(), len); + encoderOut.get(b, off, c); + off += c; + len -= c; + read += c; + encoderOut.compact(); + } else { + if (!endOfInput && (lastCoderResult == null || lastCoderResult.isUnderflow())) { + encoderIn.compact(); + int position = encoderIn.position(); + // We don't use Reader#read(CharBuffer) here because it is more efficient + // to write directly to the underlying char array (the default implementation + // copies data to a temporary char array). + int c = reader.read(encoderIn.array(), position, encoderIn.remaining()); + if (c == -1) { + endOfInput = true; + } else { + encoderIn.position(position+c); + } + encoderIn.flip(); + } + lastCoderResult = encoder.encode(encoderIn, encoderOut, endOfInput); + if (endOfInput && encoderOut.position() == 0) { + break; + } + } + } + return read == 0 && endOfInput ? -1 : read; + } + + /** + * Read the specified number of bytes into an array. + * + * @param b the byte array to read into + * @return the number of bytes read or -1 + * if the end of the stream has been reached + * @throws IOException if an I/O error occurs + */ + @Override + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + + /** + * Read a single byte. + * + * @return either the byte read or -1 if the end of the stream + * has been reached + * @throws IOException if an I/O error occurs + */ + @Override + public int read() throws IOException { + byte[] b = new byte[1]; + return read(b) == -1 ? -1 : b[0] & 0xFF; + } + + /** + * Close the stream. This method will cause the underlying {@link Reader} + * to be closed. + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + reader.close(); + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/SwappedDataInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/SwappedDataInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/SwappedDataInputStream.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,251 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.DataInput; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.io.EndianUtils; + +/** + * DataInput for systems relying on little endian data formats. + * When read, values will be changed from little endian to big + * endian formats for internal usage. + *

+ * Origin of code: Avalon Excalibur (IO) + * + * @author Peter Donald + * @version CVS $Revision: 1.1 $ $Date: 2012/10/01 13:03:01 $ + */ +public class SwappedDataInputStream extends ProxyInputStream + implements DataInput +{ + + /** + * Constructs a SwappedDataInputStream. + * + * @param input InputStream to read from + */ + public SwappedDataInputStream( InputStream input ) + { + super( input ); + } + + /** + * Return {@link #readByte()} != 0 + * @return false if the byte read is zero, otherwise true + * @throws IOException if an I/O error occurs + * @throws EOFException if an end of file is reached unexpectedly + */ + public boolean readBoolean() + throws IOException, EOFException + { + return ( 0 != readByte() ); + } + + /** + * Invokes the delegate's read() method. + * @return the byte read or -1 if the end of stream + * @throws IOException if an I/O error occurs + * @throws EOFException if an end of file is reached unexpectedly + */ + public byte readByte() + throws IOException, EOFException + { + return (byte)in.read(); + } + + /** + * Reads a character delegating to {@link #readShort()}. + * @return the byte read or -1 if the end of stream + * @throws IOException if an I/O error occurs + * @throws EOFException if an end of file is reached unexpectedly + */ + public char readChar() + throws IOException, EOFException + { + return (char)readShort(); + } + + /** + * Delegates to {@link EndianUtils#readSwappedDouble(InputStream)}. + * @return the read long + * @throws IOException if an I/O error occurs + * @throws EOFException if an end of file is reached unexpectedly + */ + public double readDouble() + throws IOException, EOFException + { + return EndianUtils.readSwappedDouble( in ); + } + + /** + * Delegates to {@link EndianUtils#readSwappedFloat(InputStream)}. + * @return the read long + * @throws IOException if an I/O error occurs + * @throws EOFException if an end of file is reached unexpectedly + */ + public float readFloat() + throws IOException, EOFException + { + return EndianUtils.readSwappedFloat( in ); + } + + /** + * Invokes the delegate's read(byte[] data, int, int) method. + * + * @param data the buffer to read the bytes into + * @throws EOFException if an end of file is reached unexpectedly + * @throws IOException if an I/O error occurs + */ + public void readFully( byte[] data ) + throws IOException, EOFException + { + readFully( data, 0, data.length ); + } + + + /** + * Invokes the delegate's read(byte[] data, int, int) method. + * + * @param data the buffer to read the bytes into + * @param offset The start offset + * @param length The number of bytes to read + * @throws EOFException if an end of file is reached unexpectedly + * @throws IOException if an I/O error occurs + */ + public void readFully( byte[] data, int offset, int length ) + throws IOException, EOFException + { + int remaining = length; + + while( remaining > 0 ) + { + int location = offset + ( length - remaining ); + int count = read( data, location, remaining ); + + if( -1 == count ) + { + throw new EOFException(); + } + + remaining -= count; + } + } + + /** + * Delegates to {@link EndianUtils#readSwappedInteger(InputStream)}. + * @return the read long + * @throws EOFException if an end of file is reached unexpectedly + * @throws IOException if an I/O error occurs + */ + public int readInt() + throws IOException, EOFException + { + return EndianUtils.readSwappedInteger( in ); + } + + /** + * Not currently supported - throws {@link UnsupportedOperationException}. + * @return the line read + * @throws EOFException if an end of file is reached unexpectedly + * @throws IOException if an I/O error occurs + */ + public String readLine() + throws IOException, EOFException + { + throw new UnsupportedOperationException( + "Operation not supported: readLine()" ); + } + + /** + * Delegates to {@link EndianUtils#readSwappedLong(InputStream)}. + * @return the read long + * @throws EOFException if an end of file is reached unexpectedly + * @throws IOException if an I/O error occurs + */ + public long readLong() + throws IOException, EOFException + { + return EndianUtils.readSwappedLong( in ); + } + + /** + * Delegates to {@link EndianUtils#readSwappedShort(InputStream)}. + * @return the read long + * @throws EOFException if an end of file is reached unexpectedly + * @throws IOException if an I/O error occurs + */ + public short readShort() + throws IOException, EOFException + { + return EndianUtils.readSwappedShort( in ); + } + + /** + * Invokes the delegate's read() method. + * @return the byte read or -1 if the end of stream + * @throws EOFException if an end of file is reached unexpectedly + * @throws IOException if an I/O error occurs + */ + public int readUnsignedByte() + throws IOException, EOFException + { + return in.read(); + } + + /** + * Delegates to {@link EndianUtils#readSwappedUnsignedShort(InputStream)}. + * @return the read long + * @throws EOFException if an end of file is reached unexpectedly + * @throws IOException if an I/O error occurs + */ + public int readUnsignedShort() + throws IOException, EOFException + { + return EndianUtils.readSwappedUnsignedShort( in ); + } + + /** + * Not currently supported - throws {@link UnsupportedOperationException}. + * @return UTF String read + * @throws EOFException if an end of file is reached unexpectedly + * @throws IOException if an I/O error occurs + */ + public String readUTF() + throws IOException, EOFException + { + throw new UnsupportedOperationException( + "Operation not supported: readUTF()" ); + } + + /** + * Invokes the delegate's skip(int) method. + * @param count the number of bytes to skip + * @return the number of bytes to skipped or -1 if the end of stream + * @throws EOFException if an end of file is reached unexpectedly + * @throws IOException if an I/O error occurs + */ + public int skipBytes( int count ) + throws IOException, EOFException + { + return (int)in.skip( count ); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/TaggedInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/TaggedInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/TaggedInputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.util.UUID; + +import org.apache.commons.io.TaggedIOException; + +/** + * An input stream decorator that tags potential exceptions so that the + * stream that caused the exception can easily be identified. This is + * done by using the {@link TaggedIOException} class to wrap all thrown + * {@link IOException}s. See below for an example of using this class. + *

+ * TaggedInputStream stream = new TaggedInputStream(...);
+ * try {
+ *     // Processing that may throw an IOException either from this stream
+ *     // or from some other IO activity like temporary files, etc.
+ *     processStream(stream);
+ * } catch (IOException e) {
+ *     if (stream.isCauseOf(e)) {
+ *         // The exception was caused by this stream.
+ *         // Use e.getCause() to get the original exception.
+ *     } else {
+ *         // The exception was caused by something else.
+ *     }
+ * }
+ * 
+ *

+ * Alternatively, the {@link #throwIfCauseOf(Throwable)} method can be + * used to let higher levels of code handle the exception caused by this + * stream while other processing errors are being taken care of at this + * lower level. + *

+ * TaggedInputStream stream = new TaggedInputStream(...);
+ * try {
+ *     processStream(stream);
+ * } catch (IOException e) {
+ *     stream.throwIfCauseOf(e);
+ *     // ... or process the exception that was caused by something else
+ * }
+ * 
+ * + * @see TaggedIOException + * @since Commons IO 2.0 + */ +public class TaggedInputStream extends ProxyInputStream { + + /** + * The unique tag associated with exceptions from stream. + */ + private final Serializable tag = UUID.randomUUID(); + + /** + * Creates a tagging decorator for the given input stream. + * + * @param proxy input stream to be decorated + */ + public TaggedInputStream(InputStream proxy) { + super(proxy); + } + + /** + * Tests if the given exception was caused by this stream. + * + * @param exception an exception + * @return true if the exception was thrown by this stream, + * false otherwise + */ + public boolean isCauseOf(Throwable exception) { + return TaggedIOException.isTaggedWith(exception, tag); + } + + /** + * Re-throws the original exception thrown by this stream. This method + * first checks whether the given exception is a {@link TaggedIOException} + * wrapper created by this decorator, and then unwraps and throws the + * original wrapped exception. Returns normally if the exception was + * not thrown by this stream. + * + * @param throwable an exception + * @throws IOException original exception, if any, thrown by this stream + */ + public void throwIfCauseOf(Throwable throwable) throws IOException { + TaggedIOException.throwCauseIfTaggedWith(throwable, tag); + } + + /** + * Tags any IOExceptions thrown, wrapping and re-throwing. + * + * @param e The IOException thrown + * @throws IOException if an I/O error occurs + */ + @Override + protected void handleIOException(IOException e) throws IOException { + throw new TaggedIOException(e, tag); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/Tailer.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/Tailer.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/Tailer.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,376 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; + +/** + * Simple implementation of the unix "tail -f" functionality. + *

+ *

1. Create a TailerListener implementation

+ *

+ * First you need to create a {@link TailerListener} implementation + * ({@link TailerListenerAdapter} is provided for convenience so that you don't have to + * implement every method). + *

+ * + *

For example:

+ *
+ *  public class MyTailerListener extends TailerListenerAdapter {
+ *      public void handle(String line) {
+ *          System.out.println(line);
+ *      }
+ *  }
+ * 
+ * + *

2. Using a Tailer

+ * + * You can create and use a Tailer in one of three ways: + *
    + *
  • Using one of the static helper methods: + *
      + *
    • {@link Tailer#create(File, TailerListener)}
    • + *
    • {@link Tailer#create(File, TailerListener, long)}
    • + *
    • {@link Tailer#create(File, TailerListener, long, boolean)}
    • + *
    + *
  • + *
  • Using an {@link java.util.concurrent.Executor}
  • + *
  • Using an {@link Thread}
  • + *
+ * + * An example of each of these is shown below. + * + *

2.1 Using the static helper method

+ * + *
+ *      TailerListener listener = new MyTailerListener();
+ *      Tailer tailer = Tailer.create(file, listener, delay);
+ * 
+ * + *

2.2 Use an Executor

+ * + *
+ *      TailerListener listener = new MyTailerListener();
+ *      Tailer tailer = new Tailer(file, listener, delay);
+ *
+ *      // stupid executor impl. for demo purposes
+ *      Executor executor = new Executor() {
+ *          public void execute(Runnable command) {
+ *              command.run();
+ *           }
+ *      };
+ *
+ *      executor.execute(tailer);
+ * 
+ * + * + *

2.3 Use a Thread

+ *
+ *      TailerListener listener = new MyTailerListener();
+ *      Tailer tailer = new Tailer(file, listener, delay);
+ *      Thread thread = new Thread(tailer);
+ *      thread.setDaemon(true); // optional
+ *      thread.start();
+ * 
+ * + *

3. Stop Tailing

+ *

Remember to stop the tailer when you have done with it:

+ *
+ *      tailer.stop();
+ * 
+ * + * @see TailerListener + * @see TailerListenerAdapter + * @version $Id: Tailer.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + * @since Commons IO 2.0 + */ +public class Tailer implements Runnable { + + /** + * The file which will be tailed. + */ + private final File file; + + /** + * The amount of time to wait for the file to be updated. + */ + private final long delay; + + /** + * Whether to tail from the end or start of file + */ + private final boolean end; + + /** + * The listener to notify of events when tailing. + */ + private final TailerListener listener; + + /** + * The tailer will run as long as this value is true. + */ + private volatile boolean run = true; + + /** + * Creates a Tailer for the given file, starting from the beginning, with the default delay of 1.0s. + * @param file The file to follow. + * @param listener the TailerListener to use. + */ + public Tailer(File file, TailerListener listener) { + this(file, listener, 1000); + } + + /** + * Creates a Tailer for the given file, starting from the beginning. + * @param file the file to follow. + * @param listener the TailerListener to use. + * @param delay the delay between checks of the file for new content in milliseconds. + */ + public Tailer(File file, TailerListener listener, long delay) { + this(file, listener, 1000, false); + } + + /** + * Creates a Tailer for the given file, with a delay other than the default 1.0s. + * @param file the file to follow. + * @param listener the TailerListener to use. + * @param delay the delay between checks of the file for new content in milliseconds. + * @param end Set to true to tail from the end of the file, false to tail from the beginning of the file. + */ + public Tailer(File file, TailerListener listener, long delay, boolean end) { + + this.file = file; + this.delay = delay; + this.end = end; + + // Save and prepare the listener + this.listener = listener; + listener.init(this); + } + + /** + * Creates and starts a Tailer for the given file. + * + * @param file the file to follow. + * @param listener the TailerListener to use. + * @param delay the delay between checks of the file for new content in milliseconds. + * @param end Set to true to tail from the end of the file, false to tail from the beginning of the file. + * @return The new tailer + */ + public static Tailer create(File file, TailerListener listener, long delay, boolean end) { + Tailer tailer = new Tailer(file, listener, delay, end); + Thread thread = new Thread(tailer); + thread.setDaemon(true); + thread.start(); + return tailer; + } + + /** + * Creates and starts a Tailer for the given file, starting at the beginning of the file + * + * @param file the file to follow. + * @param listener the TailerListener to use. + * @param delay the delay between checks of the file for new content in milliseconds. + * @return The new tailer + */ + public static Tailer create(File file, TailerListener listener, long delay) { + return create(file, listener, delay, false); + } + + /** + * Creates and starts a Tailer for the given file, starting at the beginning of the file + * with the default delay of 1.0s + * + * @param file the file to follow. + * @param listener the TailerListener to use. + * @return The new tailer + */ + public static Tailer create(File file, TailerListener listener) { + return create(file, listener, 1000, false); + } + + /** + * Return the file. + * + * @return the file + */ + public File getFile() { + return file; + } + + /** + * Return the delay. + * + * @return the delay + */ + public long getDelay() { + return delay; + } + + /** + * Follows changes in the file, calling the TailerListener's handle method for each new line. + */ + public void run() { + RandomAccessFile reader = null; + try { + long last = 0; // The last time the file was checked for changes + long position = 0; // position within the file + // Open the file + while (run && reader == null) { + try { + reader = new RandomAccessFile(file, "r"); + } catch (FileNotFoundException e) { + listener.fileNotFound(); + } + + if (reader == null) { + try { + Thread.sleep(delay); + } catch (InterruptedException e) { + } + } else { + // The current position in the file + position = end ? file.length() : 0; + last = System.currentTimeMillis(); + reader.seek(position); + } + } + + + while (run) { + + // Check the file length to see if it was rotated + long length = file.length(); + + if (length < position) { + + // File was rotated + listener.fileRotated(); + + // Reopen the reader after rotation + try { + // Ensure that the old file is closed iff we re-open it successfully + RandomAccessFile save = reader; + reader = new RandomAccessFile(file, "r"); + position = 0; + // close old file explicitly rather than relying on GC picking up previous RAF + IOUtils.closeQuietly(save); + } catch (FileNotFoundException e) { + // in this case we continue to use the previous reader and position values + listener.fileNotFound(); + } + continue; + } else { + + // File was not rotated + + // See if the file needs to be read again + if (length > position) { + + // The file has more content than it did last time + last = System.currentTimeMillis(); + position = readLines(reader); + + } else if (FileUtils.isFileNewer(file, last)) { + + /* This can happen if the file is truncated or overwritten + * with the exact same length of information. In cases like + * this, the file position needs to be reset + */ + position = 0; + reader.seek(position); // cannot be null here + + // Now we can read new lines + last = System.currentTimeMillis(); + position = readLines(reader); + } + } + try { + Thread.sleep(delay); + } catch (InterruptedException e) { + } + } + + } catch (Exception e) { + + listener.handle(e); + + } finally { + IOUtils.closeQuietly(reader); + } + } + + /** + * Allows the tailer to complete its current loop and return. + */ + public void stop() { + this.run = false; + } + + /** + * Read new lines. + * + * @param reader The file to read + * @return The new position after the lines have been read + * @throws java.io.IOException if an I/O error occurs. + */ + private long readLines(RandomAccessFile reader) throws IOException { + long pos = reader.getFilePointer(); + String line = readLine(reader); + while (line != null) { + pos = reader.getFilePointer(); + listener.handle(line); + line = readLine(reader); + } + reader.seek(pos); // Ensure we can re-read if necessary + return pos; + } + + /** + * Version of readline() that returns null on EOF rather than a partial line. + * @param reader the input file + * @return the line, or null if EOF reached before '\n' is seen. + * @throws IOException if an error occurs. + */ + private String readLine(RandomAccessFile reader) throws IOException { + StringBuffer sb = new StringBuffer(); + int ch; + boolean seenCR = false; + while((ch=reader.read()) != -1) { + switch(ch) { + case '\n': + return sb.toString(); + case '\r': + seenCR = true; + break; + default: + if (seenCR) { + sb.append('\r'); + seenCR = false; + } + sb.append((char)ch); // add character, not its ascii value + } + } + return null; + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/TailerListener.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/TailerListener.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/TailerListener.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +/** + * Listener for events from a {@link Tailer}. + * + * @version $Id: TailerListener.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + * @since Commons IO 2.0 + */ +public interface TailerListener { + + /** + * The tailer will call this method during construction, + * giving the listener a method of stopping the tailer. + * @param tailer the tailer. + */ + void init(Tailer tailer); + + /** + * This method is called if the tailed file is not found. + *

+ * Note: this is called from the tailer thread. + */ + void fileNotFound(); + + /** + * Called if a file rotation is detected. + * + * This method is called before the file is reopened, and fileNotFound may + * be called if the new file has not yet been created. + *

+ * Note: this is called from the tailer thread. + */ + void fileRotated(); + + /** + * Handles a line from a Tailer. + *

+ * Note: this is called from the tailer thread. + * @param line the line. + */ + void handle(String line); + + /** + * Handles an Exception . + *

+ * Note: this is called from the tailer thread. + * @param ex the exception. + */ + void handle(Exception ex); + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/TailerListenerAdapter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/TailerListenerAdapter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/TailerListenerAdapter.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +/** + * {@link TailerListener} Adapter. + * + * @version $Id: TailerListenerAdapter.java,v 1.1 2012/10/01 13:03:01 marcin Exp $ + * @since Commons IO 2.0 + */ +public class TailerListenerAdapter implements TailerListener { + + /** + * The tailer will call this method during construction, + * giving the listener a method of stopping the tailer. + * @param tailer the tailer. + */ + public void init(Tailer tailer) { + } + + /** + * This method is called if the tailed file is not found. + */ + public void fileNotFound() { + } + + /** + * Called if a file rotation is detected. + * + * This method is called before the file is reopened, and fileNotFound may + * be called if the new file has not yet been created. + */ + public void fileRotated() { + } + + /** + * Handles a line from a Tailer. + * @param line the line. + */ + public void handle(String line) { + } + + /** + * Handles an Exception . + * @param ex the exception. + */ + public void handle(Exception ex) { + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/TeeInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/TeeInputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/TeeInputStream.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * InputStream proxy that transparently writes a copy of all bytes read + * from the proxied stream to a given OutputStream. Using {@link #skip(long)} + * or {@link #mark(int)}/{@link #reset()} on the stream will result on some + * bytes from the input stream being skipped or duplicated in the output + * stream. + *

+ * The proxied input stream is closed when the {@link #close()} method is + * called on this proxy. It is configurable whether the associated output + * stream will also closed. + * + * @version $Id: TeeInputStream.java,v 1.1 2012/10/01 13:03:01 marcin Exp $ + * @since Commons IO 1.4 + */ +public class TeeInputStream extends ProxyInputStream { + + /** + * The output stream that will receive a copy of all bytes read from the + * proxied input stream. + */ + private final OutputStream branch; + + /** + * Flag for closing also the associated output stream when this + * stream is closed. + */ + private final boolean closeBranch; + + /** + * Creates a TeeInputStream that proxies the given {@link InputStream} + * and copies all read bytes to the given {@link OutputStream}. The given + * output stream will not be closed when this stream gets closed. + * + * @param input input stream to be proxied + * @param branch output stream that will receive a copy of all bytes read + */ + public TeeInputStream(InputStream input, OutputStream branch) { + this(input, branch, false); + } + + /** + * Creates a TeeInputStream that proxies the given {@link InputStream} + * and copies all read bytes to the given {@link OutputStream}. The given + * output stream will be closed when this stream gets closed if the + * closeBranch parameter is true. + * + * @param input input stream to be proxied + * @param branch output stream that will receive a copy of all bytes read + * @param closeBranch flag for closing also the output stream when this + * stream is closed + */ + public TeeInputStream( + InputStream input, OutputStream branch, boolean closeBranch) { + super(input); + this.branch = branch; + this.closeBranch = closeBranch; + } + + /** + * Closes the proxied input stream and, if so configured, the associated + * output stream. An exception thrown from one stream will not prevent + * closing of the other stream. + * + * @throws IOException if either of the streams could not be closed + */ + @Override + public void close() throws IOException { + try { + super.close(); + } finally { + if (closeBranch) { + branch.close(); + } + } + } + + /** + * Reads a single byte from the proxied input stream and writes it to + * the associated output stream. + * + * @return next byte from the stream, or -1 if the stream has ended + * @throws IOException if the stream could not be read (or written) + */ + @Override + public int read() throws IOException { + int ch = super.read(); + if (ch != -1) { + branch.write(ch); + } + return ch; + } + + /** + * Reads bytes from the proxied input stream and writes the read bytes + * to the associated output stream. + * + * @param bts byte buffer + * @param st start offset within the buffer + * @param end maximum number of bytes to read + * @return number of bytes read, or -1 if the stream has ended + * @throws IOException if the stream could not be read (or written) + */ + @Override + public int read(byte[] bts, int st, int end) throws IOException { + int n = super.read(bts, st, end); + if (n != -1) { + branch.write(bts, st, n); + } + return n; + } + + /** + * Reads bytes from the proxied input stream and writes the read bytes + * to the associated output stream. + * + * @param bts byte buffer + * @return number of bytes read, or -1 if the stream has ended + * @throws IOException if the stream could not be read (or written) + */ + @Override + public int read(byte[] bts) throws IOException { + int n = super.read(bts); + if (n != -1) { + branch.write(bts, 0, n); + } + return n; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/XmlStreamReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/XmlStreamReader.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/XmlStreamReader.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,752 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.text.MessageFormat; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.io.ByteOrderMark; + +/** + * Character stream that handles all the necessary Voodo to figure out the + * charset encoding of the XML document within the stream. + *

+ * IMPORTANT: This class is not related in any way to the org.xml.sax.XMLReader. + * This one IS a character stream. + *

+ * All this has to be done without consuming characters from the stream, if not + * the XML parser will not recognized the document as a valid XML. This is not + * 100% true, but it's close enough (UTF-8 BOM is not handled by all parsers + * right now, XmlStreamReader handles it and things work in all parsers). + *

+ * The XmlStreamReader class handles the charset encoding of XML documents in + * Files, raw streams and HTTP streams by offering a wide set of constructors. + *

+ * By default the charset encoding detection is lenient, the constructor with + * the lenient flag can be used for an script (following HTTP MIME and XML + * specifications). All this is nicely explained by Mark Pilgrim in his blog, + * Determining the character encoding of a feed. + *

+ * Originally developed for ROME under + * Apache License 2.0. + * + * @author Alejandro Abdelnur + * @version $Id: XmlStreamReader.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + * @see org.apache.commons.io.output.XmlStreamWriter + * @since Commons IO 2.0 + */ +public class XmlStreamReader extends Reader { + private static final int BUFFER_SIZE = 4096; + + private static final String UTF_8 = "UTF-8"; + + private static final String US_ASCII = "US-ASCII"; + + private static final String UTF_16BE = "UTF-16BE"; + + private static final String UTF_16LE = "UTF-16LE"; + + private static final String UTF_16 = "UTF-16"; + + private static final String EBCDIC = "CP1047"; + + private static final ByteOrderMark[] BOMS = new ByteOrderMark[] { + ByteOrderMark.UTF_8, + ByteOrderMark.UTF_16BE, + ByteOrderMark.UTF_16LE + }; + private static final ByteOrderMark[] XML_GUESS_BYTES = new ByteOrderMark[] { + new ByteOrderMark(UTF_8, 0x3C, 0x3F, 0x78, 0x6D), + new ByteOrderMark(UTF_16BE, 0x00, 0x3C, 0x00, 0x3F), + new ByteOrderMark(UTF_16LE, 0x3C, 0x00, 0x3F, 0x00), + new ByteOrderMark(EBCDIC, 0x4C, 0x6F, 0xA7, 0x94) + }; + + + private final Reader reader; + + private final String encoding; + + private final String defaultEncoding; + + /** + * Returns the default encoding to use if none is set in HTTP content-type, + * XML prolog and the rules based on content-type are not adequate. + *

+ * If it is NULL the content-type based rules are used. + * + * @return the default encoding to use. + */ + public String getDefaultEncoding() { + return defaultEncoding; + } + + /** + * Creates a Reader for a File. + *

+ * It looks for the UTF-8 BOM first, if none sniffs the XML prolog charset, + * if this is also missing defaults to UTF-8. + *

+ * It does a lenient charset encoding detection, check the constructor with + * the lenient parameter for details. + * + * @param file File to create a Reader from. + * @throws IOException thrown if there is a problem reading the file. + */ + public XmlStreamReader(File file) throws IOException { + this(new FileInputStream(file)); + } + + /** + * Creates a Reader for a raw InputStream. + *

+ * It follows the same logic used for files. + *

+ * It does a lenient charset encoding detection, check the constructor with + * the lenient parameter for details. + * + * @param is InputStream to create a Reader from. + * @throws IOException thrown if there is a problem reading the stream. + */ + public XmlStreamReader(InputStream is) throws IOException { + this(is, true); + } + + /** + * Creates a Reader for a raw InputStream. + *

+ * It follows the same logic used for files. + *

+ * If lenient detection is indicated and the detection above fails as per + * specifications it then attempts the following: + *

+ * If the content type was 'text/html' it replaces it with 'text/xml' and + * tries the detection again. + *

+ * Else if the XML prolog had a charset encoding that encoding is used. + *

+ * Else if the content type had a charset encoding that encoding is used. + *

+ * Else 'UTF-8' is used. + *

+ * If lenient detection is indicated an XmlStreamReaderException is never + * thrown. + * + * @param is InputStream to create a Reader from. + * @param lenient indicates if the charset encoding detection should be + * relaxed. + * @throws IOException thrown if there is a problem reading the stream. + * @throws XmlStreamReaderException thrown if the charset encoding could not + * be determined according to the specs. + */ + public XmlStreamReader(InputStream is, boolean lenient) throws IOException { + this(is, lenient, null); + } + + /** + * Creates a Reader for a raw InputStream. + *

+ * It follows the same logic used for files. + *

+ * If lenient detection is indicated and the detection above fails as per + * specifications it then attempts the following: + *

+ * If the content type was 'text/html' it replaces it with 'text/xml' and + * tries the detection again. + *

+ * Else if the XML prolog had a charset encoding that encoding is used. + *

+ * Else if the content type had a charset encoding that encoding is used. + *

+ * Else 'UTF-8' is used. + *

+ * If lenient detection is indicated an XmlStreamReaderException is never + * thrown. + * + * @param is InputStream to create a Reader from. + * @param lenient indicates if the charset encoding detection should be + * relaxed. + * @param defaultEncoding The default encoding + * @throws IOException thrown if there is a problem reading the stream. + * @throws XmlStreamReaderException thrown if the charset encoding could not + * be determined according to the specs. + */ + public XmlStreamReader(InputStream is, boolean lenient, String defaultEncoding) throws IOException { + this.defaultEncoding = defaultEncoding; + BOMInputStream bom = new BOMInputStream(new BufferedInputStream(is, BUFFER_SIZE), false, BOMS); + BOMInputStream pis = new BOMInputStream(bom, true, XML_GUESS_BYTES); + this.encoding = doRawStream(bom, pis, lenient); + this.reader = new InputStreamReader(pis, encoding); + } + + /** + * Creates a Reader using the InputStream of a URL. + *

+ * If the URL is not of type HTTP and there is not 'content-type' header in + * the fetched data it uses the same logic used for Files. + *

+ * If the URL is a HTTP Url or there is a 'content-type' header in the + * fetched data it uses the same logic used for an InputStream with + * content-type. + *

+ * It does a lenient charset encoding detection, check the constructor with + * the lenient parameter for details. + * + * @param url URL to create a Reader from. + * @throws IOException thrown if there is a problem reading the stream of + * the URL. + */ + public XmlStreamReader(URL url) throws IOException { + this(url.openConnection(), null); + } + + /** + * Creates a Reader using the InputStream of a URLConnection. + *

+ * If the URLConnection is not of type HttpURLConnection and there is not + * 'content-type' header in the fetched data it uses the same logic used for + * files. + *

+ * If the URLConnection is a HTTP Url or there is a 'content-type' header in + * the fetched data it uses the same logic used for an InputStream with + * content-type. + *

+ * It does a lenient charset encoding detection, check the constructor with + * the lenient parameter for details. + * + * @param conn URLConnection to create a Reader from. + * @param defaultEncoding The default encoding + * @throws IOException thrown if there is a problem reading the stream of + * the URLConnection. + */ + public XmlStreamReader(URLConnection conn, String defaultEncoding) throws IOException { + this.defaultEncoding = defaultEncoding; + boolean lenient = true; + String contentType = conn.getContentType(); + InputStream is = conn.getInputStream(); + BOMInputStream bom = new BOMInputStream(new BufferedInputStream(is, BUFFER_SIZE), false, BOMS); + BOMInputStream pis = new BOMInputStream(bom, true, XML_GUESS_BYTES); + if (conn instanceof HttpURLConnection || contentType != null) { + this.encoding = doHttpStream(bom, pis, contentType, lenient); + } else { + this.encoding = doRawStream(bom, pis, lenient); + } + this.reader = new InputStreamReader(pis, encoding); + } + + /** + * Creates a Reader using an InputStream an the associated content-type + * header. + *

+ * First it checks if the stream has BOM. If there is not BOM checks the + * content-type encoding. If there is not content-type encoding checks the + * XML prolog encoding. If there is not XML prolog encoding uses the default + * encoding mandated by the content-type MIME type. + *

+ * It does a lenient charset encoding detection, check the constructor with + * the lenient parameter for details. + * + * @param is InputStream to create the reader from. + * @param httpContentType content-type header to use for the resolution of + * the charset encoding. + * @throws IOException thrown if there is a problem reading the file. + */ + public XmlStreamReader(InputStream is, String httpContentType) + throws IOException { + this(is, httpContentType, true); + } + + /** + * Creates a Reader using an InputStream an the associated content-type + * header. This constructor is lenient regarding the encoding detection. + *

+ * First it checks if the stream has BOM. If there is not BOM checks the + * content-type encoding. If there is not content-type encoding checks the + * XML prolog encoding. If there is not XML prolog encoding uses the default + * encoding mandated by the content-type MIME type. + *

+ * If lenient detection is indicated and the detection above fails as per + * specifications it then attempts the following: + *

+ * If the content type was 'text/html' it replaces it with 'text/xml' and + * tries the detection again. + *

+ * Else if the XML prolog had a charset encoding that encoding is used. + *

+ * Else if the content type had a charset encoding that encoding is used. + *

+ * Else 'UTF-8' is used. + *

+ * If lenient detection is indicated an XmlStreamReaderException is never + * thrown. + * + * @param is InputStream to create the reader from. + * @param httpContentType content-type header to use for the resolution of + * the charset encoding. + * @param lenient indicates if the charset encoding detection should be + * relaxed. + * @param defaultEncoding The default encoding + * @throws IOException thrown if there is a problem reading the file. + * @throws XmlStreamReaderException thrown if the charset encoding could not + * be determined according to the specs. + */ + public XmlStreamReader(InputStream is, String httpContentType, + boolean lenient, String defaultEncoding) throws IOException { + this.defaultEncoding = defaultEncoding; + BOMInputStream bom = new BOMInputStream(new BufferedInputStream(is, BUFFER_SIZE), false, BOMS); + BOMInputStream pis = new BOMInputStream(bom, true, XML_GUESS_BYTES); + this.encoding = doHttpStream(bom, pis, httpContentType, lenient); + this.reader = new InputStreamReader(pis, encoding); + } + + /** + * Creates a Reader using an InputStream an the associated content-type + * header. This constructor is lenient regarding the encoding detection. + *

+ * First it checks if the stream has BOM. If there is not BOM checks the + * content-type encoding. If there is not content-type encoding checks the + * XML prolog encoding. If there is not XML prolog encoding uses the default + * encoding mandated by the content-type MIME type. + *

+ * If lenient detection is indicated and the detection above fails as per + * specifications it then attempts the following: + *

+ * If the content type was 'text/html' it replaces it with 'text/xml' and + * tries the detection again. + *

+ * Else if the XML prolog had a charset encoding that encoding is used. + *

+ * Else if the content type had a charset encoding that encoding is used. + *

+ * Else 'UTF-8' is used. + *

+ * If lenient detection is indicated an XmlStreamReaderException is never + * thrown. + * + * @param is InputStream to create the reader from. + * @param httpContentType content-type header to use for the resolution of + * the charset encoding. + * @param lenient indicates if the charset encoding detection should be + * relaxed. + * @throws IOException thrown if there is a problem reading the file. + * @throws XmlStreamReaderException thrown if the charset encoding could not + * be determined according to the specs. + */ + public XmlStreamReader(InputStream is, String httpContentType, + boolean lenient) throws IOException { + this(is, httpContentType, lenient, null); + } + + /** + * Returns the charset encoding of the XmlStreamReader. + * + * @return charset encoding. + */ + public String getEncoding() { + return encoding; + } + + /** + * Invokes the underlying reader's read(char[], int, int) method. + * @param buf the buffer to read the characters into + * @param offset The start offset + * @param len The number of bytes to read + * @return the number of characters read or -1 if the end of stream + * @throws IOException if an I/O error occurs + */ + @Override + public int read(char[] buf, int offset, int len) throws IOException { + return reader.read(buf, offset, len); + } + + /** + * Closes the XmlStreamReader stream. + * + * @throws IOException thrown if there was a problem closing the stream. + */ + @Override + public void close() throws IOException { + reader.close(); + } + + /** + * Process the raw stream. + * + * @param bom BOMInputStream to detect byte order marks + * @param pis BOMInputStream to guess XML encoding + * @param lenient indicates if the charset encoding detection should be + * relaxed. + * @return the encoding to be used + * @throws IOException thrown if there is a problem reading the stream. + */ + private String doRawStream(BOMInputStream bom, BOMInputStream pis, boolean lenient) + throws IOException { + String bomEnc = bom.getBOMCharsetName(); + String xmlGuessEnc = pis.getBOMCharsetName(); + String xmlEnc = getXmlProlog(pis, xmlGuessEnc); + try { + return calculateRawEncoding(bomEnc, xmlGuessEnc, xmlEnc); + } catch (XmlStreamReaderException ex) { + if (lenient) { + return doLenientDetection(null, ex); + } else { + throw ex; + } + } + } + + /** + * Process a HTTP stream. + * + * @param bom BOMInputStream to detect byte order marks + * @param pis BOMInputStream to guess XML encoding + * @param httpContentType The HTTP content type + * @param lenient indicates if the charset encoding detection should be + * relaxed. + * @return the encoding to be used + * @throws IOException thrown if there is a problem reading the stream. + */ + private String doHttpStream(BOMInputStream bom, BOMInputStream pis, String httpContentType, + boolean lenient) throws IOException { + String bomEnc = bom.getBOMCharsetName(); + String xmlGuessEnc = pis.getBOMCharsetName(); + String xmlEnc = getXmlProlog(pis, xmlGuessEnc); + try { + return calculateHttpEncoding(httpContentType, bomEnc, + xmlGuessEnc, xmlEnc, lenient); + } catch (XmlStreamReaderException ex) { + if (lenient) { + return doLenientDetection(httpContentType, ex); + } else { + throw ex; + } + } + } + + /** + * Do lenient detection. + * + * @param httpContentType content-type header to use for the resolution of + * the charset encoding. + * @param ex The thrown exception + * @return the encoding + * @throws IOException thrown if there is a problem reading the stream. + */ + private String doLenientDetection(String httpContentType, + XmlStreamReaderException ex) throws IOException { + if (httpContentType != null && httpContentType.startsWith("text/html")) { + httpContentType = httpContentType.substring("text/html".length()); + httpContentType = "text/xml" + httpContentType; + try { + return calculateHttpEncoding(httpContentType, ex.getBomEncoding(), + ex.getXmlGuessEncoding(), ex.getXmlEncoding(), true); + } catch (XmlStreamReaderException ex2) { + ex = ex2; + } + } + String encoding = ex.getXmlEncoding(); + if (encoding == null) { + encoding = ex.getContentTypeEncoding(); + } + if (encoding == null) { + encoding = (defaultEncoding == null) ? UTF_8 : defaultEncoding; + } + return encoding; + } + + /** + * Calculate the raw encoding. + * + * @param bomEnc BOM encoding + * @param xmlGuessEnc XML Guess encoding + * @param xmlEnc XML encoding + * @return the raw encoding + * @throws IOException thrown if there is a problem reading the stream. + */ + String calculateRawEncoding(String bomEnc, String xmlGuessEnc, + String xmlEnc) throws IOException { + + // BOM is Null + if (bomEnc == null) { + if (xmlGuessEnc == null || xmlEnc == null) { + return (defaultEncoding == null ? UTF_8 : defaultEncoding); + } + if (xmlEnc.equals(UTF_16) && + (xmlGuessEnc.equals(UTF_16BE) || xmlGuessEnc.equals(UTF_16LE))) { + return xmlGuessEnc; + } + return xmlEnc; + } + + // BOM is UTF-8 + if (bomEnc.equals(UTF_8)) { + if (xmlGuessEnc != null && !xmlGuessEnc.equals(UTF_8)) { + String msg = MessageFormat.format(RAW_EX_1, new Object[] { bomEnc, xmlGuessEnc, xmlEnc }); + throw new XmlStreamReaderException(msg, bomEnc, xmlGuessEnc, xmlEnc); + } + if (xmlEnc != null && !xmlEnc.equals(UTF_8)) { + String msg = MessageFormat.format(RAW_EX_1, new Object[] { bomEnc, xmlGuessEnc, xmlEnc }); + throw new XmlStreamReaderException(msg, bomEnc, xmlGuessEnc, xmlEnc); + } + return bomEnc; + } + + // BOM is UTF-16BE or UTF-16LE + if (bomEnc.equals(UTF_16BE) || bomEnc.equals(UTF_16LE)) { + if (xmlGuessEnc != null && !xmlGuessEnc.equals(bomEnc)) { + String msg = MessageFormat.format(RAW_EX_1, new Object[] { bomEnc, xmlGuessEnc, xmlEnc }); + throw new XmlStreamReaderException(msg, bomEnc, xmlGuessEnc, xmlEnc); + } + if (xmlEnc != null && !xmlEnc.equals(UTF_16) && !xmlEnc.equals(bomEnc)) { + String msg = MessageFormat.format(RAW_EX_1, new Object[] { bomEnc, xmlGuessEnc, xmlEnc }); + throw new XmlStreamReaderException(msg, bomEnc, xmlGuessEnc, xmlEnc); + } + return bomEnc; + } + + // BOM is something else + String msg = MessageFormat.format(RAW_EX_2, new Object[] { bomEnc, xmlGuessEnc, xmlEnc }); + throw new XmlStreamReaderException(msg, bomEnc, xmlGuessEnc, xmlEnc); + } + + + /** + * Calculate the HTTP encoding. + * + * @param httpContentType The HTTP content type + * @param bomEnc BOM encoding + * @param xmlGuessEnc XML Guess encoding + * @param xmlEnc XML encoding + * @param lenient indicates if the charset encoding detection should be + * relaxed. + * @return the HTTP encoding + * @throws IOException thrown if there is a problem reading the stream. + */ + String calculateHttpEncoding(String httpContentType, + String bomEnc, String xmlGuessEnc, String xmlEnc, + boolean lenient) throws IOException { + + // Lenient and has XML encoding + if (lenient && xmlEnc != null) { + return xmlEnc; + } + + // Determine mime/encoding content types from HTTP Content Type + String cTMime = getContentTypeMime(httpContentType); + String cTEnc = getContentTypeEncoding(httpContentType); + boolean appXml = isAppXml(cTMime); + boolean textXml = isTextXml(cTMime); + + // Mime type NOT "application/xml" or "text/xml" + if (!appXml && !textXml) { + String msg = MessageFormat.format(HTTP_EX_3, cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc); + throw new XmlStreamReaderException(msg, cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc); + } + + // No content type encoding + if (cTEnc == null) { + if (appXml) { + return calculateRawEncoding(bomEnc, xmlGuessEnc, xmlEnc); + } else { + return (defaultEncoding == null) ? US_ASCII : defaultEncoding; + } + } + + // UTF-16BE or UTF-16LE content type encoding + if (cTEnc.equals(UTF_16BE) || cTEnc.equals(UTF_16LE)) { + if (bomEnc != null) { + String msg = MessageFormat.format(HTTP_EX_1, cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc); + throw new XmlStreamReaderException(msg, cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc); + } + return cTEnc; + } + + // UTF-16 content type encoding + if (cTEnc.equals(UTF_16)) { + if (bomEnc != null && bomEnc.startsWith(UTF_16)) { + return bomEnc; + } + String msg = MessageFormat.format(HTTP_EX_2, cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc); + throw new XmlStreamReaderException(msg, cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc); + } + + return cTEnc; + } + + /** + * Returns MIME type or NULL if httpContentType is NULL. + * + * @param httpContentType the HTTP content type + * @return The mime content type + */ + static String getContentTypeMime(String httpContentType) { + String mime = null; + if (httpContentType != null) { + int i = httpContentType.indexOf(";"); + if (i >= 0) { + mime = httpContentType.substring(0, i); + } else { + mime = httpContentType; + } + mime = mime.trim(); + } + return mime; + } + + private static final Pattern CHARSET_PATTERN = Pattern + .compile("charset=[\"']?([.[^; \"']]*)[\"']?"); + + /** + * Returns charset parameter value, NULL if not present, NULL if + * httpContentType is NULL. + * + * @param httpContentType the HTTP content type + * @return The content type encoding + */ + static String getContentTypeEncoding(String httpContentType) { + String encoding = null; + if (httpContentType != null) { + int i = httpContentType.indexOf(";"); + if (i > -1) { + String postMime = httpContentType.substring(i + 1); + Matcher m = CHARSET_PATTERN.matcher(postMime); + encoding = (m.find()) ? m.group(1) : null; + encoding = (encoding != null) ? encoding.toUpperCase() : null; + } + } + return encoding; + } + + public static final Pattern ENCODING_PATTERN = Pattern.compile( + "<\\?xml.*encoding[\\s]*=[\\s]*((?:\".[^\"]*\")|(?:'.[^']*'))", + Pattern.MULTILINE); + + /** + * Returns the encoding declared in the , NULL if none. + * + * @param is InputStream to create the reader from. + * @param guessedEnc guessed encoding + * @return the encoding declared in the + * @throws IOException thrown if there is a problem reading the stream. + */ + private static String getXmlProlog(InputStream is, String guessedEnc) + throws IOException { + String encoding = null; + if (guessedEnc != null) { + byte[] bytes = new byte[BUFFER_SIZE]; + is.mark(BUFFER_SIZE); + int offset = 0; + int max = BUFFER_SIZE; + int c = is.read(bytes, offset, max); + int firstGT = -1; + String xmlProlog = null; + while (c != -1 && firstGT == -1 && offset < BUFFER_SIZE) { + offset += c; + max -= c; + c = is.read(bytes, offset, max); + xmlProlog = new String(bytes, 0, offset, guessedEnc); + firstGT = xmlProlog.indexOf('>'); + } + if (firstGT == -1) { + if (c == -1) { + throw new IOException("Unexpected end of XML stream"); + } else { + throw new IOException( + "XML prolog or ROOT element not found on first " + + offset + " bytes"); + } + } + int bytesRead = offset; + if (bytesRead > 0) { + is.reset(); + BufferedReader bReader = new BufferedReader(new StringReader( + xmlProlog.substring(0, firstGT + 1))); + StringBuffer prolog = new StringBuffer(); + String line = bReader.readLine(); + while (line != null) { + prolog.append(line); + line = bReader.readLine(); + } + Matcher m = ENCODING_PATTERN.matcher(prolog); + if (m.find()) { + encoding = m.group(1).toUpperCase(); + encoding = encoding.substring(1, encoding.length() - 1); + } + } + } + return encoding; + } + + /** + * Indicates if the MIME type belongs to the APPLICATION XML family. + * + * @param mime The mime type + * @return true if the mime type belongs to the APPLICATION XML family, + * otherwise false + */ + static boolean isAppXml(String mime) { + return mime != null && + (mime.equals("application/xml") || + mime.equals("application/xml-dtd") || + mime.equals("application/xml-external-parsed-entity") || + (mime.startsWith("application/") && mime.endsWith("+xml"))); + } + + /** + * Indicates if the MIME type belongs to the TEXT XML family. + * + * @param mime The mime type + * @return true if the mime type belongs to the TEXT XML family, + * otherwise false + */ + static boolean isTextXml(String mime) { + return mime != null && + (mime.equals("text/xml") || + mime.equals("text/xml-external-parsed-entity") || + (mime.startsWith("text/") && mime.endsWith("+xml"))); + } + + private static final String RAW_EX_1 = + "Invalid encoding, BOM [{0}] XML guess [{1}] XML prolog [{2}] encoding mismatch"; + + private static final String RAW_EX_2 = + "Invalid encoding, BOM [{0}] XML guess [{1}] XML prolog [{2}] unknown BOM"; + + private static final String HTTP_EX_1 = + "Invalid encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], BOM must be NULL"; + + private static final String HTTP_EX_2 = + "Invalid encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], encoding mismatch"; + + private static final String HTTP_EX_3 = + "Invalid encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], Invalid MIME"; + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/XmlStreamReaderException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/XmlStreamReaderException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/XmlStreamReaderException.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,137 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import java.io.IOException; + +/** + * The XmlStreamReaderException is thrown by the XmlStreamReader constructors if + * the charset encoding can not be determined according to the XML 1.0 + * specification and RFC 3023. + *

+ * The exception returns the unconsumed InputStream to allow the application to + * do an alternate processing with the stream. Note that the original + * InputStream given to the XmlStreamReader cannot be used as that one has been + * already read. + * + * @author Alejandro Abdelnur + * @version $Id: XmlStreamReaderException.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + * @since Commons IO 2.0 + */ +public class XmlStreamReaderException extends IOException { + + private static final long serialVersionUID = 1L; + + private final String bomEncoding; + + private final String xmlGuessEncoding; + + private final String xmlEncoding; + + private final String contentTypeMime; + + private final String contentTypeEncoding; + + /** + * Creates an exception instance if the charset encoding could not be + * determined. + *

+ * Instances of this exception are thrown by the XmlStreamReader. + * + * @param msg message describing the reason for the exception. + * @param bomEnc BOM encoding. + * @param xmlGuessEnc XML guess encoding. + * @param xmlEnc XML prolog encoding. + */ + public XmlStreamReaderException(String msg, String bomEnc, + String xmlGuessEnc, String xmlEnc) { + this(msg, null, null, bomEnc, xmlGuessEnc, xmlEnc); + } + + /** + * Creates an exception instance if the charset encoding could not be + * determined. + *

+ * Instances of this exception are thrown by the XmlStreamReader. + * + * @param msg message describing the reason for the exception. + * @param ctMime MIME type in the content-type. + * @param ctEnc encoding in the content-type. + * @param bomEnc BOM encoding. + * @param xmlGuessEnc XML guess encoding. + * @param xmlEnc XML prolog encoding. + */ + public XmlStreamReaderException(String msg, String ctMime, String ctEnc, + String bomEnc, String xmlGuessEnc, String xmlEnc) { + super(msg); + contentTypeMime = ctMime; + contentTypeEncoding = ctEnc; + bomEncoding = bomEnc; + xmlGuessEncoding = xmlGuessEnc; + xmlEncoding = xmlEnc; + } + + /** + * Returns the BOM encoding found in the InputStream. + * + * @return the BOM encoding, null if none. + */ + public String getBomEncoding() { + return bomEncoding; + } + + /** + * Returns the encoding guess based on the first bytes of the InputStream. + * + * @return the encoding guess, null if it couldn't be guessed. + */ + public String getXmlGuessEncoding() { + return xmlGuessEncoding; + } + + /** + * Returns the encoding found in the XML prolog of the InputStream. + * + * @return the encoding of the XML prolog, null if none. + */ + public String getXmlEncoding() { + return xmlEncoding; + } + + /** + * Returns the MIME type in the content-type used to attempt determining the + * encoding. + * + * @return the MIME type in the content-type, null if there was not + * content-type or the encoding detection did not involve HTTP. + */ + public String getContentTypeMime() { + return contentTypeMime; + } + + /** + * Returns the encoding in the content-type used to attempt determining the + * encoding. + * + * @return the encoding in the content-type, null if there was not + * content-type, no encoding in it or the encoding detection did not + * involve HTTP. + */ + public String getContentTypeEncoding() { + return contentTypeEncoding; + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/input/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/input/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/input/package.html 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,25 @@ + + + + +

+This package provides implementations of input classes, such as +InputStream and Reader. +

+ + Index: 3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileAlterationListener.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileAlterationListener.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileAlterationListener.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.monitor; +import java.io.File; + +/** + * A listener that receives events of file system modifications. + *

+ * Register {@link FileAlterationListener}s with a {@link FileAlterationObserver}. + * + * @see FileAlterationObserver + * @version $Id: FileAlterationListener.java,v 1.1 2012/10/01 13:03:01 marcin Exp $ + * @since Commons IO 2.0 + */ +public interface FileAlterationListener { + + /** + * File system observer started checking event. + * + * @param observer The file system observer + */ + void onStart(final FileAlterationObserver observer); + + /** + * Directory created Event. + * + * @param directory The directory created + */ + void onDirectoryCreate(final File directory); + + /** + * Directory changed Event. + * + * @param directory The directory changed + */ + void onDirectoryChange(final File directory); + + /** + * Directory deleted Event. + * + * @param directory The directory deleted + */ + void onDirectoryDelete(final File directory); + + /** + * File created Event. + * + * @param file The file created + */ + void onFileCreate(final File file); + + /** + * File changed Event. + * + * @param file The file changed + */ + void onFileChange(final File file); + + /** + * File deleted Event. + * + * @param file The file deleted + */ + void onFileDelete(final File file); + + /** + * File system observer finished checking event. + * + * @param observer The file system observer + */ + void onStop(final FileAlterationObserver observer); +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileAlterationListenerAdaptor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileAlterationListenerAdaptor.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileAlterationListenerAdaptor.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.monitor; + +import java.io.File; + +/** + * Convenience {@link FileAlterationListener} implementation that does nothing. + * + * @see FileAlterationObserver + * @version $Id: FileAlterationListenerAdaptor.java,v 1.1 2012/10/01 13:03:01 marcin Exp $ + * @since Commons IO 2.0 + */ +public class FileAlterationListenerAdaptor implements FileAlterationListener { + + /** + * File system observer started checking event. + * + * @param observer The file system observer + */ + public void onStart(final FileAlterationObserver observer) { + } + + /** + * Directory created Event. + * + * @param directory The directory created + */ + public void onDirectoryCreate(final File directory) { + } + + /** + * Directory changed Event. + * + * @param directory The directory changed + */ + public void onDirectoryChange(final File directory) { + } + + /** + * Directory deleted Event. + * + * @param directory The directory deleted + */ + public void onDirectoryDelete(final File directory) { + } + + /** + * File created Event. + * + * @param file The file created + */ + public void onFileCreate(final File file) { + } + + /** + * File changed Event. + * + * @param file The file changed + */ + public void onFileChange(final File file) { + } + + /** + * File deleted Event. + * + * @param file The file deleted + */ + public void onFileDelete(final File file) { + } + + /** + * File system observer finished checking event. + * + * @param observer The file system observer + */ + public void onStop(final FileAlterationObserver observer) { + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileAlterationMonitor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileAlterationMonitor.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileAlterationMonitor.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.monitor; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ThreadFactory; + +/** + * A runnable that spawns a monitoring thread triggering any + * registered {@link FileAlterationObserver} at a specified interval. + * + * @see FileAlterationObserver + * @version $Id: FileAlterationMonitor.java,v 1.1 2012/10/01 13:03:01 marcin Exp $ + * @since Commons IO 2.0 + */ +public final class FileAlterationMonitor implements Runnable { + + private final long interval; + private final List observers = new CopyOnWriteArrayList(); + private Thread thread = null; + private ThreadFactory threadFactory; + private volatile boolean running = false; + + /** + * Construct a monitor with a default interval of 10 seconds. + */ + public FileAlterationMonitor() { + this(10000); + } + + /** + * Construct a monitor with the specified interval. + * + * @param interval The amount of time in miliseconds to wait between + * checks of the file system + */ + public FileAlterationMonitor(long interval) { + this.interval = interval; + } + + /** + * Construct a monitor with the specified interval and set of observers. + * + * @param interval The amount of time in miliseconds to wait between + * checks of the file system + * @param observers The set of observers to add to the monitor. + */ + public FileAlterationMonitor(long interval, FileAlterationObserver... observers) { + this(interval); + if (observers != null) { + for (FileAlterationObserver observer : observers) { + addObserver(observer); + } + } + } + + /** + * Return the interval. + * + * @return the interval + */ + public long getInterval() { + return interval; + } + + /** + * Set the thread factory. + * + * @param threadFactory the thread factory + */ + public synchronized void setThreadFactory(ThreadFactory threadFactory) { + this.threadFactory = threadFactory; + } + + /** + * Add a file system observer to this monitor. + * + * @param observer The file system observer to add + */ + public void addObserver(final FileAlterationObserver observer) { + if (observer != null) { + observers.add(observer); + } + } + + /** + * Remove a file system observer from this monitor. + * + * @param observer The file system observer to remove + */ + public void removeObserver(final FileAlterationObserver observer) { + if (observer != null) { + while (observers.remove(observer)) { + } + } + } + + /** + * Returns the set of {@link FileAlterationObserver} registered with + * this monitor. + * + * @return The set of {@link FileAlterationObserver} + */ + public Iterable getObservers() { + return observers; + } + + /** + * Start monitoring. + * + * @throws Exception if an error occurs initializing the observer + */ + public synchronized void start() throws Exception { + if (running) { + throw new IllegalStateException("Monitor is already running"); + } + for (FileAlterationObserver observer : observers) { + observer.initialize(); + } + running = true; + if (threadFactory != null) { + thread = threadFactory.newThread(this); + } else { + thread = new Thread(this); + } + thread.start(); + } + + /** + * Stop monitoring. + * + * @throws Exception if an error occurs initializing the observer + */ + public synchronized void stop() throws Exception { + stop(interval); + } + + /** + * Stop monitoring. + * + * @param stopInterval the amount of time in milliseconds to wait for the thread to finish. + * A value of zero will wait until the thread is finished (see {@link Thread#join(long)}). + * @throws Exception if an error occurs initializing the observer + * @since Commons IO 2.1 + */ + public synchronized void stop(long stopInterval) throws Exception { + if (running == false) { + throw new IllegalStateException("Monitor is not running"); + } + running = false; + try { + thread.join(stopInterval); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + for (FileAlterationObserver observer : observers) { + observer.destroy(); + } + } + + /** + * Run. + */ + public void run() { + while (running) { + for (FileAlterationObserver observer : observers) { + observer.checkAndNotify(); + } + if (!running) { + break; + } + try { + Thread.sleep(interval); + } catch (final InterruptedException ignored) { + } + } + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileAlterationObserver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileAlterationObserver.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileAlterationObserver.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,464 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.monitor; + +import java.io.File; +import java.io.FileFilter; +import java.io.Serializable; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOCase; +import org.apache.commons.io.comparator.NameFileComparator; + +/** + * FileAlterationObserver represents the state of files below a root directory, + * checking the filesystem and notifying listeners of create, change or + * delete events. + *

+ * To use this implementation: + *

    + *
  • Create {@link FileAlterationListener} implementation(s) that process + * the file/directory create, change and delete events
  • + *
  • Register the listener(s) with a {@link FileAlterationObserver} for + * the appropriate directory.
  • + *
  • Either register the observer(s) with a {@link FileAlterationMonitor} or + * run manually.
  • + *
+ * + *

Basic Usage

+ * Create a {@link FileAlterationObserver} for the directory and register the listeners: + *
+ *      File directory = new File(new File("."), "src");
+ *      FileAlterationObserver observer = new FileAlterationObserver(directory);
+ *      observer.addListener(...);
+ *      observer.addListener(...);
+ * 
+ * To manually observe a directory, initialize the observer and invoked the + * {@link #checkAndNotify()} method as required: + *
+ *      // intialize
+ *      observer.init();
+ *      ...
+ *      // invoke as required
+ *      observer.checkAndNotify();
+ *      ...
+ *      observer.checkAndNotify();
+ *      ...
+ *      // finished
+ *      observer.finish();
+ * 
+ * Alternatively, register the oberver(s) with a {@link FileAlterationMonitor}, + * which creates a new thread, invoking the observer at the specified interval: + *
+ *      long interval = ...
+ *      FileAlterationMonitor monitor = new FileAlterationMonitor(interval);
+ *      monitor.addObserver(observer);
+ *      monitor.start();
+ *      ...
+ *      monitor.stop();
+ * 
+ * + *

File Filters

+ * This implementation can monitor portions of the file system + * by using {@link FileFilter}s to observe only the files and/or directories + * that are of interest. This makes it more efficient and reduces the + * noise from unwanted file system events. + *

+ * Commons IO has a good range of + * useful, ready made + * File Filter + * implementations for this purpose. + *

+ * For example, to only observe 1) visible directories and 2) files with a ".java" suffix + * in a root directory called "src" you could set up a {@link FileAlterationObserver} in the following + * way: + *

+ *      // Create a FileFilter
+ *      IOFileFilter directories = FileFilterUtils.and(
+ *                                      FileFilterUtils.directoryFileFilter(),
+ *                                      HiddenFileFilter.VISIBLE);
+ *      IOFileFilter files       = FileFilterUtils.and(
+ *                                      FileFilterUtils.fileFileFilter(),
+ *                                      FileFilterUtils.suffixFileFilter(".java"));
+ *      IOFileFilter filter = FileFilterUtils.or(directories, files);
+ *
+ *      // Create the File system observer and register File Listeners
+ *      FileAlterationObserver observer = new FileAlterationObserver(new File("src"), filter);
+ *      observer.addListener(...);
+ *      observer.addListener(...);
+ * 
+ * + *

FileEntry

+ * {@link FileEntry} represents the state of a file or directory, capturing + * {@link File} attributes at a point in time. Custom implementations of + * {@link FileEntry} can be used to capture additional properties that the + * basic implementation does not support. The {@link FileEntry#refresh(File)} + * method is used to determine if a file or directory has changed since the last + * check and stores the current state of the {@link File}'s properties. + * + * @see FileAlterationListener + * @see FileAlterationMonitor + * @version $Id: FileAlterationObserver.java,v 1.1 2012/10/01 13:03:01 marcin Exp $ + * @since Commons IO 2.0 + */ +public class FileAlterationObserver implements Serializable { + + private final List listeners = new CopyOnWriteArrayList(); + private final FileEntry rootEntry; + private final FileFilter fileFilter; + private final Comparator comparator; + + /** + * Construct an observer for the specified directory. + * + * @param directoryName the name of the directory to observe + */ + public FileAlterationObserver(String directoryName) { + this(new File(directoryName)); + } + + /** + * Construct an observer for the specified directory and file filter. + * + * @param directoryName the name of the directory to observe + * @param fileFilter The file filter or null if none + */ + public FileAlterationObserver(String directoryName, FileFilter fileFilter) { + this(new File(directoryName), fileFilter); + } + + /** + * Construct an observer for the specified directory, file filter and + * file comparator. + * + * @param directoryName the name of the directory to observe + * @param fileFilter The file filter or null if none + * @param caseSensitivity what case sensitivity to use comparing file names, null means system sensitive + */ + public FileAlterationObserver(String directoryName, FileFilter fileFilter, IOCase caseSensitivity) { + this(new File(directoryName), fileFilter, caseSensitivity); + } + + /** + * Construct an observer for the specified directory. + * + * @param directory the directory to observe + */ + public FileAlterationObserver(File directory) { + this(directory, (FileFilter)null); + } + + /** + * Construct an observer for the specified directory and file filter. + * + * @param directory the directory to observe + * @param fileFilter The file filter or null if none + */ + public FileAlterationObserver(File directory, FileFilter fileFilter) { + this(directory, fileFilter, (IOCase)null); + } + + /** + * Construct an observer for the specified directory, file filter and + * file comparator. + * + * @param directory the directory to observe + * @param fileFilter The file filter or null if none + * @param caseSensitivity what case sensitivity to use comparing file names, null means system sensitive + */ + public FileAlterationObserver(File directory, FileFilter fileFilter, IOCase caseSensitivity) { + this(new FileEntry(directory), fileFilter, caseSensitivity); + } + + /** + * Construct an observer for the specified directory, file filter and + * file comparator. + * + * @param rootEntry the root directory to observe + * @param fileFilter The file filter or null if none + * @param caseSensitivity what case sensitivity to use comparing file names, null means system sensitive + */ + protected FileAlterationObserver(FileEntry rootEntry, FileFilter fileFilter, IOCase caseSensitivity) { + if (rootEntry == null) { + throw new IllegalArgumentException("Root entry is missing"); + } + if (rootEntry.getFile() == null) { + throw new IllegalArgumentException("Root directory is missing"); + } + this.rootEntry = rootEntry; + this.fileFilter = fileFilter; + if (caseSensitivity == null || caseSensitivity.equals(IOCase.SYSTEM)) { + this.comparator = NameFileComparator.NAME_SYSTEM_COMPARATOR; + } else if (caseSensitivity.equals(IOCase.INSENSITIVE)) { + this.comparator = NameFileComparator.NAME_INSENSITIVE_COMPARATOR; + } else { + this.comparator = NameFileComparator.NAME_COMPARATOR; + } + } + + /** + * Return the directory being observed. + * + * @return the directory being observed + */ + public File getDirectory() { + return rootEntry.getFile(); + } + + /** + * Return the fileFilter. + * + * @return the fileFilter + * @since Commons IO 2.1 + */ + public FileFilter getFileFilter() { + return fileFilter; + } + + /** + * Add a file system listener. + * + * @param listener The file system listener + */ + public void addListener(final FileAlterationListener listener) { + if (listener != null) { + listeners.add(listener); + } + } + + /** + * Remove a file system listener. + * + * @param listener The file system listener + */ + public void removeListener(final FileAlterationListener listener) { + if (listener != null) { + while (listeners.remove(listener)) { + } + } + } + + /** + * Returns the set of registered file system listeners. + * + * @return The file system listeners + */ + public Iterable getListeners() { + return listeners; + } + + /** + * Initialize the observer. + * + * @throws Exception if an error occurs + */ + public void initialize() throws Exception { + rootEntry.refresh(rootEntry.getFile()); + File[] files = listFiles(rootEntry.getFile()); + FileEntry[] children = files.length > 0 ? new FileEntry[files.length] : FileEntry.EMPTY_ENTRIES; + for (int i = 0; i < files.length; i++) { + children[i] = createFileEntry(rootEntry, files[i]); + } + rootEntry.setChildren(children); + } + + /** + * Final processing. + * + * @throws Exception if an error occurs + */ + public void destroy() throws Exception { + } + + /** + * Check whether the file and its chlidren have been created, modified or deleted. + */ + public void checkAndNotify() { + + /* fire onStart() */ + for (FileAlterationListener listener : listeners) { + listener.onStart(this); + } + + /* fire directory/file events */ + File rootFile = rootEntry.getFile(); + if (rootFile.exists()) { + checkAndNotify(rootEntry, rootEntry.getChildren(), listFiles(rootFile)); + } else if (rootEntry.isExists()) { + checkAndNotify(rootEntry, rootEntry.getChildren(), FileUtils.EMPTY_FILE_ARRAY); + } else { + // Didn't exist and still doesn't + } + + /* fire onStop() */ + for (FileAlterationListener listener : listeners) { + listener.onStop(this); + } + } + + /** + * Compare two file lists for files which have been created, modified or deleted. + * + * @param parent The parent entry + * @param previous The original list of files + * @param files The current list of files + */ + private void checkAndNotify(FileEntry parent, FileEntry[] previous, File[] files) { + int c = 0; + FileEntry[] current = files.length > 0 ? new FileEntry[files.length] : FileEntry.EMPTY_ENTRIES; + for (FileEntry entry : previous) { + while (c < files.length && comparator.compare(entry.getFile(), files[c]) > 0) { + current[c] = createFileEntry(parent, files[c]); + doCreate(current[c]); + c++; + } + if (c < files.length && comparator.compare(entry.getFile(), files[c]) == 0) { + doMatch(entry, files[c]); + checkAndNotify(entry, entry.getChildren(), listFiles(files[c])); + current[c] = entry; + c++; + } else { + checkAndNotify(entry, entry.getChildren(), FileUtils.EMPTY_FILE_ARRAY); + doDelete(entry); + } + } + for (; c < files.length; c++) { + current[c] = createFileEntry(parent, files[c]); + doCreate(current[c]); + } + parent.setChildren(current); + } + + /** + * Create a new file entry for the specified file. + * + * @param parent The parent file entry + * @param file The file to create an entry for + * @return A new file entry + */ + private FileEntry createFileEntry(FileEntry parent, File file) { + FileEntry entry = parent.newChildInstance(file); + entry.refresh(file); + File[] files = listFiles(file); + FileEntry[] children = files.length > 0 ? new FileEntry[files.length] : FileEntry.EMPTY_ENTRIES; + for (int i = 0; i < files.length; i++) { + children[i] = createFileEntry(entry, files[i]); + } + entry.setChildren(children); + return entry; + } + + /** + * Fire directory/file created events to the registered listeners. + * + * @param entry The file entry + */ + private void doCreate(FileEntry entry) { + for (FileAlterationListener listener : listeners) { + if (entry.isDirectory()) { + listener.onDirectoryCreate(entry.getFile()); + } else { + listener.onFileCreate(entry.getFile()); + } + } + FileEntry[] children = entry.getChildren(); + for (FileEntry aChildren : children) { + doCreate(aChildren); + } + } + + /** + * Fire directory/file change events to the registered listeners. + * + * @param entry The previous file system entry + * @param file The current file + */ + private void doMatch(FileEntry entry, File file) { + if (entry.refresh(file)) { + for (FileAlterationListener listener : listeners) { + if (entry.isDirectory()) { + listener.onDirectoryChange(file); + } else { + listener.onFileChange(file); + } + } + } + } + + /** + * Fire directory/file delete events to the registered listeners. + * + * @param entry The file entry + */ + private void doDelete(FileEntry entry) { + for (FileAlterationListener listener : listeners) { + if (entry.isDirectory()) { + listener.onDirectoryDelete(entry.getFile()); + } else { + listener.onFileDelete(entry.getFile()); + } + } + } + + /** + * List the contents of a directory + * + * @param file The file to list the contents of + * @return the directory contents or a zero length array if + * the empty or the file is not a directory + */ + private File[] listFiles(File file) { + File[] children = null; + if (file.isDirectory()) { + children = (fileFilter == null) ? file.listFiles() : file.listFiles(fileFilter); + } + if (children == null) { + children = FileUtils.EMPTY_FILE_ARRAY; + } + if (comparator != null && children.length > 1) { + Arrays.sort(children, comparator); + } + return children; + } + + /** + * Provide a String representation of this observer. + * + * @return a String representation of this observer + */ + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(getClass().getSimpleName()); + builder.append("[file='"); + builder.append(getDirectory().getPath()); + builder.append('\''); + if (fileFilter != null) { + builder.append(", "); + builder.append(fileFilter.toString()); + } + builder.append(", listeners="); + builder.append(listeners.size()); + builder.append("]"); + return builder.toString(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileEntry.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileEntry.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/monitor/FileEntry.java 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,268 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.monitor; + +import java.io.File; +import java.io.Serializable; + +/** + * {@link FileEntry} represents the state of a file or directory, capturing + * the following {@link File} attributes at a point in time. + *
    + *
  • File Name (see {@link File#getName()})
  • + *
  • Exists - whether the file exists or not (see {@link File#exists()})
  • + *
  • Directory - whether the file is a directory or not (see {@link File#isDirectory()})
  • + *
  • Last Modified Date/Time (see {@link File#lastModified()})
  • + *
  • Length (see {@link File#length()}) - directories treated as zero
  • + *
  • Children - contents of a directory (see {@link File#listFiles(java.io.FileFilter)})
  • + *
+ *

+ *

Custom Implementations

+ * If the state of additional {@link File} attributes is required then create a custom + * {@link FileEntry} with properties for those attributes. Override the + * {@link #newChildInstance(File)} to return a new instance of the appropriate type. + * You may also want to override the {@link #refresh(File)} method. + * @see FileAlterationObserver + * @since Commons IO 2.0 + */ +public class FileEntry implements Serializable { + + static final FileEntry[] EMPTY_ENTRIES = new FileEntry[0]; + + private final FileEntry parent; + private FileEntry[] children; + private final File file; + private String name; + private boolean exists; + private boolean directory; + private long lastModified; + private long length; + + /** + * Construct a new monitor for a specified {@link File}. + * + * @param file The file being monitored + */ + public FileEntry(File file) { + this((FileEntry)null, file); + } + + /** + * Construct a new monitor for a specified {@link File}. + * + * @param parent The parent + * @param file The file being monitored + */ + public FileEntry(FileEntry parent, File file) { + if (file == null) { + throw new IllegalArgumentException("File is missing"); + } + this.file = file; + this.parent = parent; + this.name = file.getName(); + } + + /** + * Refresh the attributes from the {@link File}, indicating + * whether the file has changed. + *

+ * This implementation refreshes the name, exists, + * directory, lastModified and length + * properties. + *

+ * The exists, directory, lastModified + * and length properties are compared for changes + * + * @param file the file instance to compare to + * @return true if the file has changed, otherwise false + */ + public boolean refresh(File file) { + + // cache original values + boolean origExists = exists; + long origLastModified = lastModified; + boolean origDirectory = directory; + long origLength = length; + + // refresh the values + name = file.getName(); + exists = file.exists(); + directory = (exists ? file.isDirectory() : false); + lastModified = (exists ? file.lastModified() : 0); + length = (exists && !directory ? file.length() : 0); + + // Return if there are changes + return (exists != origExists || + lastModified != origLastModified || + directory != origDirectory || + length != origLength); + } + + /** + * Create a new child instance. + *

+ * Custom implementations should override this method to return + * a new instance of the appropriate type. + * + * @param file The child file + * @return a new child instance + */ + public FileEntry newChildInstance(File file) { + return new FileEntry(this, file); + } + + /** + * Return the parent entry. + * + * @return the parent entry + */ + public FileEntry getParent() { + return parent; + } + + /** + * Return the level + * + * @return the level + */ + public int getLevel() { + return parent == null ? 0 : parent.getLevel() + 1; + } + + /** + * Return the directory's files. + * + * @return This directory's files or an empty + * array if the file is not a directory or the + * directory is empty + */ + public FileEntry[] getChildren() { + return children != null ? children : EMPTY_ENTRIES; + } + + /** + * Set the directory's files. + * + * @param children This directory's files, may be null + */ + public void setChildren(FileEntry[] children) { + this.children = children; + } + + /** + * Return the file being monitored. + * + * @return the file being monitored + */ + public File getFile() { + return file; + } + + /** + * Return the file name. + * + * @return the file name + */ + public String getName() { + return name; + } + + /** + * Set the file name. + * + * @param name the file name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Return the last modified time from the last time it + * was checked. + * + * @return the last modified time + */ + public long getLastModified() { + return lastModified; + } + + /** + * Return the last modified time from the last time it + * was checked. + * + * @param lastModified The last modified time + */ + public void setLastModified(long lastModified) { + this.lastModified = lastModified; + } + + /** + * Return the length. + * + * @return the length + */ + public long getLength() { + return length; + } + + /** + * Set the length. + * + * @param length the length + */ + public void setLength(long length) { + this.length = length; + } + + /** + * Indicate whether the file existed the last time it + * was checked. + * + * @return whether the file existed + */ + public boolean isExists() { + return exists; + } + + /** + * Set whether the file existed the last time it + * was checked. + * + * @param exists whether the file exists or not + */ + public void setExists(boolean exists) { + this.exists = exists; + } + + /** + * Indicate whether the file is a directory or not. + * + * @return whether the file is a directory or not + */ + public boolean isDirectory() { + return directory; + } + + /** + * Set whether the file is a directory or not. + * + * @param directory whether the file is a directory or not + */ + public void setDirectory(boolean directory) { + this.directory = directory; + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/monitor/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/monitor/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/monitor/package.html 1 Oct 2012 13:03:01 -0000 1.1 @@ -0,0 +1,25 @@ + + + + +

+This package provides a component for monitoring file system events +(directory and file create, update and delete events). +

+ + Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/BrokenOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/BrokenOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/BrokenOutputStream.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Broken output stream. This stream always throws an {@link IOException} from + * all {@link OutputStream} methods. + *

+ * This class is mostly useful for testing error handling in code that uses an + * output stream. + * + * @since Commons IO 2.0 + */ +public class BrokenOutputStream extends OutputStream { + + /** + * The exception that is thrown by all methods of this class. + */ + private final IOException exception; + + /** + * Creates a new stream that always throws the given exception. + * + * @param exception the exception to be thrown + */ + public BrokenOutputStream(IOException exception) { + this.exception = exception; + } + + /** + * Creates a new stream that always throws an {@link IOException} + */ + public BrokenOutputStream() { + this(new IOException("Broken output stream")); + } + + /** + * Throws the configured exception. + * + * @param b ignored + * @throws IOException always thrown + */ + @Override + public void write(int b) throws IOException { + throw exception; + } + + /** + * Throws the configured exception. + * + * @throws IOException always thrown + */ + @Override + public void flush() throws IOException { + throw exception; + } + + /** + * Throws the configured exception. + * + * @throws IOException always thrown + */ + @Override + public void close() throws IOException { + throw exception; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/ByteArrayOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/ByteArrayOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/ByteArrayOutputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,361 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.SequenceInputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.io.input.ClosedInputStream; + +/** + * This class implements an output stream in which the data is + * written into a byte array. The buffer automatically grows as data + * is written to it. + *

+ * The data can be retrieved using toByteArray() and + * toString(). + *

+ * Closing a ByteArrayOutputStream has no effect. The methods in + * this class can be called after the stream has been closed without + * generating an IOException. + *

+ * This is an alternative implementation of the {@link java.io.ByteArrayOutputStream} + * class. The original implementation only allocates 32 bytes at the beginning. + * As this class is designed for heavy duty it starts at 1024 bytes. In contrast + * to the original it doesn't reallocate the whole memory block but allocates + * additional buffers. This way no buffers need to be garbage collected and + * the contents don't have to be copied to the new buffer. This class is + * designed to behave exactly like the original. The only exception is the + * deprecated toString(int) method that has been ignored. + * + * @author Jeremias Maerki + * @author Holger Hoffstatte + * @version $Id: ByteArrayOutputStream.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + */ +public class ByteArrayOutputStream extends OutputStream { + + /** A singleton empty byte array. */ + private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + + /** The list of buffers, which grows and never reduces. */ + private final List buffers = new ArrayList(); + /** The index of the current buffer. */ + private int currentBufferIndex; + /** The total count of bytes in all the filled buffers. */ + private int filledBufferSum; + /** The current buffer. */ + private byte[] currentBuffer; + /** The total count of bytes written. */ + private int count; + + /** + * Creates a new byte array output stream. The buffer capacity is + * initially 1024 bytes, though its size increases if necessary. + */ + public ByteArrayOutputStream() { + this(1024); + } + + /** + * Creates a new byte array output stream, with a buffer capacity of + * the specified size, in bytes. + * + * @param size the initial size + * @throws IllegalArgumentException if size is negative + */ + public ByteArrayOutputStream(int size) { + if (size < 0) { + throw new IllegalArgumentException( + "Negative initial size: " + size); + } + synchronized (this) { + needNewBuffer(size); + } + } + + /** + * Makes a new buffer available either by allocating + * a new one or re-cycling an existing one. + * + * @param newcount the size of the buffer if one is created + */ + private void needNewBuffer(int newcount) { + if (currentBufferIndex < buffers.size() - 1) { + //Recycling old buffer + filledBufferSum += currentBuffer.length; + + currentBufferIndex++; + currentBuffer = buffers.get(currentBufferIndex); + } else { + //Creating new buffer + int newBufferSize; + if (currentBuffer == null) { + newBufferSize = newcount; + filledBufferSum = 0; + } else { + newBufferSize = Math.max( + currentBuffer.length << 1, + newcount - filledBufferSum); + filledBufferSum += currentBuffer.length; + } + + currentBufferIndex++; + currentBuffer = new byte[newBufferSize]; + buffers.add(currentBuffer); + } + } + + /** + * Write the bytes to byte array. + * @param b the bytes to write + * @param off The start offset + * @param len The number of bytes to write + */ + @Override + public void write(byte[] b, int off, int len) { + if ((off < 0) + || (off > b.length) + || (len < 0) + || ((off + len) > b.length) + || ((off + len) < 0)) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + synchronized (this) { + int newcount = count + len; + int remaining = len; + int inBufferPos = count - filledBufferSum; + while (remaining > 0) { + int part = Math.min(remaining, currentBuffer.length - inBufferPos); + System.arraycopy(b, off + len - remaining, currentBuffer, inBufferPos, part); + remaining -= part; + if (remaining > 0) { + needNewBuffer(newcount); + inBufferPos = 0; + } + } + count = newcount; + } + } + + /** + * Write a byte to byte array. + * @param b the byte to write + */ + @Override + public synchronized void write(int b) { + int inBufferPos = count - filledBufferSum; + if (inBufferPos == currentBuffer.length) { + needNewBuffer(count + 1); + inBufferPos = 0; + } + currentBuffer[inBufferPos] = (byte) b; + count++; + } + + /** + * Writes the entire contents of the specified input stream to this + * byte stream. Bytes from the input stream are read directly into the + * internal buffers of this streams. + * + * @param in the input stream to read from + * @return total number of bytes read from the input stream + * (and written to this stream) + * @throws IOException if an I/O error occurs while reading the input stream + * @since Commons IO 1.4 + */ + public synchronized int write(InputStream in) throws IOException { + int readCount = 0; + int inBufferPos = count - filledBufferSum; + int n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos); + while (n != -1) { + readCount += n; + inBufferPos += n; + count += n; + if (inBufferPos == currentBuffer.length) { + needNewBuffer(currentBuffer.length); + inBufferPos = 0; + } + n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos); + } + return readCount; + } + + /** + * Return the current size of the byte array. + * @return the current size of the byte array + */ + public synchronized int size() { + return count; + } + + /** + * Closing a ByteArrayOutputStream has no effect. The methods in + * this class can be called after the stream has been closed without + * generating an IOException. + * + * @throws IOException never (this method should not declare this exception + * but it has to now due to backwards compatability) + */ + @Override + public void close() throws IOException { + //nop + } + + /** + * @see java.io.ByteArrayOutputStream#reset() + */ + public synchronized void reset() { + count = 0; + filledBufferSum = 0; + currentBufferIndex = 0; + currentBuffer = buffers.get(currentBufferIndex); + } + + /** + * Writes the entire contents of this byte stream to the + * specified output stream. + * + * @param out the output stream to write to + * @throws IOException if an I/O error occurs, such as if the stream is closed + * @see java.io.ByteArrayOutputStream#writeTo(OutputStream) + */ + public synchronized void writeTo(OutputStream out) throws IOException { + int remaining = count; + for (byte[] buf : buffers) { + int c = Math.min(buf.length, remaining); + out.write(buf, 0, c); + remaining -= c; + if (remaining == 0) { + break; + } + } + } + + /** + * Fetches entire contents of an InputStream and represent + * same data as result InputStream. + *

+ * This method is useful where, + *

    + *
  • Source InputStream is slow.
  • + *
  • It has network resources associated, so we cannot keep it open for + * long time.
  • + *
  • It has network timeout associated.
  • + *
+ * It can be used in favor of {@link #toByteArray()}, since it + * avoids unnecessary allocation and copy of byte[].
+ * This method buffers the input internally, so there is no need to use a + * BufferedInputStream. + * + * @param input Stream to be fully buffered. + * @return A fully buffered stream. + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + public static InputStream toBufferedInputStream(InputStream input) + throws IOException { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + output.write(input); + return output.toBufferedInputStream(); + } + + /** + * Gets the current contents of this byte stream as a Input Stream. The + * returned stream is backed by buffers of this stream, + * avoiding memory allocation and copy, thus saving space and time.
+ * + * @return the current contents of this output stream. + * @see java.io.ByteArrayOutputStream#toByteArray() + * @see #reset() + * @since Commons IO 2.0 + */ + private InputStream toBufferedInputStream() { + int remaining = count; + if (remaining == 0) { + return new ClosedInputStream(); + } + List list = new ArrayList(buffers.size()); + for (byte[] buf : buffers) { + int c = Math.min(buf.length, remaining); + list.add(new ByteArrayInputStream(buf, 0, c)); + remaining -= c; + if (remaining == 0) { + break; + } + } + return new SequenceInputStream(Collections.enumeration(list)); + } + + /** + * Gets the curent contents of this byte stream as a byte array. + * The result is independent of this stream. + * + * @return the current contents of this output stream, as a byte array + * @see java.io.ByteArrayOutputStream#toByteArray() + */ + public synchronized byte[] toByteArray() { + int remaining = count; + if (remaining == 0) { + return EMPTY_BYTE_ARRAY; + } + byte newbuf[] = new byte[remaining]; + int pos = 0; + for (byte[] buf : buffers) { + int c = Math.min(buf.length, remaining); + System.arraycopy(buf, 0, newbuf, pos, c); + pos += c; + remaining -= c; + if (remaining == 0) { + break; + } + } + return newbuf; + } + + /** + * Gets the curent contents of this byte stream as a string. + * @return the contents of the byte array as a String + * @see java.io.ByteArrayOutputStream#toString() + */ + @Override + public String toString() { + return new String(toByteArray()); + } + + /** + * Gets the curent contents of this byte stream as a string + * using the specified encoding. + * + * @param enc the name of the character encoding + * @return the string converted from the byte array + * @throws UnsupportedEncodingException if the encoding is not supported + * @see java.io.ByteArrayOutputStream#toString(String) + */ + public String toString(String enc) throws UnsupportedEncodingException { + return new String(toByteArray(), enc); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/CloseShieldOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/CloseShieldOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/CloseShieldOutputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.OutputStream; + +/** + * Proxy stream that prevents the underlying output stream from being closed. + *

+ * This class is typically used in cases where an output stream needs to be + * passed to a component that wants to explicitly close the stream even if + * other components would still use the stream for output. + * + * @version $Id: CloseShieldOutputStream.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + * @since Commons IO 1.4 + */ +public class CloseShieldOutputStream extends ProxyOutputStream { + + /** + * Creates a proxy that shields the given output stream from being + * closed. + * + * @param out underlying output stream + */ + public CloseShieldOutputStream(OutputStream out) { + super(out); + } + + /** + * Replaces the underlying output stream with a {@link ClosedOutputStream} + * sentinel. The original output stream will remain open, but this proxy + * will appear closed. + */ + @Override + public void close() { + out = new ClosedOutputStream(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/ClosedOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/ClosedOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/ClosedOutputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Closed output stream. This stream throws an exception on all attempts to + * write something to the stream. + *

+ * Typically uses of this class include testing for corner cases in methods + * that accept an output stream and acting as a sentinel value instead of + * a null output stream. + * + * @version $Id: ClosedOutputStream.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + * @since Commons IO 1.4 + */ +public class ClosedOutputStream extends OutputStream { + + /** + * A singleton. + */ + public static final ClosedOutputStream CLOSED_OUTPUT_STREAM = new ClosedOutputStream(); + + /** + * Throws an {@link IOException} to indicate that the stream is closed. + * + * @param b ignored + * @throws IOException always thrown + */ + @Override + public void write(int b) throws IOException { + throw new IOException("write(" + b + ") failed: stream is closed"); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/CountingOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/CountingOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/CountingOutputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.OutputStream; + +/** + * A decorating output stream that counts the number of bytes that have passed + * through the stream so far. + *

+ * A typical use case would be during debugging, to ensure that data is being + * written as expected. + * + * @version $Id: CountingOutputStream.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + */ +public class CountingOutputStream extends ProxyOutputStream { + + /** The count of bytes that have passed. */ + private long count = 0; + + /** + * Constructs a new CountingOutputStream. + * + * @param out the OutputStream to write to + */ + public CountingOutputStream( OutputStream out ) { + super(out); + } + + //----------------------------------------------------------------------- + + /** + * Updates the count with the number of bytes that are being written. + * + * @param n number of bytes to be written to the stream + * @since Commons IO 2.0 + */ + @Override + protected synchronized void beforeWrite(int n) { + count += n; + } + + //----------------------------------------------------------------------- + /** + * The number of bytes that have passed through this stream. + *

+ * NOTE: From v1.3 this method throws an ArithmeticException if the + * count is greater than can be expressed by an int. + * See {@link #getByteCount()} for a method using a long. + * + * @return the number of bytes accumulated + * @throws ArithmeticException if the byte count is too large + */ + public int getCount() { + long result = getByteCount(); + if (result > Integer.MAX_VALUE) { + throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int"); + } + return (int) result; + } + + /** + * Set the byte count back to 0. + *

+ * NOTE: From v1.3 this method throws an ArithmeticException if the + * count is greater than can be expressed by an int. + * See {@link #resetByteCount()} for a method using a long. + * + * @return the count previous to resetting + * @throws ArithmeticException if the byte count is too large + */ + public int resetCount() { + long result = resetByteCount(); + if (result > Integer.MAX_VALUE) { + throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int"); + } + return (int) result; + } + + /** + * The number of bytes that have passed through this stream. + *

+ * NOTE: This method is an alternative for getCount(). + * It was added because that method returns an integer which will + * result in incorrect count for files over 2GB. + * + * @return the number of bytes accumulated + * @since Commons IO 1.3 + */ + public synchronized long getByteCount() { + return this.count; + } + + /** + * Set the byte count back to 0. + *

+ * NOTE: This method is an alternative for resetCount(). + * It was added because that method returns an integer which will + * result in incorrect count for files over 2GB. + * + * @return the count previous to resetting + * @since Commons IO 1.3 + */ + public synchronized long resetByteCount() { + long tmp = this.count; + this.count = 0; + return tmp; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/DeferredFileOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/DeferredFileOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/DeferredFileOutputStream.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,286 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.commons.io.IOUtils; + + +/** + * An output stream which will retain data in memory until a specified + * threshold is reached, and only then commit it to disk. If the stream is + * closed before the threshold is reached, the data will not be written to + * disk at all. + *

+ * This class originated in FileUpload processing. In this use case, you do + * not know in advance the size of the file being uploaded. If the file is small + * you want to store it in memory (for speed), but if the file is large you want + * to store it to file (to avoid memory issues). + * + * @author Martin Cooper + * @author gaxzerow + * + * @version $Id: DeferredFileOutputStream.java,v 1.1 2012/10/01 13:02:59 marcin Exp $ + */ +public class DeferredFileOutputStream + extends ThresholdingOutputStream +{ + + // ----------------------------------------------------------- Data members + + + /** + * The output stream to which data will be written prior to the theshold + * being reached. + */ + private ByteArrayOutputStream memoryOutputStream; + + + /** + * The output stream to which data will be written at any given time. This + * will always be one of memoryOutputStream or + * diskOutputStream. + */ + private OutputStream currentOutputStream; + + + /** + * The file to which output will be directed if the threshold is exceeded. + */ + private File outputFile; + + /** + * The temporary file prefix. + */ + private final String prefix; + + /** + * The temporary file suffix. + */ + private final String suffix; + + /** + * The directory to use for temporary files. + */ + private final File directory; + + + /** + * True when close() has been called successfully. + */ + private boolean closed = false; + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an instance of this class which will trigger an event at the + * specified threshold, and save data to a file beyond that point. + * + * @param threshold The number of bytes at which to trigger an event. + * @param outputFile The file to which data is saved beyond the threshold. + */ + public DeferredFileOutputStream(int threshold, File outputFile) + { + this(threshold, outputFile, null, null, null); + } + + + /** + * Constructs an instance of this class which will trigger an event at the + * specified threshold, and save data to a temporary file beyond that point. + * + * @param threshold The number of bytes at which to trigger an event. + * @param prefix Prefix to use for the temporary file. + * @param suffix Suffix to use for the temporary file. + * @param directory Temporary file directory. + * + * @since Commons IO 1.4 + */ + public DeferredFileOutputStream(int threshold, String prefix, String suffix, File directory) + { + this(threshold, null, prefix, suffix, directory); + if (prefix == null) { + throw new IllegalArgumentException("Temporary file prefix is missing"); + } + } + + /** + * Constructs an instance of this class which will trigger an event at the + * specified threshold, and save data either to a file beyond that point. + * + * @param threshold The number of bytes at which to trigger an event. + * @param outputFile The file to which data is saved beyond the threshold. + * @param prefix Prefix to use for the temporary file. + * @param suffix Suffix to use for the temporary file. + * @param directory Temporary file directory. + */ + private DeferredFileOutputStream(int threshold, File outputFile, String prefix, String suffix, File directory) { + super(threshold); + this.outputFile = outputFile; + + memoryOutputStream = new ByteArrayOutputStream(); + currentOutputStream = memoryOutputStream; + this.prefix = prefix; + this.suffix = suffix; + this.directory = directory; + } + + + // --------------------------------------- ThresholdingOutputStream methods + + + /** + * Returns the current output stream. This may be memory based or disk + * based, depending on the current state with respect to the threshold. + * + * @return The underlying output stream. + * + * @exception IOException if an error occurs. + */ + @Override + protected OutputStream getStream() throws IOException + { + return currentOutputStream; + } + + + /** + * Switches the underlying output stream from a memory based stream to one + * that is backed by disk. This is the point at which we realise that too + * much data is being written to keep in memory, so we elect to switch to + * disk-based storage. + * + * @exception IOException if an error occurs. + */ + @Override + protected void thresholdReached() throws IOException + { + if (prefix != null) { + outputFile = File.createTempFile(prefix, suffix, directory); + } + FileOutputStream fos = new FileOutputStream(outputFile); + memoryOutputStream.writeTo(fos); + currentOutputStream = fos; + memoryOutputStream = null; + } + + + // --------------------------------------------------------- Public methods + + + /** + * Determines whether or not the data for this output stream has been + * retained in memory. + * + * @return true if the data is available in memory; + * false otherwise. + */ + public boolean isInMemory() + { + return (!isThresholdExceeded()); + } + + + /** + * Returns the data for this output stream as an array of bytes, assuming + * that the data has been retained in memory. If the data was written to + * disk, this method returns null. + * + * @return The data for this output stream, or null if no such + * data is available. + */ + public byte[] getData() + { + if (memoryOutputStream != null) + { + return memoryOutputStream.toByteArray(); + } + return null; + } + + + /** + * Returns either the output file specified in the constructor or + * the temporary file created or null. + *

+ * If the constructor specifying the file is used then it returns that + * same output file, even when threashold has not been reached. + *

+ * If constructor specifying a temporary file prefix/suffix is used + * then the temporary file created once the threashold is reached is returned + * If the threshold was not reached then null is returned. + * + * @return The file for this output stream, or null if no such + * file exists. + */ + public File getFile() + { + return outputFile; + } + + + /** + * Closes underlying output stream, and mark this as closed + * + * @exception IOException if an error occurs. + */ + @Override + public void close() throws IOException + { + super.close(); + closed = true; + } + + + /** + * Writes the data from this output stream to the specified output stream, + * after it has been closed. + * + * @param out output stream to write to. + * @exception IOException if this stream is not yet closed or an error occurs. + */ + public void writeTo(OutputStream out) throws IOException + { + // we may only need to check if this is closed if we are working with a file + // but we should force the habit of closing wether we are working with + // a file or memory. + if (!closed) + { + throw new IOException("Stream not closed"); + } + + if(isInMemory()) + { + memoryOutputStream.writeTo(out); + } + else + { + FileInputStream fis = new FileInputStream(outputFile); + try { + IOUtils.copy(fis, out); + } finally { + IOUtils.closeQuietly(fis); + } + } + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/DemuxOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/DemuxOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/DemuxOutputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Data written to this stream is forwarded to a stream that has been associated + * with this thread. + * + * @author Peter Donald + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:00 $ + */ +public class DemuxOutputStream + extends OutputStream +{ + private final InheritableThreadLocal m_streams = new InheritableThreadLocal(); + + /** + * Bind the specified stream to the current thread. + * + * @param output the stream to bind + * @return the OutputStream that was previously active + */ + public OutputStream bindStream( OutputStream output ) + { + OutputStream stream = m_streams.get(); + m_streams.set( output ); + return stream; + } + + /** + * Closes stream associated with current thread. + * + * @throws IOException if an error occurs + */ + @Override + public void close() + throws IOException + { + OutputStream output = m_streams.get(); + if( null != output ) + { + output.close(); + } + } + + /** + * Flushes stream associated with current thread. + * + * @throws IOException if an error occurs + */ + @Override + public void flush() + throws IOException + { + OutputStream output = m_streams.get(); + if( null != output ) + { + output.flush(); + } + } + + /** + * Writes byte to stream associated with current thread. + * + * @param ch the byte to write to stream + * @throws IOException if an error occurs + */ + @Override + public void write( int ch ) + throws IOException + { + OutputStream output = m_streams.get(); + if( null != output ) + { + output.write( ch ); + } + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/FileWriterWithEncoding.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/FileWriterWithEncoding.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/FileWriterWithEncoding.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,331 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; + +/** + * Writer of files that allows the encoding to be set. + *

+ * This class provides a simple alternative to FileWriter + * that allows an encoding to be set. Unfortunately, it cannot subclass + * FileWriter. + *

+ * By default, the file will be overwritten, but this may be changed to append. + *

+ * The encoding must be specified using either the name of the {@link Charset}, + * the {@link Charset}, or a {@link CharsetEncoder}. If the default encoding + * is required then use the {@link java.io.FileWriter} directly, rather than + * this implementation. + *

+ * + * + * @since Commons IO 1.4 + * @version $Id: FileWriterWithEncoding.java,v 1.1 2012/10/01 13:02:59 marcin Exp $ + */ +public class FileWriterWithEncoding extends Writer { + // Cannot extend ProxyWriter, as requires writer to be + // known when super() is called + + /** The writer to decorate. */ + private final Writer out; + + /** + * Constructs a FileWriterWithEncoding with a file encoding. + * + * @param filename the name of the file to write to, not null + * @param encoding the encoding to use, not null + * @throws NullPointerException if the file name or encoding is null + * @throws IOException in case of an I/O error + */ + public FileWriterWithEncoding(String filename, String encoding) throws IOException { + this(new File(filename), encoding, false); + } + + /** + * Constructs a FileWriterWithEncoding with a file encoding. + * + * @param filename the name of the file to write to, not null + * @param encoding the encoding to use, not null + * @param append true if content should be appended, false to overwrite + * @throws NullPointerException if the file name or encoding is null + * @throws IOException in case of an I/O error + */ + public FileWriterWithEncoding(String filename, String encoding, boolean append) throws IOException { + this(new File(filename), encoding, append); + } + + /** + * Constructs a FileWriterWithEncoding with a file encoding. + * + * @param filename the name of the file to write to, not null + * @param encoding the encoding to use, not null + * @throws NullPointerException if the file name or encoding is null + * @throws IOException in case of an I/O error + */ + public FileWriterWithEncoding(String filename, Charset encoding) throws IOException { + this(new File(filename), encoding, false); + } + + /** + * Constructs a FileWriterWithEncoding with a file encoding. + * + * @param filename the name of the file to write to, not null + * @param encoding the encoding to use, not null + * @param append true if content should be appended, false to overwrite + * @throws NullPointerException if the file name or encoding is null + * @throws IOException in case of an I/O error + */ + public FileWriterWithEncoding(String filename, Charset encoding, boolean append) throws IOException { + this(new File(filename), encoding, append); + } + + /** + * Constructs a FileWriterWithEncoding with a file encoding. + * + * @param filename the name of the file to write to, not null + * @param encoding the encoding to use, not null + * @throws NullPointerException if the file name or encoding is null + * @throws IOException in case of an I/O error + */ + public FileWriterWithEncoding(String filename, CharsetEncoder encoding) throws IOException { + this(new File(filename), encoding, false); + } + + /** + * Constructs a FileWriterWithEncoding with a file encoding. + * + * @param filename the name of the file to write to, not null + * @param encoding the encoding to use, not null + * @param append true if content should be appended, false to overwrite + * @throws NullPointerException if the file name or encoding is null + * @throws IOException in case of an I/O error + */ + public FileWriterWithEncoding(String filename, CharsetEncoder encoding, boolean append) throws IOException { + this(new File(filename), encoding, append); + } + + /** + * Constructs a FileWriterWithEncoding with a file encoding. + * + * @param file the file to write to, not null + * @param encoding the encoding to use, not null + * @throws NullPointerException if the file or encoding is null + * @throws IOException in case of an I/O error + */ + public FileWriterWithEncoding(File file, String encoding) throws IOException { + this(file, encoding, false); + } + + /** + * Constructs a FileWriterWithEncoding with a file encoding. + * + * @param file the file to write to, not null + * @param encoding the encoding to use, not null + * @param append true if content should be appended, false to overwrite + * @throws NullPointerException if the file or encoding is null + * @throws IOException in case of an I/O error + */ + public FileWriterWithEncoding(File file, String encoding, boolean append) throws IOException { + super(); + this.out = initWriter(file, encoding, append); + } + + /** + * Constructs a FileWriterWithEncoding with a file encoding. + * + * @param file the file to write to, not null + * @param encoding the encoding to use, not null + * @throws NullPointerException if the file or encoding is null + * @throws IOException in case of an I/O error + */ + public FileWriterWithEncoding(File file, Charset encoding) throws IOException { + this(file, encoding, false); + } + + /** + * Constructs a FileWriterWithEncoding with a file encoding. + * + * @param file the file to write to, not null + * @param encoding the encoding to use, not null + * @param append true if content should be appended, false to overwrite + * @throws NullPointerException if the file or encoding is null + * @throws IOException in case of an I/O error + */ + public FileWriterWithEncoding(File file, Charset encoding, boolean append) throws IOException { + super(); + this.out = initWriter(file, encoding, append); + } + + /** + * Constructs a FileWriterWithEncoding with a file encoding. + * + * @param file the file to write to, not null + * @param encoding the encoding to use, not null + * @throws NullPointerException if the file or encoding is null + * @throws IOException in case of an I/O error + */ + public FileWriterWithEncoding(File file, CharsetEncoder encoding) throws IOException { + this(file, encoding, false); + } + + /** + * Constructs a FileWriterWithEncoding with a file encoding. + * + * @param file the file to write to, not null + * @param encoding the encoding to use, not null + * @param append true if content should be appended, false to overwrite + * @throws NullPointerException if the file or encoding is null + * @throws IOException in case of an I/O error + */ + public FileWriterWithEncoding(File file, CharsetEncoder encoding, boolean append) throws IOException { + super(); + this.out = initWriter(file, encoding, append); + } + + //----------------------------------------------------------------------- + /** + * Initialise the wrapped file writer. + * Ensure that a cleanup occurs if the writer creation fails. + * + * @param file the file to be accessed + * @param encoding the encoding to use - may be Charset, CharsetEncoder or String + * @param append true to append + * @return the initialised writer + * @throws NullPointerException if the file or encoding is null + * @throws IOException if an error occurs + */ + private static Writer initWriter(File file, Object encoding, boolean append) throws IOException { + if (file == null) { + throw new NullPointerException("File is missing"); + } + if (encoding == null) { + throw new NullPointerException("Encoding is missing"); + } + boolean fileExistedAlready = file.exists(); + OutputStream stream = null; + Writer writer = null; + try { + stream = new FileOutputStream(file, append); + if (encoding instanceof Charset) { + writer = new OutputStreamWriter(stream, (Charset)encoding); + } else if (encoding instanceof CharsetEncoder) { + writer = new OutputStreamWriter(stream, (CharsetEncoder)encoding); + } else { + writer = new OutputStreamWriter(stream, (String)encoding); + } + } catch (IOException ex) { + IOUtils.closeQuietly(writer); + IOUtils.closeQuietly(stream); + if (fileExistedAlready == false) { + FileUtils.deleteQuietly(file); + } + throw ex; + } catch (RuntimeException ex) { + IOUtils.closeQuietly(writer); + IOUtils.closeQuietly(stream); + if (fileExistedAlready == false) { + FileUtils.deleteQuietly(file); + } + throw ex; + } + return writer; + } + + //----------------------------------------------------------------------- + /** + * Write a character. + * @param idx the character to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(int idx) throws IOException { + out.write(idx); + } + + /** + * Write the characters from an array. + * @param chr the characters to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(char[] chr) throws IOException { + out.write(chr); + } + + /** + * Write the specified characters from an array. + * @param chr the characters to write + * @param st The start offset + * @param end The number of characters to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(char[] chr, int st, int end) throws IOException { + out.write(chr, st, end); + } + + /** + * Write the characters from a string. + * @param str the string to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(String str) throws IOException { + out.write(str); + } + + /** + * Write the specified characters from a string. + * @param str the string to write + * @param st The start offset + * @param end The number of characters to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(String str, int st, int end) throws IOException { + out.write(str, st, end); + } + + /** + * Flush the stream. + * @throws IOException if an I/O error occurs + */ + @Override + public void flush() throws IOException { + out.flush(); + } + + /** + * Close the stream. + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + out.close(); + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/LockableFileWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/LockableFileWriter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/LockableFileWriter.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,346 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; + +/** + * FileWriter that will create and honor lock files to allow simple + * cross thread file lock handling. + *

+ * This class provides a simple alternative to FileWriter + * that will use a lock file to prevent duplicate writes. + *

+ * N.B. the lock file is deleted when {@link #close()} is called + * - or if the main file cannot be opened initially. + * In the (unlikely) event that the lockfile cannot be deleted, + * this is not reported, and subsequent requests using + * the same lockfile will fail. + *

+ * By default, the file will be overwritten, but this may be changed to append. + * The lock directory may be specified, but defaults to the system property + * java.io.tmpdir. + * The encoding may also be specified, and defaults to the platform default. + * + * @author Scott Sanders + * @author Michael Salmon + * @author Jon S. Stevens + * @author Daniel Rall + * @author Stephen Colebourne + * @author Andy Lehane + * @version $Id: LockableFileWriter.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + */ +public class LockableFileWriter extends Writer { + // Cannot extend ProxyWriter, as requires writer to be + // known when super() is called + + /** The extension for the lock file. */ + private static final String LCK = ".lck"; + + /** The writer to decorate. */ + private final Writer out; + /** The lock file. */ + private final File lockFile; + + /** + * Constructs a LockableFileWriter. + * If the file exists, it is overwritten. + * + * @param fileName the file to write to, not null + * @throws NullPointerException if the file is null + * @throws IOException in case of an I/O error + */ + public LockableFileWriter(String fileName) throws IOException { + this(fileName, false, null); + } + + /** + * Constructs a LockableFileWriter. + * + * @param fileName file to write to, not null + * @param append true if content should be appended, false to overwrite + * @throws NullPointerException if the file is null + * @throws IOException in case of an I/O error + */ + public LockableFileWriter(String fileName, boolean append) throws IOException { + this(fileName, append, null); + } + + /** + * Constructs a LockableFileWriter. + * + * @param fileName the file to write to, not null + * @param append true if content should be appended, false to overwrite + * @param lockDir the directory in which the lock file should be held + * @throws NullPointerException if the file is null + * @throws IOException in case of an I/O error + */ + public LockableFileWriter(String fileName, boolean append, String lockDir) throws IOException { + this(new File(fileName), append, lockDir); + } + + /** + * Constructs a LockableFileWriter. + * If the file exists, it is overwritten. + * + * @param file the file to write to, not null + * @throws NullPointerException if the file is null + * @throws IOException in case of an I/O error + */ + public LockableFileWriter(File file) throws IOException { + this(file, false, null); + } + + /** + * Constructs a LockableFileWriter. + * + * @param file the file to write to, not null + * @param append true if content should be appended, false to overwrite + * @throws NullPointerException if the file is null + * @throws IOException in case of an I/O error + */ + public LockableFileWriter(File file, boolean append) throws IOException { + this(file, append, null); + } + + /** + * Constructs a LockableFileWriter. + * + * @param file the file to write to, not null + * @param append true if content should be appended, false to overwrite + * @param lockDir the directory in which the lock file should be held + * @throws NullPointerException if the file is null + * @throws IOException in case of an I/O error + */ + public LockableFileWriter(File file, boolean append, String lockDir) throws IOException { + this(file, null, append, lockDir); + } + + /** + * Constructs a LockableFileWriter with a file encoding. + * + * @param file the file to write to, not null + * @param encoding the encoding to use, null means platform default + * @throws NullPointerException if the file is null + * @throws IOException in case of an I/O error + */ + public LockableFileWriter(File file, String encoding) throws IOException { + this(file, encoding, false, null); + } + + /** + * Constructs a LockableFileWriter with a file encoding. + * + * @param file the file to write to, not null + * @param encoding the encoding to use, null means platform default + * @param append true if content should be appended, false to overwrite + * @param lockDir the directory in which the lock file should be held + * @throws NullPointerException if the file is null + * @throws IOException in case of an I/O error + */ + public LockableFileWriter(File file, String encoding, boolean append, + String lockDir) throws IOException { + super(); + // init file to create/append + file = file.getAbsoluteFile(); + if (file.getParentFile() != null) { + FileUtils.forceMkdir(file.getParentFile()); + } + if (file.isDirectory()) { + throw new IOException("File specified is a directory"); + } + + // init lock file + if (lockDir == null) { + lockDir = System.getProperty("java.io.tmpdir"); + } + File lockDirFile = new File(lockDir); + FileUtils.forceMkdir(lockDirFile); + testLockDir(lockDirFile); + lockFile = new File(lockDirFile, file.getName() + LCK); + + // check if locked + createLock(); + + // init wrapped writer + out = initWriter(file, encoding, append); + } + + //----------------------------------------------------------------------- + /** + * Tests that we can write to the lock directory. + * + * @param lockDir the File representing the lock directory + * @throws IOException if we cannot write to the lock directory + * @throws IOException if we cannot find the lock file + */ + private void testLockDir(File lockDir) throws IOException { + if (!lockDir.exists()) { + throw new IOException( + "Could not find lockDir: " + lockDir.getAbsolutePath()); + } + if (!lockDir.canWrite()) { + throw new IOException( + "Could not write to lockDir: " + lockDir.getAbsolutePath()); + } + } + + /** + * Creates the lock file. + * + * @throws IOException if we cannot create the file + */ + private void createLock() throws IOException { + synchronized (LockableFileWriter.class) { + if (!lockFile.createNewFile()) { + throw new IOException("Can't write file, lock " + + lockFile.getAbsolutePath() + " exists"); + } + lockFile.deleteOnExit(); + } + } + + /** + * Initialise the wrapped file writer. + * Ensure that a cleanup occurs if the writer creation fails. + * + * @param file the file to be accessed + * @param encoding the encoding to use + * @param append true to append + * @return The initialised writer + * @throws IOException if an error occurs + */ + private Writer initWriter(File file, String encoding, boolean append) throws IOException { + boolean fileExistedAlready = file.exists(); + OutputStream stream = null; + Writer writer = null; + try { + if (encoding == null) { + writer = new FileWriter(file.getAbsolutePath(), append); + } else { + stream = new FileOutputStream(file.getAbsolutePath(), append); + writer = new OutputStreamWriter(stream, encoding); + } + } catch (IOException ex) { + IOUtils.closeQuietly(writer); + IOUtils.closeQuietly(stream); + FileUtils.deleteQuietly(lockFile); + if (fileExistedAlready == false) { + FileUtils.deleteQuietly(file); + } + throw ex; + } catch (RuntimeException ex) { + IOUtils.closeQuietly(writer); + IOUtils.closeQuietly(stream); + FileUtils.deleteQuietly(lockFile); + if (fileExistedAlready == false) { + FileUtils.deleteQuietly(file); + } + throw ex; + } + return writer; + } + + //----------------------------------------------------------------------- + /** + * Closes the file writer and deletes the lockfile (if possible). + * + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + try { + out.close(); + } finally { + lockFile.delete(); + } + } + + //----------------------------------------------------------------------- + /** + * Write a character. + * @param idx the character to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(int idx) throws IOException { + out.write(idx); + } + + /** + * Write the characters from an array. + * @param chr the characters to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(char[] chr) throws IOException { + out.write(chr); + } + + /** + * Write the specified characters from an array. + * @param chr the characters to write + * @param st The start offset + * @param end The number of characters to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(char[] chr, int st, int end) throws IOException { + out.write(chr, st, end); + } + + /** + * Write the characters from a string. + * @param str the string to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(String str) throws IOException { + out.write(str); + } + + /** + * Write the specified characters from a string. + * @param str the string to write + * @param st The start offset + * @param end The number of characters to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(String str, int st, int end) throws IOException { + out.write(str, st, end); + } + + /** + * Flush the stream. + * @throws IOException if an I/O error occurs + */ + @Override + public void flush() throws IOException { + out.flush(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/NullOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/NullOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/NullOutputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * This OutputStream writes all data to the famous /dev/null. + *

+ * This output stream has no destination (file/socket etc.) and all + * bytes written to it are ignored and lost. + * + * @author Jeremias Maerki + * @version $Id: NullOutputStream.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + */ +public class NullOutputStream extends OutputStream { + + /** + * A singleton. + */ + public static final NullOutputStream NULL_OUTPUT_STREAM = new NullOutputStream(); + + /** + * Does nothing - output to /dev/null. + * @param b The bytes to write + * @param off The start offset + * @param len The number of bytes to write + */ + @Override + public void write(byte[] b, int off, int len) { + //to /dev/null + } + + /** + * Does nothing - output to /dev/null. + * @param b The byte to write + */ + @Override + public void write(int b) { + //to /dev/null + } + + /** + * Does nothing - output to /dev/null. + * @param b The bytes to write + * @throws IOException never + */ + @Override + public void write(byte[] b) throws IOException { + //to /dev/null + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/NullWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/NullWriter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/NullWriter.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.Writer; + +/** + * This {@link Writer} writes all data to the famous /dev/null. + *

+ * This Writer has no destination (file/socket etc.) and all + * characters written to it are ignored and lost. + * + * @version $Id: NullWriter.java,v 1.1 2012/10/01 13:02:59 marcin Exp $ + */ +public class NullWriter extends Writer { + + /** + * A singleton. + */ + public static final NullWriter NULL_WRITER = new NullWriter(); + + /** + * Constructs a new NullWriter. + */ + public NullWriter() { + } + + /** + * Does nothing - output to /dev/null. + * @param c The character to write + * @return this writer + * @since Commons IO 2.0 + */ + @Override + public Writer append(char c) { + //to /dev/null + return this; + } + + /** + * Does nothing - output to /dev/null. + * @param csq The character sequence to write + * @param start The index of the first character to write + * @param end The index of the first character to write (exclusive) + * @return this writer + * @since Commons IO 2.0 + */ + @Override + public Writer append(CharSequence csq, int start, int end) { + //to /dev/null + return this; + } + + /** + * Does nothing - output to /dev/null. + * @param csq The character sequence to write + * @return this writer + * @since Commons IO 2.0 + */ + @Override + public Writer append(CharSequence csq) { + //to /dev/null + return this; + } + + /** + * Does nothing - output to /dev/null. + * @param idx The character to write + */ + @Override + public void write(int idx) { + //to /dev/null + } + + /** + * Does nothing - output to /dev/null. + * @param chr The characters to write + */ + @Override + public void write(char[] chr) { + //to /dev/null + } + + /** + * Does nothing - output to /dev/null. + * @param chr The characters to write + * @param st The start offset + * @param end The number of characters to write + */ + @Override + public void write(char[] chr, int st, int end) { + //to /dev/null + } + + /** + * Does nothing - output to /dev/null. + * @param str The string to write + */ + @Override + public void write(String str) { + //to /dev/null + } + + /** + * Does nothing - output to /dev/null. + * @param str The string to write + * @param st The start offset + * @param end The number of characters to write + */ + @Override + public void write(String str, int st, int end) { + //to /dev/null + } + + /** @see java.io.Writer#flush() */ + @Override + public void flush() { + //to /dev/null + } + + /** @see java.io.Writer#close() */ + @Override + public void close() { + //to /dev/null + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/ProxyOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/ProxyOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/ProxyOutputStream.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * A Proxy stream which acts as expected, that is it passes the method + * calls on to the proxied stream and doesn't change which methods are + * being called. It is an alternative base class to FilterOutputStream + * to increase reusability. + *

+ * See the protected methods for ways in which a subclass can easily decorate + * a stream with custom pre-, post- or error processing functionality. + * + * @author Stephen Colebourne + * @version $Id: ProxyOutputStream.java,v 1.1 2012/10/01 13:02:59 marcin Exp $ + */ +public class ProxyOutputStream extends FilterOutputStream { + + /** + * Constructs a new ProxyOutputStream. + * + * @param proxy the OutputStream to delegate to + */ + public ProxyOutputStream(OutputStream proxy) { + super(proxy); + // the proxy is stored in a protected superclass variable named 'out' + } + + /** + * Invokes the delegate's write(int) method. + * @param idx the byte to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(int idx) throws IOException { + try { + beforeWrite(1); + out.write(idx); + afterWrite(1); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's write(byte[]) method. + * @param bts the bytes to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(byte[] bts) throws IOException { + try { + int len = bts != null ? bts.length : 0; + beforeWrite(len); + out.write(bts); + afterWrite(len); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's write(byte[]) method. + * @param bts the bytes to write + * @param st The start offset + * @param end The number of bytes to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(byte[] bts, int st, int end) throws IOException { + try { + beforeWrite(end); + out.write(bts, st, end); + afterWrite(end); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's flush() method. + * @throws IOException if an I/O error occurs + */ + @Override + public void flush() throws IOException { + try { + out.flush(); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's close() method. + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + try { + out.close(); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invoked by the write methods before the call is proxied. The number + * of bytes to be written (1 for the {@link #write(int)} method, buffer + * length for {@link #write(byte[])}, etc.) is given as an argument. + *

+ * Subclasses can override this method to add common pre-processing + * functionality without having to override all the write methods. + * The default implementation does nothing. + * + * @since Commons IO 2.0 + * @param n number of bytes to be written + * @throws IOException if the pre-processing fails + */ + protected void beforeWrite(int n) throws IOException { + } + + /** + * Invoked by the write methods after the proxied call has returned + * successfully. The number of bytes written (1 for the + * {@link #write(int)} method, buffer length for {@link #write(byte[])}, + * etc.) is given as an argument. + *

+ * Subclasses can override this method to add common post-processing + * functionality without having to override all the write methods. + * The default implementation does nothing. + * + * @since Commons IO 2.0 + * @param n number of bytes written + * @throws IOException if the post-processing fails + */ + protected void afterWrite(int n) throws IOException { + } + + /** + * Handle any IOExceptions thrown. + *

+ * This method provides a point to implement custom exception + * handling. The default behaviour is to re-throw the exception. + * @param e The IOException thrown + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + protected void handleIOException(IOException e) throws IOException { + throw e; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/ProxyWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/ProxyWriter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/ProxyWriter.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,276 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.FilterWriter; +import java.io.IOException; +import java.io.Writer; + +/** + * A Proxy stream which acts as expected, that is it passes the method + * calls on to the proxied stream and doesn't change which methods are + * being called. It is an alternative base class to FilterWriter + * to increase reusability, because FilterWriter changes the + * methods being called, such as write(char[]) to write(char[], int, int) + * and write(String) to write(String, int, int). + * + * @author Stephen Colebourne + * @version $Id: ProxyWriter.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + */ +public class ProxyWriter extends FilterWriter { + + /** + * Constructs a new ProxyWriter. + * + * @param proxy the Writer to delegate to + */ + public ProxyWriter(Writer proxy) { + super(proxy); + // the proxy is stored in a protected superclass variable named 'out' + } + + /** + * Invokes the delegate's append(char) method. + * @param c The character to write + * @return this writer + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + @Override + public Writer append(char c) throws IOException { + try { + beforeWrite(1); + out.append(c); + afterWrite(1); + } catch (IOException e) { + handleIOException(e); + } + return this; + } + + /** + * Invokes the delegate's append(CharSequence, int, int) method. + * @param csq The character sequence to write + * @param start The index of the first character to write + * @param end The index of the first character to write (exclusive) + * @return this writer + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + @Override + public Writer append(CharSequence csq, int start, int end) throws IOException { + try { + beforeWrite(end - start); + out.append(csq, start, end); + afterWrite(end - start); + } catch (IOException e) { + handleIOException(e); + } + return this; + } + + /** + * Invokes the delegate's append(CharSequence) method. + * @param csq The character sequence to write + * @return this writer + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + @Override + public Writer append(CharSequence csq) throws IOException { + try { + int len = 0; + if (csq != null) { + len = csq.length(); + } + + beforeWrite(len); + out.append(csq); + afterWrite(len); + } catch (IOException e) { + handleIOException(e); + } + return this; + } + + /** + * Invokes the delegate's write(int) method. + * @param idx the character to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(int idx) throws IOException { + try { + beforeWrite(1); + out.write(idx); + afterWrite(1); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's write(char[]) method. + * @param chr the characters to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(char[] chr) throws IOException { + try { + int len = 0; + if (chr != null) { + len = chr.length; + } + + beforeWrite(len); + out.write(chr); + afterWrite(len); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's write(char[], int, int) method. + * @param chr the characters to write + * @param st The start offset + * @param len The number of characters to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(char[] chr, int st, int len) throws IOException { + try { + beforeWrite(len); + out.write(chr, st, len); + afterWrite(len); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's write(String) method. + * @param str the string to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(String str) throws IOException { + try { + int len = 0; + if (str != null) { + len = str.length(); + } + + beforeWrite(len); + out.write(str); + afterWrite(len); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's write(String) method. + * @param str the string to write + * @param st The start offset + * @param len The number of characters to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(String str, int st, int len) throws IOException { + try { + beforeWrite(len); + out.write(str, st, len); + afterWrite(len); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's flush() method. + * @throws IOException if an I/O error occurs + */ + @Override + public void flush() throws IOException { + try { + out.flush(); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invokes the delegate's close() method. + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + try { + out.close(); + } catch (IOException e) { + handleIOException(e); + } + } + + /** + * Invoked by the write methods before the call is proxied. The number + * of chars to be written (1 for the {@link #write(int)} method, buffer + * length for {@link #write(char[])}, etc.) is given as an argument. + *

+ * Subclasses can override this method to add common pre-processing + * functionality without having to override all the write methods. + * The default implementation does nothing. + * + * @since Commons IO 2.0 + * @param n number of chars to be written + * @throws IOException if the pre-processing fails + */ + protected void beforeWrite(int n) throws IOException { + } + + /** + * Invoked by the write methods after the proxied call has returned + * successfully. The number of chars written (1 for the + * {@link #write(int)} method, buffer length for {@link #write(char[])}, + * etc.) is given as an argument. + *

+ * Subclasses can override this method to add common post-processing + * functionality without having to override all the write methods. + * The default implementation does nothing. + * + * @since Commons IO 2.0 + * @param n number of chars written + * @throws IOException if the post-processing fails + */ + protected void afterWrite(int n) throws IOException { + } + + /** + * Handle any IOExceptions thrown. + *

+ * This method provides a point to implement custom exception + * handling. The default behaviour is to re-throw the exception. + * @param e The IOException thrown + * @throws IOException if an I/O error occurs + * @since Commons IO 2.0 + */ + protected void handleIOException(IOException e) throws IOException { + throw e; + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/StringBuilderWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/StringBuilderWriter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/StringBuilderWriter.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.Serializable; +import java.io.Writer; + +/** + * {@link Writer} implementation that outputs to a {@link StringBuilder}. + *

+ * NOTE: This implementation, as an alternative to + * java.io.StringWriter, provides an un-synchronized + * (i.e. for use in a single thread) implementation for better performance. + * For safe usage with multiple {@link Thread}s then + * java.io.StringWriter should be used. + * + * @version $Revision: 1.1 $ $Date: 2012/10/01 13:03:00 $ + * @since Commons IO 2.0 + */ +public class StringBuilderWriter extends Writer implements Serializable { + + private final StringBuilder builder; + + /** + * Construct a new {@link StringBuilder} instance with default capacity. + */ + public StringBuilderWriter() { + this.builder = new StringBuilder(); + } + + /** + * Construct a new {@link StringBuilder} instance with the specified capacity. + * + * @param capacity The initial capacity of the underlying {@link StringBuilder} + */ + public StringBuilderWriter(int capacity) { + this.builder = new StringBuilder(capacity); + } + + /** + * Construct a new instance with the specified {@link StringBuilder}. + * + * @param builder The String builder + */ + public StringBuilderWriter(StringBuilder builder) { + this.builder = (builder != null ? builder : new StringBuilder()); + } + + /** + * Append a single character to this Writer. + * + * @param value The character to append + * @return This writer instance + */ + @Override + public Writer append(char value) { + builder.append(value); + return this; + } + + /** + * Append a character sequence to this Writer. + * + * @param value The character to append + * @return This writer instance + */ + @Override + public Writer append(CharSequence value) { + builder.append(value); + return this; + } + + /** + * Append a portion of a character sequence to the {@link StringBuilder}. + * + * @param value The character to append + * @param start The index of the first character + * @param end The index of the last character + 1 + * @return This writer instance + */ + @Override + public Writer append(CharSequence value, int start, int end) { + builder.append(value, start, end); + return this; + } + + /** + * Closing this writer has no effect. + */ + @Override + public void close() { + } + + /** + * Flushing this writer has no effect. + */ + @Override + public void flush() { + } + + + /** + * Write a String to the {@link StringBuilder}. + * + * @param value The value to write + */ + @Override + public void write(String value) { + if (value != null) { + builder.append(value); + } + } + + /** + * Write a portion of a character array to the {@link StringBuilder}. + * + * @param value The value to write + * @param offset The index of the first character + * @param length The number of characters to write + */ + @Override + public void write(char[] value, int offset, int length) { + if (value != null) { + builder.append(value, offset, length); + } + } + + /** + * Return the underlying builder. + * + * @return The underlying builder + */ + public StringBuilder getBuilder() { + return builder; + } + + /** + * Returns {@link StringBuilder#toString()}. + * + * @return The contents of the String builder. + */ + @Override + public String toString() { + return builder.toString(); + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/TaggedOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/TaggedOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/TaggedOutputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Serializable; +import java.util.UUID; + +import org.apache.commons.io.TaggedIOException; + +/** + * An output stream decorator that tags potential exceptions so that the + * stream that caused the exception can easily be identified. This is + * done by using the {@link TaggedIOException} class to wrap all thrown + * {@link IOException}s. See below for an example of using this class. + *

+ * TaggedOutputStream stream = new TaggedOutputStream(...);
+ * try {
+ *     // Processing that may throw an IOException either from this stream
+ *     // or from some other IO activity like temporary files, etc.
+ *     writeToStream(stream);
+ * } catch (IOException e) {
+ *     if (stream.isCauseOf(e)) {
+ *         // The exception was caused by this stream.
+ *         // Use e.getCause() to get the original exception.
+ *     } else {
+ *         // The exception was caused by something else.
+ *     }
+ * }
+ * 
+ *

+ * Alternatively, the {@link #throwIfCauseOf(Exception)} method can be + * used to let higher levels of code handle the exception caused by this + * stream while other processing errors are being taken care of at this + * lower level. + *

+ * TaggedOutputStream stream = new TaggedOutputStream(...);
+ * try {
+ *     writeToStream(stream);
+ * } catch (IOException e) {
+ *     stream.throwIfCauseOf(e);
+ *     // ... or process the exception that was caused by something else
+ * }
+ * 
+ * + * @see TaggedIOException + * @since Commons IO 2.0 + */ +public class TaggedOutputStream extends ProxyOutputStream { + + /** + * The unique tag associated with exceptions from stream. + */ + private final Serializable tag = UUID.randomUUID(); + + /** + * Creates a tagging decorator for the given output stream. + * + * @param proxy output stream to be decorated + */ + public TaggedOutputStream(OutputStream proxy) { + super(proxy); + } + + /** + * Tests if the given exception was caused by this stream. + * + * @param exception an exception + * @return true if the exception was thrown by this stream, + * false otherwise + */ + public boolean isCauseOf(Exception exception) { + return TaggedIOException.isTaggedWith(exception, tag); + } + + /** + * Re-throws the original exception thrown by this stream. This method + * first checks whether the given exception is a {@link TaggedIOException} + * wrapper created by this decorator, and then unwraps and throws the + * original wrapped exception. Returns normally if the exception was + * not thrown by this stream. + * + * @param exception an exception + * @throws IOException original exception, if any, thrown by this stream + */ + public void throwIfCauseOf(Exception exception) throws IOException { + TaggedIOException.throwCauseIfTaggedWith(exception, tag); + } + + /** + * Tags any IOExceptions thrown, wrapping and re-throwing. + * + * @param e The IOException thrown + * @throws IOException if an I/O error occurs + */ + @Override + protected void handleIOException(IOException e) throws IOException { + throw new TaggedIOException(e, tag); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/TeeOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/TeeOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/TeeOutputStream.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Classic splitter of OutputStream. Named after the unix 'tee' + * command. It allows a stream to be branched off so there + * are now two streams. + * + * @version $Id: TeeOutputStream.java,v 1.1 2012/10/01 13:02:59 marcin Exp $ + */ +public class TeeOutputStream extends ProxyOutputStream { + + /** the second OutputStream to write to */ + protected OutputStream branch; + + /** + * Constructs a TeeOutputStream. + * @param out the main OutputStream + * @param branch the second OutputStream + */ + public TeeOutputStream( OutputStream out, OutputStream branch ) { + super(out); + this.branch = branch; + } + + /** + * Write the bytes to both streams. + * @param b the bytes to write + * @throws IOException if an I/O error occurs + */ + @Override + public synchronized void write(byte[] b) throws IOException { + super.write(b); + this.branch.write(b); + } + + /** + * Write the specified bytes to both streams. + * @param b the bytes to write + * @param off The start offset + * @param len The number of bytes to write + * @throws IOException if an I/O error occurs + */ + @Override + public synchronized void write(byte[] b, int off, int len) throws IOException { + super.write(b, off, len); + this.branch.write(b, off, len); + } + + /** + * Write a byte to both streams. + * @param b the byte to write + * @throws IOException if an I/O error occurs + */ + @Override + public synchronized void write(int b) throws IOException { + super.write(b); + this.branch.write(b); + } + + /** + * Flushes both streams. + * @throws IOException if an I/O error occurs + */ + @Override + public void flush() throws IOException { + super.flush(); + this.branch.flush(); + } + + /** + * Closes both streams. + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + super.close(); + this.branch.close(); + } + +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/ThresholdingOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/ThresholdingOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/ThresholdingOutputStream.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,262 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.IOException; +import java.io.OutputStream; + + +/** + * An output stream which triggers an event when a specified number of bytes of + * data have been written to it. The event can be used, for example, to throw + * an exception if a maximum has been reached, or to switch the underlying + * stream type when the threshold is exceeded. + *

+ * This class overrides all OutputStream methods. However, these + * overrides ultimately call the corresponding methods in the underlying output + * stream implementation. + *

+ * NOTE: This implementation may trigger the event before the threshold + * is actually reached, since it triggers when a pending write operation would + * cause the threshold to be exceeded. + * + * @author Martin Cooper + * + * @version $Id: ThresholdingOutputStream.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + */ +public abstract class ThresholdingOutputStream + extends OutputStream +{ + + // ----------------------------------------------------------- Data members + + + /** + * The threshold at which the event will be triggered. + */ + private final int threshold; + + + /** + * The number of bytes written to the output stream. + */ + private long written; + + + /** + * Whether or not the configured threshold has been exceeded. + */ + private boolean thresholdExceeded; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an instance of this class which will trigger an event at the + * specified threshold. + * + * @param threshold The number of bytes at which to trigger an event. + */ + public ThresholdingOutputStream(int threshold) + { + this.threshold = threshold; + } + + + // --------------------------------------------------- OutputStream methods + + + /** + * Writes the specified byte to this output stream. + * + * @param b The byte to be written. + * + * @exception IOException if an error occurs. + */ + @Override + public void write(int b) throws IOException + { + checkThreshold(1); + getStream().write(b); + written++; + } + + + /** + * Writes b.length bytes from the specified byte array to this + * output stream. + * + * @param b The array of bytes to be written. + * + * @exception IOException if an error occurs. + */ + @Override + public void write(byte b[]) throws IOException + { + checkThreshold(b.length); + getStream().write(b); + written += b.length; + } + + + /** + * Writes len bytes from the specified byte array starting at + * offset off to this output stream. + * + * @param b The byte array from which the data will be written. + * @param off The start offset in the byte array. + * @param len The number of bytes to write. + * + * @exception IOException if an error occurs. + */ + @Override + public void write(byte b[], int off, int len) throws IOException + { + checkThreshold(len); + getStream().write(b, off, len); + written += len; + } + + + /** + * Flushes this output stream and forces any buffered output bytes to be + * written out. + * + * @exception IOException if an error occurs. + */ + @Override + public void flush() throws IOException + { + getStream().flush(); + } + + + /** + * Closes this output stream and releases any system resources associated + * with this stream. + * + * @exception IOException if an error occurs. + */ + @Override + public void close() throws IOException + { + try + { + flush(); + } + catch (IOException ignored) + { + // ignore + } + getStream().close(); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Returns the threshold, in bytes, at which an event will be triggered. + * + * @return The threshold point, in bytes. + */ + public int getThreshold() + { + return threshold; + } + + + /** + * Returns the number of bytes that have been written to this output stream. + * + * @return The number of bytes written. + */ + public long getByteCount() + { + return written; + } + + + /** + * Determines whether or not the configured threshold has been exceeded for + * this output stream. + * + * @return true if the threshold has been reached; + * false otherwise. + */ + public boolean isThresholdExceeded() + { + return (written > threshold); + } + + + // ------------------------------------------------------ Protected methods + + + /** + * Checks to see if writing the specified number of bytes would cause the + * configured threshold to be exceeded. If so, triggers an event to allow + * a concrete implementation to take action on this. + * + * @param count The number of bytes about to be written to the underlying + * output stream. + * + * @exception IOException if an error occurs. + */ + protected void checkThreshold(int count) throws IOException + { + if (!thresholdExceeded && (written + count > threshold)) + { + thresholdExceeded = true; + thresholdReached(); + } + } + + /** + * Resets the byteCount to zero. You can call this from + * {@link #thresholdReached()} if you want the event to be triggered again. + */ + protected void resetByteCount() + { + this.thresholdExceeded = false; + this.written = 0; + } + + // ------------------------------------------------------- Abstract methods + + + /** + * Returns the underlying output stream, to which the corresponding + * OutputStream methods in this class will ultimately delegate. + * + * @return The underlying output stream. + * + * @exception IOException if an error occurs. + */ + protected abstract OutputStream getStream() throws IOException; + + + /** + * Indicates that the configured threshold has been reached, and that a + * subclass should take whatever action necessary on this event. This may + * include changing the underlying output stream. + * + * @exception IOException if an error occurs. + */ + protected abstract void thresholdReached() throws IOException; +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/WriterOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/WriterOutputStream.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/WriterOutputStream.java 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,307 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; + +/** + * {@link OutputStream} implementation that transforms a byte stream to a + * character stream using a specified charset encoding and writes the resulting + * stream to a {@link Writer}. The stream is transformed using a + * {@link CharsetDecoder} object, guaranteeing that all charset + * encodings supported by the JRE are handled correctly. + *

+ * The output of the {@link CharsetDecoder} is buffered using a fixed size buffer. + * This implies that the data is written to the underlying {@link Writer} in chunks + * that are no larger than the size of this buffer. By default, the buffer is + * flushed only when it overflows or when {@link #flush()} or {@link #close()} + * is called. In general there is therefore no need to wrap the underlying {@link Writer} + * in a {@link java.io.BufferedWriter}. {@link WriterOutputStream} can also + * be instructed to flush the buffer after each write operation. In this case, all + * available data is written immediately to the underlying {@link Writer}, implying that + * the current position of the {@link Writer} is correlated to the current position + * of the {@link WriterOutputStream}. + *

+ * {@link WriterOutputStream} implements the inverse transformation of {@link java.io.OutputStreamWriter}; + * in the following example, writing to out2 would have the same result as writing to + * out directly (provided that the byte sequence is legal with respect to the + * charset encoding): + *

+ * OutputStream out = ...
+ * Charset cs = ...
+ * OutputStreamWriter writer = new OutputStreamWriter(out, cs);
+ * WriterOutputStream out2 = new WriterOutputStream(writer, cs);
+ * {@link WriterOutputStream} implements the same transformation as {@link java.io.InputStreamReader}, + * except that the control flow is reversed: both classes transform a byte stream + * into a character stream, but {@link java.io.InputStreamReader} pulls data from the underlying stream, + * while {@link WriterOutputStream} pushes it to the underlying stream. + *

+ * Note that while there are use cases where there is no alternative to using + * this class, very often the need to use this class is an indication of a flaw + * in the design of the code. This class is typically used in situations where an existing + * API only accepts an {@link OutputStream} object, but where the stream is known to represent + * character data that must be decoded for further use. + *

+ * Instances of {@link WriterOutputStream} are not thread safe. + * + * @see org.apache.commons.io.input.ReaderInputStream + * + * @author Andreas Veithen + * @since Commons IO 2.0 + */ +public class WriterOutputStream extends OutputStream { + private static final int DEFAULT_BUFFER_SIZE = 1024; + + private final Writer writer; + private final CharsetDecoder decoder; + private final boolean writeImmediately; + + /** + * ByteBuffer used as input for the decoder. This buffer can be small + * as it is used only to transfer the received data to the + * decoder. + */ + private final ByteBuffer decoderIn = ByteBuffer.allocate(128); + + /** + * CharBuffer used as output for the decoder. It should be + * somewhat larger as we write from this buffer to the + * underlying Writer. + */ + private final CharBuffer decoderOut; + + /** + * Constructs a new {@link WriterOutputStream} with a default output buffer size of + * 1024 characters. The output buffer will only be flushed when it overflows or when + * {@link #flush()} or {@link #close()} is called. + * + * @param writer the target {@link Writer} + * @param decoder the charset decoder + * @since Commons IO 2.1 + */ + public WriterOutputStream(Writer writer, CharsetDecoder decoder) { + this(writer, decoder, DEFAULT_BUFFER_SIZE, false); + } + + /** + * Constructs a new {@link WriterOutputStream}. + * + * @param writer the target {@link Writer} + * @param decoder the charset decoder + * @param bufferSize the size of the output buffer in number of characters + * @param writeImmediately If true the output buffer will be flushed after each + * write operation, i.e. all available data will be written to the + * underlying {@link Writer} immediately. If false, the + * output buffer will only be flushed when it overflows or when + * {@link #flush()} or {@link #close()} is called. + * @since Commons IO 2.1 + */ + public WriterOutputStream(Writer writer, CharsetDecoder decoder, int bufferSize, boolean writeImmediately) { + this.writer = writer; + this.decoder = decoder; + this.writeImmediately = writeImmediately; + decoderOut = CharBuffer.allocate(bufferSize); + } + + /** + * Constructs a new {@link WriterOutputStream}. + * + * @param writer the target {@link Writer} + * @param charset the charset encoding + * @param bufferSize the size of the output buffer in number of characters + * @param writeImmediately If true the output buffer will be flushed after each + * write operation, i.e. all available data will be written to the + * underlying {@link Writer} immediately. If false, the + * output buffer will only be flushed when it overflows or when + * {@link #flush()} or {@link #close()} is called. + */ + public WriterOutputStream(Writer writer, Charset charset, int bufferSize, boolean writeImmediately) { + this(writer, + charset.newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE) + .replaceWith("?"), + bufferSize, + writeImmediately); + } + + /** + * Constructs a new {@link WriterOutputStream} with a default output buffer size of + * 1024 characters. The output buffer will only be flushed when it overflows or when + * {@link #flush()} or {@link #close()} is called. + * + * @param writer the target {@link Writer} + * @param charset the charset encoding + */ + public WriterOutputStream(Writer writer, Charset charset) { + this(writer, charset, DEFAULT_BUFFER_SIZE, false); + } + + /** + * Constructs a new {@link WriterOutputStream}. + * + * @param writer the target {@link Writer} + * @param charsetName the name of the charset encoding + * @param bufferSize the size of the output buffer in number of characters + * @param writeImmediately If true the output buffer will be flushed after each + * write operation, i.e. all available data will be written to the + * underlying {@link Writer} immediately. If false, the + * output buffer will only be flushed when it overflows or when + * {@link #flush()} or {@link #close()} is called. + */ + public WriterOutputStream(Writer writer, String charsetName, int bufferSize, boolean writeImmediately) { + this(writer, Charset.forName(charsetName), bufferSize, writeImmediately); + } + + /** + * Constructs a new {@link WriterOutputStream} with a default output buffer size of + * 1024 characters. The output buffer will only be flushed when it overflows or when + * {@link #flush()} or {@link #close()} is called. + * + * @param writer the target {@link Writer} + * @param charsetName the name of the charset encoding + */ + public WriterOutputStream(Writer writer, String charsetName) { + this(writer, charsetName, DEFAULT_BUFFER_SIZE, false); + } + + /** + * Constructs a new {@link WriterOutputStream} that uses the default character encoding + * and with a default output buffer size of 1024 characters. The output buffer will only + * be flushed when it overflows or when {@link #flush()} or {@link #close()} is called. + * + * @param writer the target {@link Writer} + */ + public WriterOutputStream(Writer writer) { + this(writer, Charset.defaultCharset(), DEFAULT_BUFFER_SIZE, false); + } + + /** + * Write bytes from the specified byte array to the stream. + * + * @param b the byte array containing the bytes to write + * @param off the start offset in the byte array + * @param len the number of bytes to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(byte[] b, int off, int len) throws IOException { + while (len > 0) { + int c = Math.min(len, decoderIn.remaining()); + decoderIn.put(b, off, c); + processInput(false); + len -= c; + off += c; + } + if (writeImmediately) { + flushOutput(); + } + } + + /** + * Write bytes from the specified byte array to the stream. + * + * @param b the byte array containing the bytes to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(byte[] b) throws IOException { + write(b, 0, b.length); + } + + /** + * Write a single byte to the stream. + * + * @param b the byte to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(int b) throws IOException { + write(new byte[] { (byte)b }, 0, 1); + } + + /** + * Flush the stream. Any remaining content accumulated in the output buffer + * will be written to the underlying {@link Writer}. After that + * {@link Writer#flush()} will be called. + * @throws IOException if an I/O error occurs + */ + @Override + public void flush() throws IOException { + flushOutput(); + writer.flush(); + } + + /** + * Close the stream. Any remaining content accumulated in the output buffer + * will be written to the underlying {@link Writer}. After that + * {@link Writer#close()} will be called. + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + processInput(true); + flushOutput(); + writer.close(); + } + + /** + * Decode the contents of the input ByteBuffer into a CharBuffer. + * + * @param endOfInput indicates end of input + * @throws IOException if an I/O error occurs + */ + private void processInput(boolean endOfInput) throws IOException { + // Prepare decoderIn for reading + decoderIn.flip(); + CoderResult coderResult; + while (true) { + coderResult = decoder.decode(decoderIn, decoderOut, endOfInput); + if (coderResult.isOverflow()) { + flushOutput(); + } else if (coderResult.isUnderflow()) { + break; + } else { + // The decoder is configured to replace malformed input and unmappable characters, + // so we should not get here. + throw new IOException("Unexpected coder result"); + } + } + // Discard the bytes that have been read + decoderIn.compact(); + } + + /** + * Flush the output. + * + * @throws IOException if an I/O error occurs + */ + private void flushOutput() throws IOException { + if (decoderOut.position() > 0) { + writer.write(decoderOut.array(), 0, decoderOut.position()); + decoderOut.rewind(); + } + } +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/XmlStreamWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/XmlStreamWriter.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/XmlStreamWriter.java 1 Oct 2012 13:03:00 -0000 1.1 @@ -0,0 +1,221 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.output; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.io.input.XmlStreamReader; + +/** + * Character stream that handles all the necessary Voodo to figure out the + * charset encoding of the XML document written to the stream. + * + * @author Herve Boutemy + * @version $Id: XmlStreamWriter.java,v 1.1 2012/10/01 13:03:00 marcin Exp $ + * @see XmlStreamReader + * @since Commons IO 2.0 + */ +public class XmlStreamWriter extends Writer { + private static final int BUFFER_SIZE = 4096; + + private final OutputStream out; + + private final String defaultEncoding; + + private StringWriter xmlPrologWriter = new StringWriter(BUFFER_SIZE); + + private Writer writer; + + private String encoding; + + /** + * Construct an new XML stream writer for the specified output stream + * with a default encoding of UTF-8. + * + * @param out The output stream + */ + public XmlStreamWriter(OutputStream out) { + this(out, null); + } + + /** + * Construct an new XML stream writer for the specified output stream + * with the specified default encoding. + * + * @param out The output stream + * @param defaultEncoding The default encoding if not encoding could be detected + */ + public XmlStreamWriter(OutputStream out, String defaultEncoding) { + this.out = out; + this.defaultEncoding = (defaultEncoding != null ? defaultEncoding : "UTF-8"); + } + + /** + * Construct an new XML stream writer for the specified file + * with a default encoding of UTF-8. + * + * @param file The file to write to + * @throws FileNotFoundException if there is an error creating or + * opening the file + */ + public XmlStreamWriter(File file) throws FileNotFoundException { + this(file, null); + } + + /** + * Construct an new XML stream writer for the specified file + * with the specified default encoding. + * + * @param file The file to write to + * @param defaultEncoding The default encoding if not encoding could be detected + * @throws FileNotFoundException if there is an error creating or + * opening the file + */ + public XmlStreamWriter(File file, String defaultEncoding) throws FileNotFoundException { + this(new FileOutputStream(file), defaultEncoding); + } + + /** + * Return the detected encoding. + * + * @return the detected encoding + */ + public String getEncoding() { + return encoding; + } + + /** + * Return the default encoding. + * + * @return the default encoding + */ + public String getDefaultEncoding() { + return defaultEncoding; + } + + /** + * Close the underlying writer. + * + * @throws IOException if an error occurs closing the underlying writer + */ + @Override + public void close() throws IOException { + if (writer == null) { + encoding = defaultEncoding; + writer = new OutputStreamWriter(out, encoding); + writer.write(xmlPrologWriter.toString()); + } + writer.close(); + } + + /** + * Flush the underlying writer. + * + * @throws IOException if an error occurs flushing the underlying writer + */ + @Override + public void flush() throws IOException { + if (writer != null) { + writer.flush(); + } + } + + /** + * Detect the encoding. + * + * @param cbuf the buffer to write the characters from + * @param off The start offset + * @param len The number of characters to write + * @throws IOException if an error occurs detecting the encoding + */ + private void detectEncoding(char[] cbuf, int off, int len) + throws IOException { + int size = len; + StringBuffer xmlProlog = xmlPrologWriter.getBuffer(); + if (xmlProlog.length() + len > BUFFER_SIZE) { + size = BUFFER_SIZE - xmlProlog.length(); + } + xmlPrologWriter.write(cbuf, off, size); + + // try to determine encoding + if (xmlProlog.length() >= 5) { + if (xmlProlog.substring(0, 5).equals(""); + if (xmlPrologEnd > 0) { + // ok, full XML prolog written: let's extract encoding + Matcher m = ENCODING_PATTERN.matcher(xmlProlog.substring(0, + xmlPrologEnd)); + if (m.find()) { + encoding = m.group(1).toUpperCase(); + encoding = encoding.substring(1, encoding.length() - 1); + } else { + // no encoding found in XML prolog: using default + // encoding + encoding = defaultEncoding; + } + } else { + if (xmlProlog.length() >= BUFFER_SIZE) { + // no encoding found in first characters: using default + // encoding + encoding = defaultEncoding; + } + } + } else { + // no XML prolog: using default encoding + encoding = defaultEncoding; + } + if (encoding != null) { + // encoding has been chosen: let's do it + xmlPrologWriter = null; + writer = new OutputStreamWriter(out, encoding); + writer.write(xmlProlog.toString()); + if (len > size) { + writer.write(cbuf, off + size, len - size); + } + } + } + } + + /** + * Write the characters to the underlying writer, detecing encoding. + * + * @param cbuf the buffer to write the characters from + * @param off The start offset + * @param len The number of characters to write + * @throws IOException if an error occurs detecting the encoding + */ + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + if (xmlPrologWriter != null) { + detectEncoding(cbuf, off, len); + } else { + writer.write(cbuf, off, len); + } + } + + static final Pattern ENCODING_PATTERN = XmlStreamReader.ENCODING_PATTERN; +} Index: 3rdParty_sources/commons-io/org/apache/commons/io/output/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/commons-io/org/apache/commons/io/output/package.html,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/commons-io/org/apache/commons/io/output/package.html 1 Oct 2012 13:02:59 -0000 1.1 @@ -0,0 +1,25 @@ + + + + +

+This package provides implementations of output classes, such as +OutputStream and Writer. +

+ + Index: lams_build/3rdParty.userlibraries =================================================================== RCS file: /usr/local/cvsroot/lams_build/3rdParty.userlibraries,v diff -u -r1.58 -r1.59 --- lams_build/3rdParty.userlibraries 10 Sep 2012 19:02:31 -0000 1.58 +++ lams_build/3rdParty.userlibraries 1 Oct 2012 13:03:16 -0000 1.59 @@ -24,7 +24,7 @@ - +