diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ResourceUtils.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ResourceUtils.java | 860 |
1 files changed, 0 insertions, 860 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ResourceUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ResourceUtils.java deleted file mode 100644 index 6397f714..00000000 --- a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ResourceUtils.java +++ /dev/null @@ -1,860 +0,0 @@ -/* - * 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.tools.ant.util; - -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -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.nio.channels.FileChannel; -import java.util.Arrays; -import java.util.Vector; - -import org.apache.tools.ant.Project; -import org.apache.tools.ant.ProjectComponent; -import org.apache.tools.ant.filters.util.ChainReaderHelper; -import org.apache.tools.ant.types.FilterSetCollection; -import org.apache.tools.ant.types.Resource; -import org.apache.tools.ant.types.ResourceCollection; -import org.apache.tools.ant.types.ResourceFactory; -import org.apache.tools.ant.types.TimeComparison; -import org.apache.tools.ant.types.resources.Appendable; -import org.apache.tools.ant.types.resources.FileProvider; -import org.apache.tools.ant.types.resources.FileResource; -import org.apache.tools.ant.types.resources.Resources; -import org.apache.tools.ant.types.resources.Restrict; -import org.apache.tools.ant.types.resources.StringResource; -import org.apache.tools.ant.types.resources.Touchable; -import org.apache.tools.ant.types.resources.Union; -import org.apache.tools.ant.types.resources.selectors.Date; -import org.apache.tools.ant.types.resources.selectors.ResourceSelector; -import org.apache.tools.ant.types.selectors.SelectorUtils; - -// CheckStyle:HideUtilityClassConstructorCheck OFF - bc - -/** - * This class provides utility methods to process Resources. - * - * @since Ant 1.5.2 - */ -public class ResourceUtils { - - /** Utilities used for file operations */ - private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); - - /** - * Name of charset "ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1". - * - * @since Ant 1.8.1 - */ - public static final String ISO_8859_1 = "ISO-8859-1"; - - private static final long MAX_IO_CHUNK_SIZE = 16*1024*1024; // 16 MB - - /** - * Tells which source files should be reprocessed based on the - * last modification date of target files. - * @param logTo where to send (more or less) interesting output. - * @param source array of resources bearing relative path and last - * modification date. - * @param mapper filename mapper indicating how to find the target - * files. - * @param targets object able to map as a resource a relative path - * at <b>destination</b>. - * @return array containing the source files which need to be - * copied or processed, because the targets are out of date or do - * not exist. - */ - public static Resource[] selectOutOfDateSources(final ProjectComponent logTo, - final Resource[] source, - final FileNameMapper mapper, - final ResourceFactory targets) { - return selectOutOfDateSources(logTo, source, mapper, targets, - FILE_UTILS.getFileTimestampGranularity()); - } - - /** - * Tells which source files should be reprocessed based on the - * last modification date of target files. - * @param logTo where to send (more or less) interesting output. - * @param source array of resources bearing relative path and last - * modification date. - * @param mapper filename mapper indicating how to find the target - * files. - * @param targets object able to map as a resource a relative path - * at <b>destination</b>. - * @param granularity The number of milliseconds leeway to give - * before deciding a target is out of date. - * @return array containing the source files which need to be - * copied or processed, because the targets are out of date or do - * not exist. - * @since Ant 1.6.2 - */ - public static Resource[] selectOutOfDateSources(final ProjectComponent logTo, - final Resource[] source, - final FileNameMapper mapper, - final ResourceFactory targets, - final long granularity) { - final Union u = new Union(); - u.addAll(Arrays.asList(source)); - final ResourceCollection rc - = selectOutOfDateSources(logTo, u, mapper, targets, granularity); - return rc.size() == 0 ? new Resource[0] : ((Union) rc).listResources(); - } - - /** - * Tells which sources should be reprocessed based on the - * last modification date of targets. - * @param logTo where to send (more or less) interesting output. - * @param source ResourceCollection. - * @param mapper filename mapper indicating how to find the target Resources. - * @param targets object able to map a relative path as a Resource. - * @param granularity The number of milliseconds leeway to give - * before deciding a target is out of date. - * @return ResourceCollection. - * @since Ant 1.7 - */ - public static ResourceCollection selectOutOfDateSources(final ProjectComponent logTo, - final ResourceCollection source, - final FileNameMapper mapper, - final ResourceFactory targets, - final long granularity) { - logFuture(logTo, source, granularity); - final ResourceSelectorProvider p = - new ResourceSelectorProvider() { - public ResourceSelector - getTargetSelectorForSource(final Resource sr) { - return new ResourceSelector() { - public boolean isSelected(final Resource target) { - /* Extra I/O, probably wasted: - if (target.isDirectory()) { - return false; - } - */ - return SelectorUtils.isOutOfDate(sr, target, - granularity); - } - }; - } - }; - return selectSources(logTo, source, mapper, targets, p); - } - - /** - * Tells which sources should be reprocessed because the given - * selector selects at least one target. - * - * @param logTo where to send (more or less) interesting output. - * @param source ResourceCollection. - * @param mapper filename mapper indicating how to find the target Resources. - * @param targets object able to map a relative path as a Resource. - * @param selector returns a selector that is applied to target - * files. If it selects at least one target the source will be - * added to the returned collection. - * @return ResourceCollection. - * @since Ant 1.8.0 - */ - public static ResourceCollection selectSources(final ProjectComponent logTo, - ResourceCollection source, - final FileNameMapper mapper, - final ResourceFactory targets, - final ResourceSelectorProvider selector) { - if (source.size() == 0) { - logTo.log("No sources found.", Project.MSG_VERBOSE); - return Resources.NONE; - } - source = Union.getInstance(source); - - final Union result = new Union(); - for (final Resource sr : source) { - String srName = sr.getName(); - srName = srName == null - ? srName : srName.replace('/', File.separatorChar); - - String[] targetnames = null; - try { - targetnames = mapper.mapFileName(srName); - } catch (final Exception e) { - logTo.log("Caught " + e + " mapping resource " + sr, - Project.MSG_VERBOSE); - } - if (targetnames == null || targetnames.length == 0) { - logTo.log(sr + " skipped - don\'t know how to handle it", - Project.MSG_VERBOSE); - continue; - } - for (int i = 0; i < targetnames.length; i++) { - if (targetnames[i] == null) { - targetnames[i] = "(no name)"; - } - } - final Union targetColl = new Union(); - for (int i = 0; i < targetnames.length; i++) { - targetColl.add(targets.getResource( - targetnames[i].replace(File.separatorChar, '/'))); - } - //find the out-of-date targets: - final Restrict r = new Restrict(); - r.add(selector.getTargetSelectorForSource(sr)); - r.add(targetColl); - if (r.size() > 0) { - result.add(sr); - final Resource t = r.iterator().next(); - logTo.log(sr.getName() + " added as " + t.getName() - + (t.isExists() ? " is outdated." : " doesn\'t exist."), - Project.MSG_VERBOSE); - continue; - } - //log uptodateness of all targets: - logTo.log(sr.getName() - + " omitted as " + targetColl.toString() - + (targetColl.size() == 1 ? " is" : " are ") - + " up to date.", Project.MSG_VERBOSE); - } - return result; - } - - /** - * Convenience method to copy content from one Resource to another. - * No filtering is performed. - * - * @param source the Resource to copy from. - * Must not be <code>null</code>. - * @param dest the Resource to copy to. - * Must not be <code>null</code>. - * - * @throws IOException if the copying fails. - * - * @since Ant 1.7 - */ - public static void copyResource(final Resource source, final Resource dest) throws IOException { - copyResource(source, dest, null); - } - - /** - * Convenience method to copy content from one Resource to another. - * No filtering is performed. - * - * @param source the Resource to copy from. - * Must not be <code>null</code>. - * @param dest the Resource to copy to. - * Must not be <code>null</code>. - * @param project the project instance. - * - * @throws IOException if the copying fails. - * - * @since Ant 1.7 - */ - public static void copyResource(final Resource source, final Resource dest, final Project project) - throws IOException { - copyResource(source, dest, null, null, false, - false, null, null, project); - } - - // CheckStyle:ParameterNumberCheck OFF - bc - /** - * Convenience method to copy content from one Resource to another - * specifying whether token filtering must be used, whether filter chains - * must be used, whether newer destination files may be overwritten and - * whether the last modified time of <code>dest</code> file should be made - * equal to the last modified time of <code>source</code>. - * - * @param source the Resource to copy from. - * Must not be <code>null</code>. - * @param dest the Resource 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 Resource should be - * overwritten if it already exists. - * @param preserveLastModified Whether or not the last modified time of - * the destination Resource should be set to that - * of the source. - * @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.7 - */ - public static void copyResource(final Resource source, final Resource dest, - final FilterSetCollection filters, final Vector filterChains, - final boolean overwrite, final boolean preserveLastModified, - final String inputEncoding, final String outputEncoding, - final Project project) - throws IOException { - copyResource(source, dest, filters, filterChains, overwrite, preserveLastModified, false, inputEncoding, outputEncoding, project); - } - - // CheckStyle:ParameterNumberCheck OFF - bc - /** - * Convenience method to copy content from one Resource to another - * specifying whether token filtering must be used, whether filter chains - * must be used, whether newer destination files may be overwritten and - * whether the last modified time of <code>dest</code> file should be made - * equal to the last modified time of <code>source</code>. - * - * @param source the Resource to copy from. - * Must not be <code>null</code>. - * @param dest the Resource 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 Resource should be - * overwritten if it already exists. - * @param preserveLastModified Whether or not the last modified time of - * the destination Resource should be set to that - * of the source. - * @param append Whether to append to an Appendable Resource. - * @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.8 - */ - public static void copyResource(final Resource source, final Resource dest, - final FilterSetCollection filters, final Vector filterChains, - final boolean overwrite, final boolean preserveLastModified, - final boolean append, - final String inputEncoding, final String outputEncoding, - final Project project) - throws IOException { - copyResource(source, dest, filters, filterChains, overwrite, - preserveLastModified, append, inputEncoding, - outputEncoding, project, /* force: */ false); - } - - /** - * Convenience method to copy content from one Resource to another - * specifying whether token filtering must be used, whether filter chains - * must be used, whether newer destination files may be overwritten and - * whether the last modified time of <code>dest</code> file should be made - * equal to the last modified time of <code>source</code>. - * - * @param source the Resource to copy from. - * Must not be <code>null</code>. - * @param dest the Resource 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 Resource should be - * overwritten if it already exists. - * @param preserveLastModified Whether or not the last modified time of - * the destination Resource should be set to that - * of the source. - * @param append Whether to append to an Appendable Resource. - * @param inputEncoding the encoding used to read the files. - * @param outputEncoding the encoding used to write the files. - * @param project the project instance. - * @param force whether read-only target files will be overwritten - * - * @throws IOException if the copying fails. - * - * @since Ant 1.8.2 - */ - public static void copyResource(final Resource source, final Resource dest, - final FilterSetCollection filters, final Vector filterChains, - final boolean overwrite, final boolean preserveLastModified, - final boolean append, - final String inputEncoding, final String outputEncoding, - final Project project, final boolean force) - throws IOException { - if (!(overwrite || SelectorUtils.isOutOfDate(source, dest, FileUtils.getFileUtils() - .getFileTimestampGranularity()))) { - return; - } - final boolean filterSetsAvailable = (filters != null - && filters.hasFilters()); - final boolean filterChainsAvailable = (filterChains != null - && filterChains.size() > 0); - String effectiveInputEncoding = null; - if (source instanceof StringResource) { - effectiveInputEncoding = ((StringResource) source).getEncoding(); - } else { - effectiveInputEncoding = inputEncoding; - } - File destFile = null; - if (dest.as(FileProvider.class) != null) { - destFile = dest.as(FileProvider.class).getFile(); - } - if (destFile != null && destFile.isFile() && !destFile.canWrite()) { - if (!force) { - throw new ReadOnlyTargetFileException(destFile); - } else if (!FILE_UTILS.tryHardToDelete(destFile)) { - throw new IOException("failed to delete read-only " - + "destination file " + destFile); - } - } - - if (filterSetsAvailable) { - copyWithFilterSets(source, dest, filters, filterChains, - filterChainsAvailable, append, - effectiveInputEncoding, outputEncoding, - project); - } else if (filterChainsAvailable - || (effectiveInputEncoding != null - && !effectiveInputEncoding.equals(outputEncoding)) - || (effectiveInputEncoding == null && outputEncoding != null)) { - copyWithFilterChainsOrTranscoding(source, dest, filterChains, - filterChainsAvailable, append, - effectiveInputEncoding, - outputEncoding, project); - } else { - boolean copied = false; - if (source.as(FileProvider.class) != null - && destFile != null && !append) { - final File sourceFile = - source.as(FileProvider.class).getFile(); - try { - copyUsingFileChannels(sourceFile, destFile); - copied = true; - } catch (final IOException ex) { - String msg = "Attempt to copy " + sourceFile - + " to " + destFile + " using NIO Channels" - + " failed due to '" + ex.getMessage() - + "'. Falling back to streams."; - if (project != null) { - project.log(msg, Project.MSG_WARN); - } else { - System.err.println(msg); - } - } - } - if (!copied) { - copyUsingStreams(source, dest, append, project); - } - } - if (preserveLastModified) { - final Touchable t = dest.as(Touchable.class); - if (t != null) { - setLastModified(t, source.getLastModified()); - } - } - } - // CheckStyle:ParameterNumberCheck ON - - /** - * Set the last modified time of an object implementing - * org.apache.tools.ant.types.resources.Touchable . - * - * @param t the Touchable 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. - * @since Ant 1.7 - */ - public static void setLastModified(final Touchable t, final long time) { - t.touch((time < 0) ? System.currentTimeMillis() : time); - } - - /** - * Compares the contents of two Resources. - * - * @param r1 the Resource whose content is to be compared. - * @param r2 the other Resource whose content is to be compared. - * @param text true if the content is to be treated as text and - * differences in kind of line break are to be ignored. - * - * @return true if the content of the Resources is the same. - * - * @throws IOException if the Resources cannot be read. - * @since Ant 1.7 - */ - public static boolean contentEquals(final Resource r1, final Resource r2, final boolean text) throws IOException { - if (r1.isExists() != r2.isExists()) { - return false; - } - if (!r1.isExists()) { - // two not existing files are equal - return true; - } - // should the following two be switched? If r1 and r2 refer to the same file, - // isn't their content equal regardless of whether that file is a directory? - if (r1.isDirectory() || r2.isDirectory()) { - // don't want to compare directory contents for now - return false; - } - if (r1.equals(r2)) { - return true; - } - if (!text) { - final long s1 = r1.getSize(); - final long s2 = r2.getSize(); - if (s1 != Resource.UNKNOWN_SIZE && s2 != Resource.UNKNOWN_SIZE - && s1 != s2) { - return false; - } - } - return compareContent(r1, r2, text) == 0; - } - - /** - * Compare the content of two Resources. A nonexistent Resource's - * content is "less than" that of an existing Resource; a directory-type - * Resource's content is "less than" that of a file-type Resource. - * @param r1 the Resource whose content is to be compared. - * @param r2 the other Resource whose content is to be compared. - * @param text true if the content is to be treated as text and - * differences in kind of line break are to be ignored. - * @return a negative integer, zero, or a positive integer as the first - * argument is less than, equal to, or greater than the second. - * @throws IOException if the Resources cannot be read. - * @since Ant 1.7 - */ - public static int compareContent(final Resource r1, final Resource r2, final boolean text) throws IOException { - if (r1.equals(r2)) { - return 0; - } - final boolean e1 = r1.isExists(); - final boolean e2 = r2.isExists(); - if (!(e1 || e2)) { - return 0; - } - if (e1 != e2) { - return e1 ? 1 : -1; - } - final boolean d1 = r1.isDirectory(); - final boolean d2 = r2.isDirectory(); - if (d1 && d2) { - return 0; - } - if (d1 || d2) { - return d1 ? -1 : 1; - } - return text ? textCompare(r1, r2) : binaryCompare(r1, r2); - } - - /** - * Convenience method to turn any fileProvider into a basic - * FileResource with the file's immediate parent as the basedir, - * for tasks that need one. - * @param fileProvider input - * @return fileProvider if it is a FileResource instance, or a new - * FileResource with fileProvider's file. - * @since Ant 1.8 - */ - public static FileResource asFileResource(final FileProvider fileProvider) { - if (fileProvider instanceof FileResource || fileProvider == null) { - return (FileResource) fileProvider; - } - final FileResource result = new FileResource(fileProvider.getFile()); - result.setProject(Project.getProject(fileProvider)); - return result; - } - - /** - * Binary compares the contents of two Resources. - * <p> - * simple but sub-optimal comparison algorithm. written for working - * rather than fast. Better would be a block read into buffers followed - * by long comparisons apart from the final 1-7 bytes. - * </p> - * - * @param r1 the Resource whose content is to be compared. - * @param r2 the other Resource whose content is to be compared. - * @return a negative integer, zero, or a positive integer as the first - * argument is less than, equal to, or greater than the second. - * @throws IOException if the Resources cannot be read. - * @since Ant 1.7 - */ - private static int binaryCompare(final Resource r1, final Resource r2) throws IOException { - InputStream in1 = null; - InputStream in2 = null; - try { - in1 = new BufferedInputStream(r1.getInputStream()); - in2 = new BufferedInputStream(r2.getInputStream()); - - for (int b1 = in1.read(); b1 != -1; b1 = in1.read()) { - final int b2 = in2.read(); - if (b1 != b2) { - return b1 > b2 ? 1 : -1; - } - } - return in2.read() == -1 ? 0 : -1; - } finally { - FileUtils.close(in1); - FileUtils.close(in2); - } - } - - /** - * Text compares the contents of two Resources. - * Ignores different kinds of line endings. - * @param r1 the Resource whose content is to be compared. - * @param r2 the other Resource whose content is to be compared. - * @return a negative integer, zero, or a positive integer as the first - * argument is less than, equal to, or greater than the second. - * @throws IOException if the Resources cannot be read. - * @since Ant 1.7 - */ - private static int textCompare(final Resource r1, final Resource r2) throws IOException { - BufferedReader in1 = null; - BufferedReader in2 = null; - try { - in1 = new BufferedReader(new InputStreamReader(r1.getInputStream())); - in2 = new BufferedReader(new InputStreamReader(r2.getInputStream())); - - String expected = in1.readLine(); - while (expected != null) { - final String actual = in2.readLine(); - if (!expected.equals(actual)) { - if (actual == null) { - return 1; - } - return expected.compareTo(actual); - } - expected = in1.readLine(); - } - return in2.readLine() == null ? 0 : -1; - } finally { - FileUtils.close(in1); - FileUtils.close(in2); - } - } - - /** - * Log which Resources (if any) have been modified in the future. - * @param logTo the ProjectComponent to do the logging. - * @param rc the collection of Resources to check. - * @param granularity the timestamp granularity to use. - * @since Ant 1.7 - */ - private static void logFuture(final ProjectComponent logTo, - final ResourceCollection rc, final long granularity) { - final long now = System.currentTimeMillis() + granularity; - final Date sel = new Date(); - sel.setMillis(now); - sel.setWhen(TimeComparison.AFTER); - final Restrict future = new Restrict(); - future.add(sel); - future.add(rc); - for (final Resource r : future) { - logTo.log("Warning: " + r.getName() + " modified in the future.", Project.MSG_WARN); - } - } - - private static void copyWithFilterSets(final Resource source, final Resource dest, - final FilterSetCollection filters, - final Vector filterChains, - final boolean filterChainsAvailable, - final boolean append, final String inputEncoding, - final String outputEncoding, - final Project project) - throws IOException { - BufferedReader in = null; - BufferedWriter out = null; - try { - InputStreamReader isr = null; - if (inputEncoding == null) { - isr = new InputStreamReader(source.getInputStream()); - } else { - isr = new InputStreamReader(source.getInputStream(), - inputEncoding); - } - in = new BufferedReader(isr); - final OutputStream os = getOutputStream(dest, append, project); - OutputStreamWriter osw; - if (outputEncoding == null) { - osw = new OutputStreamWriter(os); - } else { - osw = new OutputStreamWriter(os, outputEncoding); - } - out = new BufferedWriter(osw); - if (filterChainsAvailable) { - final ChainReaderHelper crh = new ChainReaderHelper(); - crh.setBufferSize(FileUtils.BUF_SIZE); - crh.setPrimaryReader(in); - crh.setFilterChains(filterChains); - crh.setProject(project); - final Reader rdr = crh.getAssembledReader(); - in = new BufferedReader(rdr); - } - final 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 { - FileUtils.close(out); - FileUtils.close(in); - } - } - - private static void copyWithFilterChainsOrTranscoding(final Resource source, - final Resource dest, - final Vector filterChains, - final boolean filterChainsAvailable, - final boolean append, - final String inputEncoding, - final String outputEncoding, - final Project project) - throws IOException { - BufferedReader in = null; - BufferedWriter out = null; - try { - InputStreamReader isr = null; - if (inputEncoding == null) { - isr = new InputStreamReader(source.getInputStream()); - } else { - isr = new InputStreamReader(source.getInputStream(), - inputEncoding); - } - in = new BufferedReader(isr); - final OutputStream os = getOutputStream(dest, append, project); - OutputStreamWriter osw; - if (outputEncoding == null) { - osw = new OutputStreamWriter(os); - } else { - osw = new OutputStreamWriter(os, outputEncoding); - } - out = new BufferedWriter(osw); - if (filterChainsAvailable) { - final ChainReaderHelper crh = new ChainReaderHelper(); - crh.setBufferSize(FileUtils.BUF_SIZE); - crh.setPrimaryReader(in); - crh.setFilterChains(filterChains); - crh.setProject(project); - final Reader rdr = crh.getAssembledReader(); - in = new BufferedReader(rdr); - } - final char[] buffer = new char[FileUtils.BUF_SIZE]; - while (true) { - final int nRead = in.read(buffer, 0, buffer.length); - if (nRead == -1) { - break; - } - out.write(buffer, 0, nRead); - } - } finally { - FileUtils.close(out); - FileUtils.close(in); - } - } - - private static void copyUsingFileChannels(final File sourceFile, - final File destFile) - throws IOException { - - final File parent = destFile.getParentFile(); - if (parent != null && !parent.isDirectory() - && !(parent.mkdirs() || parent.isDirectory())) { - throw new IOException("failed to create the parent directory" - + " for " + destFile); - } - - FileInputStream in = null; - FileOutputStream out = null; - FileChannel srcChannel = null; - FileChannel destChannel = null; - - try { - in = new FileInputStream(sourceFile); - out = new FileOutputStream(destFile); - - srcChannel = in.getChannel(); - destChannel = out.getChannel(); - - long position = 0; - final long count = srcChannel.size(); - while (position < count) { - final long chunk = Math.min(MAX_IO_CHUNK_SIZE, count - position); - position += - destChannel.transferFrom(srcChannel, position, chunk); - } - } finally { - FileUtils.close(srcChannel); - FileUtils.close(destChannel); - FileUtils.close(out); - FileUtils.close(in); - } - } - - private static void copyUsingStreams(final Resource source, final Resource dest, - final boolean append, final Project project) - throws IOException { - InputStream in = null; - OutputStream out = null; - try { - in = source.getInputStream(); - out = getOutputStream(dest, append, project); - - final byte[] buffer = new byte[FileUtils.BUF_SIZE]; - int count = 0; - do { - out.write(buffer, 0, count); - count = in.read(buffer, 0, buffer.length); - } while (count != -1); - } finally { - FileUtils.close(out); - FileUtils.close(in); - } - } - - private static OutputStream getOutputStream(final Resource resource, final boolean append, final Project project) - throws IOException { - if (append) { - final Appendable a = resource.as(Appendable.class); - if (a != null) { - return a.getAppendOutputStream(); - } - String msg = "Appendable OutputStream not available for non-appendable resource " - + resource + "; using plain OutputStream"; - if (project != null) { - project.log(msg, Project.MSG_VERBOSE); - } else { - System.out.println(msg); - } - } - return resource.getOutputStream(); - } - - public interface ResourceSelectorProvider { - ResourceSelector getTargetSelectorForSource(Resource source); - } - - /** - * @since Ant 1.9.4 - */ - public static class ReadOnlyTargetFileException extends IOException { - private static final long serialVersionUID = 1L; - - public ReadOnlyTargetFileException(final File destFile) { - super("can't write to read-only destination file " + destFile); - } - } -} |