Hello Kevin,

NioFileUtils should go into another package
org.apache.tools.ant.util.java14 otherwise we are going to have build
problems under java 1.2
This should be entered in the build.xml (selector needs.jdk14+)
Therefore NioFileUtils would be packaged in ant-nodeps.jar

We need also a FileUtilsFactory. The FileUtilsFactory would instantiate
NioFileUtils if the java runtime is 1.4 or 1.5, the normal FileUtils
otherwise.
This should be developed along the lines of the RegexpFactory, which
means no imports of optional classes such as NioFileUtils or
Java16FileUtils.

Similarly, users of FileUtils would call
FileUtilsFactory.newFileUtils(Project p) instead of
FileUtils.newFileUtils() where a project member variable is available,
otherwise FileUtilsFactory.newFileUtils().

FileUtilsFactory would be the place where the right FileUtils
implementation is picked.

Regards,

Antoine

Kev Jackson wrote:
> Hi,
>
> As promised, here's the code that I hacked together today at Antoine's
> suggestion regarding a patch in bugzilla [1].
>
> Feel free to tear it to pieces and point out obvious problems.  I've
> patched my version of copy to use this code instead of FileUtils
> directly and so far there have been no problems with it.
>
> Thanks
> Kev
>
> [1]http://issues.apache.org/bugzilla/show_bug.cgi?id=30094
> ------------------------------------------------------------------------
>
> Index: 
> D:/java_projects/ant-core-trunk/src/main/org/apache/tools/ant/util/FileUtils.java
> ===================================================================
> --- 
> D:/java_projects/ant-core-trunk/src/main/org/apache/tools/ant/util/FileUtils.java
>  (revision 395527)
> +++ 
> D:/java_projects/ant-core-trunk/src/main/org/apache/tools/ant/util/FileUtils.java
>  (working copy)
> @@ -46,7 +46,7 @@
>   * their last modification time.
>   *
>   */
> -public class FileUtils {
> +public class FileUtils implements FileUtilsAdapter {
>  
>      private static final FileUtils PRIMARY_INSTANCE = new FileUtils();
>
> Index: 
> D:/java_projects/ant-core-trunk/src/main/org/apache/tools/ant/util/FileUtilsAdapter.java
> ===================================================================
> /*
>  * Copyright  2006 The Apache Software Foundation
>  *
>  *  Licensed 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.tools.ant.util;
>
> import java.io.File;
> import java.io.IOException;
> import java.net.MalformedURLException;
> import java.net.URL;
> import java.util.Vector;
>
> import org.apache.tools.ant.Project;
> import org.apache.tools.ant.types.FilterSetCollection;
>
> /**
>  * An interface for the different types of FileUtils (classic, Nio, Java6+)
>  *
>  */
> public interface FileUtilsAdapter {
>     
>     /**
>      * The granularity of timestamps under FAT.
>      */
>     public static final long FAT_FILE_TIMESTAMP_GRANULARITY = 2000;
>
>     /**
>      * The granularity of timestamps under Unix.
>      */
>     public static final long UNIX_FILE_TIMESTAMP_GRANULARITY = 1000;
>
>     /**
>      * The granularity of timestamps under the NT File System.
>      * NTFS has a granularity of 100 nanoseconds, which is less
>      * than 1 millisecond, so we round this up to 1 millisecond.
>      */
>     public static final long NTFS_FILE_TIMESTAMP_GRANULARITY = 1;
>     
>     /**
>      * Get the URL for a file taking into account # characters.
>      *
>      * @param file the file whose URL representation is required.
>      * @return The FileURL value.
>      * @throws MalformedURLException if the URL representation cannot be
>      *      formed.
>      */
>     public URL getFileURL(File file) throws MalformedURLException;
>     
>     /**
>      * Convenience method to copy a file from a source to a destination.
>      * No filtering is performed.
>      *
>      * @param sourceFile Name of file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile Name of file to copy to.
>      *                 Must not be <code>null</code>.
>      *
>      * @throws IOException if the copying fails.
>      */
>     public void copyFile(String sourceFile, String destFile)
>         throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a destination
>      * specifying if token filtering must be used.
>      *
>      * @param sourceFile Name of file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile Name of file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      *
>      * @throws IOException if the copying fails.
>      */
>     public void copyFile(String sourceFile, String destFile,
>                          FilterSetCollection filters)
>         throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a
>      * destination specifying if token filtering must be used and if
>      * source files may overwrite newer destination files.
>      *
>      * @param sourceFile Name of file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile Name of file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      * @param overwrite Whether or not the destination file should be
>      *                  overwritten if it already exists.
>      *
>      * @throws IOException if the copying fails.
>      */
>     public void copyFile(String sourceFile, String destFile, 
> FilterSetCollection filters,
>                          boolean overwrite) throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a
>      * destination specifying if token filtering must be used, if
>      * source files may overwrite newer destination files and the
>      * last modified time of <code>destFile</code> file should be made equal
>      * to the last modified time of <code>sourceFile</code>.
>      *
>      * @param sourceFile Name of file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile Name of file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      * @param overwrite Whether or not the destination file should be
>      *                  overwritten if it already exists.
>      * @param preserveLastModified Whether or not the last modified time of
>      *                             the resulting file should be set to that
>      *                             of the source file.
>      *
>      * @throws IOException if the copying fails.
>      */
>     public void copyFile(String sourceFile, String destFile, 
> FilterSetCollection filters,
>                          boolean overwrite, boolean preserveLastModified)
>         throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a
>      * destination specifying if token filtering must be used, if
>      * source files may overwrite newer destination files and the
>      * last modified time of <code>destFile</code> file should be made equal
>      * to the last modified time of <code>sourceFile</code>.
>      *
>      * @param sourceFile Name of file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile Name of file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      * @param overwrite Whether or not the destination file should be
>      *                  overwritten if it already exists.
>      * @param preserveLastModified Whether or not the last modified time of
>      *                             the resulting file should be set to that
>      *                             of the source file.
>      * @param encoding the encoding used to read and write the files.
>      *
>      * @throws IOException if the copying fails.
>      *
>      * @since Ant 1.5
>      */
>     public void copyFile(String sourceFile, String destFile,
>                          FilterSetCollection filters, boolean overwrite,
>                          boolean preserveLastModified, String encoding)
>         throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a
>      * destination specifying if token filtering must be used, if
>      * filter chains must be used, if source files may overwrite
>      * newer destination files and the last modified time of
>      * <code>destFile</code> file should be made equal
>      * to the last modified time of <code>sourceFile</code>.
>      *
>      * @param sourceFile Name of file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile Name of file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      * @param filterChains filterChains to apply during the copy.
>      * @param overwrite Whether or not the destination file should be
>      *                  overwritten if it already exists.
>      * @param preserveLastModified Whether or not the last modified time of
>      *                             the resulting file should be set to that
>      *                             of the source file.
>      * @param encoding the encoding used to read and write the files.
>      * @param project the project instance.
>      *
>      * @throws IOException if the copying fails.
>      *
>      * @since Ant 1.5
>      */
>     public void copyFile(String sourceFile, String destFile,
>                          FilterSetCollection filters, Vector filterChains,
>                          boolean overwrite, boolean preserveLastModified,
>                          String encoding, Project project)
>         throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a
>      * destination specifying if token filtering must be used, if
>      * filter chains must be used, if source files may overwrite
>      * newer destination files and the last modified time of
>      * <code>destFile</code> file should be made equal
>      * to the last modified time of <code>sourceFile</code>.
>      *
>      * @param sourceFile Name of file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile Name of file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      * @param filterChains filterChains to apply during the copy.
>      * @param overwrite Whether or not the destination file should be
>      *                  overwritten if it already exists.
>      * @param preserveLastModified Whether or not the last modified time of
>      *                             the resulting file should be set to that
>      *                             of the source file.
>      * @param inputEncoding the encoding used to read the files.
>      * @param outputEncoding the encoding used to write the files.
>      * @param project the project instance.
>      *
>      * @throws IOException if the copying fails.
>      *
>      * @since Ant 1.6
>      */
>     public void copyFile(String sourceFile, String destFile,
>                          FilterSetCollection filters, Vector filterChains,
>                          boolean overwrite, boolean preserveLastModified,
>                          String inputEncoding, String outputEncoding,
>                          Project project)
>         throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a destination.
>      * No filtering is performed.
>      *
>      * @param sourceFile the file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile the file to copy to.
>      *                 Must not be <code>null</code>.
>      *
>      * @throws IOException if the copying fails.
>      */
>     public void copyFile(File sourceFile, File destFile) throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a destination
>      * specifying if token filtering must be used.
>      *
>      * @param sourceFile the file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile the file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      *
>      * @throws IOException if the copying fails.
>      */
>     public void copyFile(File sourceFile, File destFile, FilterSetCollection 
> filters)
>         throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a
>      * destination specifying if token filtering must be used and if
>      * source files may overwrite newer destination files.
>      *
>      * @param sourceFile the file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile the file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      * @param overwrite Whether or not the destination file should be
>      *                  overwritten if it already exists.
>      *
>      * @throws IOException if the copying fails.
>      */
>     public void copyFile(File sourceFile, File destFile, FilterSetCollection 
> filters,
>                          boolean overwrite) throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a
>      * destination specifying if token filtering must be used, if
>      * source files may overwrite newer destination files and the
>      * last modified time of <code>destFile</code> file should be made equal
>      * to the last modified time of <code>sourceFile</code>.
>      *
>      * @param sourceFile the file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile the file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      * @param overwrite Whether or not the destination file should be
>      *                  overwritten if it already exists.
>      * @param preserveLastModified Whether or not the last modified time of
>      *                             the resulting file should be set to that
>      *                             of the source file.
>      *
>      * @throws IOException if the copying fails.
>      */
>     public void copyFile(File sourceFile, File destFile, FilterSetCollection 
> filters,
>                          boolean overwrite, boolean preserveLastModified)
>         throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a
>      * destination specifying if token filtering must be used, if
>      * source files may overwrite newer destination files, the last
>      * modified time of <code>destFile</code> file should be made
>      * equal to the last modified time of <code>sourceFile</code> and
>      * which character encoding to assume.
>      *
>      * @param sourceFile the file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile the file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      * @param overwrite Whether or not the destination file should be
>      *                  overwritten if it already exists.
>      * @param preserveLastModified Whether or not the last modified time of
>      *                             the resulting file should be set to that
>      *                             of the source file.
>      * @param encoding the encoding used to read and write the files.
>      *
>      * @throws IOException if the copying fails.
>      *
>      * @since Ant 1.5
>      */
>     public void copyFile(File sourceFile, File destFile,
>                          FilterSetCollection filters, boolean overwrite,
>                          boolean preserveLastModified, String encoding)
>         throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a
>      * destination specifying if token filtering must be used, if
>      * filter chains must be used, if source files may overwrite
>      * newer destination files and the last modified time of
>      * <code>destFile</code> file should be made equal
>      * to the last modified time of <code>sourceFile</code>.
>      *
>      * @param sourceFile the file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile the file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      * @param filterChains filterChains to apply during the copy.
>      * @param overwrite Whether or not the destination file should be
>      *                  overwritten if it already exists.
>      * @param preserveLastModified Whether or not the last modified time of
>      *                             the resulting file should be set to that
>      *                             of the source file.
>      * @param encoding the encoding used to read and write the files.
>      * @param project the project instance.
>      *
>      * @throws IOException if the copying fails.
>      *
>      * @since Ant 1.5
>      */
>     public void copyFile(File sourceFile, File destFile,
>                          FilterSetCollection filters, Vector filterChains,
>                          boolean overwrite, boolean preserveLastModified,
>                          String encoding, Project project)
>         throws IOException;
>     
>     /**
>      * Convenience method to copy a file from a source to a
>      * destination specifying if token filtering must be used, if
>      * filter chains must be used, if source files may overwrite
>      * newer destination files and the last modified time of
>      * <code>destFile</code> file should be made equal
>      * to the last modified time of <code>sourceFile</code>.
>      *
>      * @param sourceFile the file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile the file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      * @param filterChains filterChains to apply during the copy.
>      * @param overwrite Whether or not the destination file should be
>      *                  overwritten if it already exists.
>      * @param preserveLastModified Whether or not the last modified time of
>      *                             the resulting file should be set to that
>      *                             of the source file.
>      * @param inputEncoding the encoding used to read the files.
>      * @param outputEncoding the encoding used to write the files.
>      * @param project the project instance.
>      *
>      *
>      * @throws IOException if the copying fails.
>      *
>      * @since Ant 1.6
>      */
>     public void copyFile(File sourceFile, File destFile,
>                          FilterSetCollection filters, Vector filterChains,
>                          boolean overwrite, boolean preserveLastModified,
>                          String inputEncoding, String outputEncoding,
>                          Project project)
>         throws IOException;
>     
>     /**
>      * Calls File.setLastModified(long time). Originally written to
>      * to dynamically bind to that call on Java1.2+.
>      *
>      * @param file the file whose modified time is to be set
>      * @param time the time to which the last modified time is to be set.
>      *             if this is -1, the current time is used.
>      */
>     public void setFileLastModified(File file, long time);
>     
>     /**
>      * Interpret the filename as a file relative to the given file
>      * unless the filename already represents an absolute filename.
>      * Differs from <code>new File(file, filename)</code> in that
>      * the resulting File's path will always be a normalized,
>      * absolute pathname.  Also, if it is determined that
>      * <code>filename</code> is context-relative, <code>file</code>
>      * will be discarded and the reference will be resolved using
>      * available context/state information about the filesystem.
>      *
>      * @param file the "reference" file for relative paths. This
>      * instance must be an absolute file and must not contain
>      * &quot;./&quot; or &quot;../&quot; sequences (same for \ instead
>      * of /).  If it is null, this call is equivalent to
>      * <code>new java.io.File(filename).getAbsoluteFile()</code>.
>      *
>      * @param filename a file name.
>      *
>      * @return an absolute file.
>      * @throws java.lang.NullPointerException if filename is null.
>      */
>     public File resolveFile(File file, String filename);
>                 
>     /**
>      * &quot;Normalize&quot; the given absolute path.
>      *
>      * <p>This includes:
>      * <ul>
>      *   <li>Uppercase the drive letter if there is one.</li>
>      *   <li>Remove redundant slashes after the drive spec.</li>
>      *   <li>Resolve all ./, .\, ../ and ..\ sequences.</li>
>      *   <li>DOS style paths that start with a drive letter will have
>      *     \ as the separator.</li>
>      * </ul>
>      * Unlike <code>File#getCanonicalPath()</code> this method
>      * specifically does not resolve symbolic links.
>      *
>      * @param path the path to be normalized.
>      * @return the normalized version of the path.
>      *
>      * @throws java.lang.NullPointerException if path is null.
>      */
>     public File normalize(final String path);
>     
>     /**
>      * Dissect the specified absolute path.
>      * @param path the path to dissect.
>      * @return String[] {root, remaining path}.
>      * @throws java.lang.NullPointerException if path is null.
>      * @since Ant 1.7
>      */
>     public String[] dissect(String path);
>     
>     /**
>      * Returns a VMS String representation of a <code>File</code> object.
>      * This is useful since the JVM by default internally converts VMS paths
>      * to Unix style.
>      * The returned String is always an absolute path.
>      *
>      * @param f The <code>File</code> to get the VMS path for.
>      * @return The absolute VMS path to <code>f</code>.
>      */
>     public String toVMSPath(File f);
>     
>     /**
>      * Create a temporary file in a given directory.
>      *
>      * <p>The file denoted by the returned abstract pathname did not
>      * exist before this method was invoked, any subsequent invocation
>      * of this method will yield a different file name.</p>
>      * <p>
>      * The filename is prefixNNNNNsuffix where NNNN is a random number.
>      * </p>
>      * <p>This method is different from File.createTempFile() of JDK 1.2
>      * as it doesn't create the file itself.  It uses the location pointed
>      * to by java.io.tmpdir when the parentDir attribute is null.</p>
>      *
>      * @param prefix prefix before the random number.
>      * @param suffix file extension; include the '.'.
>      * @param parentDir Directory to create the temporary file in;
>      * java.io.tmpdir used if not specified.
>      *
>      * @return a File reference to the new temporary file.
>      * @since Ant 1.5
>      */
>     public File createTempFile(String prefix, String suffix, File parentDir);
>     
>     /**
>      * Compares the contents of two files.
>      *
>      * @param f1 the file whose content is to be compared.
>      * @param f2 the other file whose content is to be compared.
>      *
>      * @return true if the content of the files is the same.
>      *
>      * @throws IOException if the files cannot be read.
>      */
>     public boolean contentEquals(File f1, File f2) throws IOException;
>     
>     /**
>      * Compares the contents of two files.
>      *
>      * @param f1 the file whose content is to be compared.
>      * @param f2 the other file whose content is to be compared.
>      * @param textfile true if the file is to be treated as a text file and
>      *        differences in kind of line break are to be ignored.
>      *
>      * @return true if the content of the files is the same.
>      *
>      * @throws IOException if the files cannot be read.
>      * @since Ant 1.6.3
>      */
>     public boolean contentEquals(File f1, File f2, boolean textfile) throws 
> IOException;
>     
>     /**
>      * This was originally an emulation of [EMAIL PROTECTED] 
> File#getParentFile} for JDK 1.1,
>      * but it is now implemented using that method (Ant 1.6.3 onwards).
>      * @param f the file whose parent is required.
>      * @return the given file's parent, or null if the file does not have a
>      *         parent.
>      * @since 1.10
>      * @deprecated Just use [EMAIL PROTECTED] File#getParentFile} directly.
>      */
>     public File getParentFile(File f);
>     
>     /**
>      * This was originally an emulation of File.createNewFile for JDK 1.1,
>      * but it is now implemented using that method (Ant 1.6.3 onwards).
>      *
>      * <p>This method has historically <strong>not</strong> guaranteed that 
> the
>      * operation was atomic. In its current implementation it is.
>      *
>      * @param f the file to be created.
>      * @return true if the file did not exist already.
>      * @throws IOException on error.
>      * @since Ant 1.5
>      */
>     public boolean createNewFile(File f) throws IOException;
>     
>     /**
>      * Create a new file, optionally creating parent directories.
>      *
>      * @param f the file to be created.
>      * @param mkdirs <code>boolean</code> whether to create parent 
> directories.
>      * @return true if the file did not exist already.
>      * @throws IOException on error.
>      * @since Ant 1.6.3
>      */
>     public boolean createNewFile(File f, boolean mkdirs) throws IOException;
>     
>     /**
>      * Checks whether a given file is a symbolic link.
>      *
>      * <p>It doesn't really test for symbolic links but whether the
>      * canonical and absolute paths of the file are identical--this
>      * may lead to false positives on some platforms.</p>
>      *
>      * @param parent the parent directory of the file to test
>      * @param name the name of the file to test.
>      *
>      * @return true if the file is a symbolic link.
>      * @throws IOException on error.
>      * @since Ant 1.5
>      */
>     public boolean isSymbolicLink(File parent, String name)
>         throws IOException;
>     
>     /**
>      * Removes a leading path from a second path.
>      *
>      * @param leading The leading path, must not be null, must be absolute.
>      * @param path The path to remove from, must not be null, must be 
> absolute.
>      *
>      * @return path's normalized absolute if it doesn't start with
>      * leading; path's path with leading's path removed otherwise.
>      *
>      * @since Ant 1.5
>      */
>     public String removeLeadingPath(File leading, File path);
>     
>     /**
>      * Learn whether one path "leads" another.
>      * @param leading The leading path, must not be null, must be absolute.
>      * @param path The path to remove from, must not be null, must be 
> absolute.
>      * @return true if path starts with leading; false otherwise.
>      * @since Ant 1.7
>      */
>     public boolean isLeadingPath(File leading, File path);
>     
>     /**
>      * Constructs a <code>file:</code> URI that represents the
>      * external form of the given pathname.
>      *
>      * <p>Will be an absolute URI if the given path is absolute.</p>
>      *
>      * <p>This code encodes non ASCII characters too.</p>
>      *
>      * <p>The coding of the output is the same as what 
> File.toURI().toASCIIString() produces</p>
>      *
>      * @see <a href="http://www.w3.org/TR/xml11/#dt-sysid";>dt-sysid</a>
>      * which makes some mention of how
>      * characters not supported by URI Reference syntax should be escaped.
>      *
>      * @param path the path in the local file system.
>      * @return the URI version of the local path.
>      * @since Ant 1.6
>      */
>     public String toURI(String path);
>     
>     /**
>      * Constructs a file path from a <code>file:</code> URI.
>      *
>      * <p>Will be an absolute path if the given URI is absolute.</p>
>      *
>      * <p>Swallows '%' that are not followed by two characters,
>      * doesn't deal with non-ASCII characters.</p>
>      *
>      * @param uri the URI designating a file in the local filesystem.
>      * @return the local file system path for the file.
>      * @since Ant 1.6
>      */
>     public String fromURI(String uri);
>     
>     /**
>      * Compares two filenames.
>      *
>      * <p>Unlike java.io.File#equals this method will try to compare
>      * the absolute paths and &quot;normalize&quot; the filenames
>      * before comparing them.</p>
>      *
>      * @param f1 the file whose name is to be compared.
>      * @param f2 the other file whose name is to be compared.
>      *
>      * @return true if the file are for the same file.
>      *
>      * @since Ant 1.5.3
>      */
>     public boolean fileNameEquals(File f1, File f2);
>     
>     /**
>      * Renames a file, even if that involves crossing file system boundaries.
>      *
>      * <p>This will remove <code>to</code> (if it exists), ensure that
>      * <code>to</code>'s parent directory exists and move
>      * <code>from</code>, which involves deleting <code>from</code> as
>      * well.</p>
>      *
>      * @param from the file to move.
>      * @param to the new file name.
>      *
>      * @throws IOException if anything bad happens during this
>      * process.  Note that <code>to</code> may have been deleted
>      * already when this happens.
>      *
>      * @since Ant 1.6
>      */
>     public void rename(File from, File to) throws IOException;
>     
>     /**
>      * Get the granularity of file timestamps.
>      * The choice is made based on OS, which is incorrect--it should really be
>      * by filesystem. We do not have an easy way to probe for file systems,
>      * however, so this heuristic gives us a decent default.
>      * @return the difference, in milliseconds, which two file timestamps 
> must have
>      * in order for the two files to be considered to have different 
> timestamps.
>      */
>     public long getFileTimestampGranularity();
>     
>     /**
>      * Returns true if the source is older than the dest.
>      * If the dest file does not exist, then the test returns false; it is
>      * implicitly not up do date.
>      * @param source source file (should be the older).
>      * @param dest dest file (should be the newer).
>      * @param granularity an offset added to the source time.
>      * @return true if the source is older than the dest after accounting
>      *              for granularity.
>      * @since Ant 1.6.3
>      */
>     public boolean isUpToDate(File source, File dest, long granularity);
>     
>     /**
>      * Returns true if the source is older than the dest.
>      * @param source source file (should be the older).
>      * @param dest dest file (should be the newer).
>      * @return true if the source is older than the dest, taking the 
> granularity into account.
>      * @since Ant 1.6.3
>      */
>     public boolean isUpToDate(File source, File dest);
>     
>     /**
>      * Compare two timestamps for being up to date using
>      * the specified granularity.
>      *
>      * @param sourceTime timestamp of source file.
>      * @param destTime timestamp of dest file.
>      * @param granularity os/filesys granularity.
>      * @return true if the dest file is considered up to date.
>      */
>     public boolean isUpToDate(long sourceTime, long destTime, long 
> granularity);
>     
>     /**
>      * Compare two timestamps for being up to date using the
>      * current granularity.
>      *
>      * @param sourceTime  timestamp of source file.
>      * @param destTime    timestamp of dest file.
>      * @return true if the dest file is considered up to date.
>      */
>     public boolean isUpToDate(long sourceTime, long destTime);   
> }
>
> Index: 
> D:/java_projects/ant-core-trunk/src/main/org/apache/tools/ant/util/FileUtilsAdapterFactory.java
> ===================================================================
>
> /*
>  * Copyright  2006 The Apache Software Foundation
>  *
>  *  Licensed 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.tools.ant.util;
>
> public class FileUtilsAdapterFactory {
>
>     private FileUtilsAdapterFactory() {}
>     
>     public static FileUtilsAdapter getFileUtils(final String type) {
>         if (type.equals("nio")) {
>             //just print out to see if it's actually picking up the correct 
> class
>             System.out.println("Using nio fileutils");
>             return new NioFileUtils();
>         } else if (type.equals("java6")) {
>             System.out.println("Using java6 fileutils");
>             return new Java6FileUtils();
>         } else {
>             System.out.println("Using classic fileutils");
>             return new FileUtils();
>         }
>     }
>     
>     public static FileUtilsAdapter getBestFileUtils() {
>         final int v = JavaEnvUtils.getJavaVersionNumber();
>         if (v >= 16) {
>             return getFileUtils("java6");
>         } else if (v >=14) {
>             return getFileUtils("nio");
>         } else {
>             return new FileUtils();
>         }
>     }
> }
>
> Index: 
> D:/java_projects/ant-core-trunk/src/main/org/apache/tools/ant/util/NioFileUtils.java
> ===================================================================
>
> /*
>  * Copyright  2006 The Apache Software Foundation
>  *
>  *  Licensed 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.tools.ant.util;
>
> import java.io.BufferedReader;
> import java.io.BufferedWriter;
> import java.io.File;
> import java.io.FileInputStream;
> import java.io.FileOutputStream;
> import java.io.FileReader;
> import java.io.FileWriter;
> import java.io.IOException;
> import java.io.InputStreamReader;
> import java.io.OutputStreamWriter;
> import java.io.Reader;
> import java.nio.channels.FileChannel;
> import java.util.Vector;
> import org.apache.tools.ant.Project;
> import org.apache.tools.ant.filters.util.ChainReaderHelper;
> import org.apache.tools.ant.types.FilterSetCollection;
>
> /**
>  * @author jbleijen
>  */
> public class NioFileUtils extends FileUtils implements FileUtilsAdapter{
>
>     private static final int TRANSFER_SIZE = 81920;
>
>     /**
>      * Empty constructor.
>      */
>     protected NioFileUtils() {
>         super();
>     }
>
>     /**
>      * Convenience method to copy a file from a source to a
>      * destination specifying if token filtering must be used, if
>      * filter chains must be used, if source files may overwrite
>      * newer destination files and the last modified time of
>      * <code>destFile</code> file should be made equal
>      * to the last modified time of <code>sourceFile</code>.
>      *
>      * @param sourceFile the file to copy from.
>      *                   Must not be <code>null</code>.
>      * @param destFile the file to copy to.
>      *                 Must not be <code>null</code>.
>      * @param filters the collection of filters to apply to this copy.
>      * @param filterChains filterChains to apply during the copy.
>      * @param overwrite Whether or not the destination file should be
>      *                  overwritten if it already exists.
>      * @param preserveLastModified Whether or not the last modified time of
>      *                             the resulting file should be set to that
>      *                             of the source file.
>      * @param inputEncoding the encoding used to read the files.
>      * @param outputEncoding the encoding used to write the files.
>      * @param project the project instance.
>      *
>      *
>      * @throws IOException if the copying fails.
>      *
>      * @since Ant 1.6
>      */
>     public void copyFile(File sourceFile, File destFile,
>                          FilterSetCollection filters, Vector filterChains,
>                          boolean overwrite, boolean preserveLastModified,
>                          String inputEncoding, String outputEncoding,
>                          Project project)
>         throws IOException {
>
>         if (overwrite || !destFile.exists()
>             || destFile.lastModified() < sourceFile.lastModified()) {
>
>             if (destFile.exists() && destFile.isFile()) {
>                 destFile.delete();
>             }
>             // ensure that parent dir of dest file exists!
>             // not using getParentFile method to stay 1.1 compat
>             File parent = destFile.getParentFile();
>             if (parent != null && !parent.exists()) {
>                 parent.mkdirs();
>             }
>             final boolean filterSetsAvailable = (filters != null
>                                                  && filters.hasFilters());
>             final boolean filterChainsAvailable = (filterChains != null
>                                                    && filterChains.size() > 
> 0);
>             if (filterSetsAvailable) {
>                 BufferedReader in = null;
>                 BufferedWriter out = null;
>                 try {
>                     if (inputEncoding == null) {
>                         in = new BufferedReader(new FileReader(sourceFile));
>                     } else {
>                         InputStreamReader isr
>                             = new InputStreamReader(new 
> FileInputStream(sourceFile),
>                                                     inputEncoding);
>                         in = new BufferedReader(isr);
>                     }
>                     if (outputEncoding == null) {
>                         out = new BufferedWriter(new FileWriter(destFile));
>                     } else {
>                         OutputStreamWriter osw
>                             = new OutputStreamWriter(new 
> FileOutputStream(destFile),
>                                                      outputEncoding);
>                         out = new BufferedWriter(osw);
>                     }
>                     if (filterChainsAvailable) {
>                         ChainReaderHelper crh = new ChainReaderHelper();
>                         crh.setBufferSize(BUF_SIZE);
>                         crh.setPrimaryReader(in);
>                         crh.setFilterChains(filterChains);
>                         crh.setProject(project);
>                         Reader rdr = crh.getAssembledReader();
>                         in = new BufferedReader(rdr);
>                     }
>                     LineTokenizer lineTokenizer = new LineTokenizer();
>                     lineTokenizer.setIncludeDelims(true);
>                     String newline = null;
>                     String line = lineTokenizer.getToken(in);
>                     while (line != null) {
>                         if (line.length() == 0) {
>                             // this should not happen, because the lines are
>                             // returned with the end of line delimiter
>                             out.newLine();
>                         } else {
>                             newline = filters.replaceTokens(line);
>                             out.write(newline);
>                         }
>                         line = lineTokenizer.getToken(in);
>                     }
>                 } finally {
>                     close(out);
>                     close(in);
>                 }
>             } else if (filterChainsAvailable
>                        || (inputEncoding != null
>                            && !inputEncoding.equals(outputEncoding))
>                        || (inputEncoding == null && outputEncoding != null)) {
>                 BufferedReader in = null;
>                 BufferedWriter out = null;
>                  try {
>                      if (inputEncoding == null) {
>                          in = new BufferedReader(new FileReader(sourceFile));
>                      } else {
>                          in =
>                              new BufferedReader(
>                                  new InputStreamReader(
>                                      new FileInputStream(sourceFile),
>                                      inputEncoding));
>                      }
>                      if (outputEncoding == null) {
>                          out = new BufferedWriter(new FileWriter(destFile));
>                      } else {
>                          out =
>                              new BufferedWriter(
>                                  new OutputStreamWriter(
>                                      new FileOutputStream(destFile),
>                                      outputEncoding));
>                      }
>                      if (filterChainsAvailable) {
>                          ChainReaderHelper crh = new ChainReaderHelper();
>                          crh.setBufferSize(BUF_SIZE);
>                          crh.setPrimaryReader(in);
>                          crh.setFilterChains(filterChains);
>                          crh.setProject(project);
>                          Reader rdr = crh.getAssembledReader();
>                          in = new BufferedReader(rdr);
>                      }
>                      char[] buffer = new char[BUF_SIZE];
>                      while (true) {
>                          int nRead = in.read(buffer, 0, buffer.length);
>                          if (nRead == -1) {
>                              break;
>                          }
>                          out.write(buffer, 0, nRead);
>                       }
>                  } finally {
>                      close(out);
>                      close(in);
>                  }
>             } else {
>                 FileInputStream in = null;
>                 FileOutputStream out = null;
>                 FileChannel srcChannel = null;
>                 FileChannel destChannel = null;
>
>                 try {
>                     // we can use direct copy with nio
>                     in = new FileInputStream(sourceFile);
>                     out = new FileOutputStream(destFile);
>                         
>                     srcChannel = in.getChannel();
>                     destChannel = out.getChannel();
>                     
>                     long position = 0;
>                     long count = srcChannel.size();
>                     while( position < count ) {
>                       position += srcChannel.transferTo(position, 
> TRANSFER_SIZE, destChannel);
>                     }
>                } finally {
>                     if (srcChannel != null)
>                        srcChannel.close();
>                     if (destChannel != null)
>                         destChannel.close();
>                     if (out != null)
>                         out.close();
>                     if (in != null)
>                         in.close();
>                 }
>
>             }
>             if (preserveLastModified) {
>                 setFileLastModified(destFile, sourceFile.lastModified());
>             }
>         }
>     }
> }
>
>
> Index: 
> D:/java_projects/ant-core-trunk/src/main/org/apache/tools/ant/util/Java6FileUtils.java
> ===================================================================
>
> /*
>  * Copyright  2006 The Apache Software Foundation
>  *
>  *  Licensed 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.tools.ant.util;
>
> public class Java6FileUtils extends FileUtils implements FileUtilsAdapter {
>
> }
>
>
>   
> ------------------------------------------------------------------------
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to