diff --git a/src/main/org/apache/tools/ant/types/resources/comparators/Content.java b/src/main/org/apache/tools/ant/types/resources/comparators/Content.java
index d212cf037..9b2db8d11 100755
--- a/src/main/org/apache/tools/ant/types/resources/comparators/Content.java
+++ b/src/main/org/apache/tools/ant/types/resources/comparators/Content.java
@@ -20,7 +20,7 @@ import java.io.IOException;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.ResourceUtils;
/**
* Compares Resources by content.
@@ -60,7 +60,7 @@ public class Content extends ResourceComparator {
*/
protected int resourceCompare(Resource foo, Resource bar) {
try {
- return FileUtils.getFileUtils().compareContent(foo, bar, !binary);
+ return ResourceUtils.compareContent(foo, bar, !binary);
} catch (IOException e) {
throw new BuildException(e);
}
diff --git a/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java b/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java
index 89bffe2ef..83e719279 100644
--- a/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java
@@ -38,6 +38,7 @@ import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
import org.apache.tools.ant.types.selectors.BaseExtendSelector;
import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.ResourceUtils;
/**
@@ -540,7 +541,7 @@ public class ModifiedSelector extends BaseExtendSelector
FileUtils fu = FileUtils.getFileUtils();
File tmpFile = fu.createTempFile("modified-", ".tmp", null);
Resource tmpResource = new FileResource(tmpFile);
- fu.copyResource(resource, tmpResource);
+ ResourceUtils.copyResource(resource, tmpResource);
boolean isSelected = isSelected(tmpFile.getParentFile(),
tmpFile.getName(),
resource.toLongString());
diff --git a/src/main/org/apache/tools/ant/util/FileUtils.java b/src/main/org/apache/tools/ant/util/FileUtils.java
index 2d9846c39..aa71197ec 100644
--- a/src/main/org/apache/tools/ant/util/FileUtils.java
+++ b/src/main/org/apache/tools/ant/util/FileUtils.java
@@ -41,9 +41,7 @@ import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.filters.util.ChainReaderHelper;
import org.apache.tools.ant.taskdefs.condition.Os;
-import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.FilterSetCollection;
-import org.apache.tools.ant.types.resources.Touchable;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.launch.Locator;
@@ -54,7 +52,6 @@ import org.apache.tools.ant.launch.Locator;
* their last modification time.
*
*/
-
public class FileUtils {
private static final FileUtils PRIMARY_INSTANCE = new FileUtils();
@@ -68,7 +65,7 @@ public class FileUtils {
private static boolean onWin9x = Os.isFamily("win9x");
private static boolean onWindows = Os.isFamily("windows");
- private static final int BUF_SIZE = 8192;
+ static final int BUF_SIZE = 8192;
// for toURI
private static boolean[] isSpecial = new boolean[256];
@@ -520,206 +517,12 @@ public class FileUtils {
String inputEncoding, String outputEncoding,
Project project)
throws IOException {
- copyResource(new FileResource(sourceFile), new FileResource(destFile),
+ ResourceUtils.copyResource(
+ new FileResource(sourceFile), new FileResource(destFile),
filters, filterChains, overwrite, preserveLastModified,
inputEncoding, outputEncoding, project);
}
- /**
- * Convenience method to copy content from one Resource to another.
- * No filtering is performed.
- *
- * @param source the Resource to copy from.
- * Must not be null
.
- * @param dest the Resource to copy to.
- * Must not be null
.
- *
- * @throws IOException if the copying fails.
- *
- * @since Ant 1.7
- */
- public void copyResource(Resource source, 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 null
.
- * @param dest the Resource to copy to.
- * Must not be null
.
- * @param project the project instance.
- *
- * @throws IOException if the copying fails.
- *
- * @since Ant 1.7
- */
- public void copyResource(Resource source, Resource dest, Project project)
- throws IOException {
- copyResource(source, dest, null, null, false,
- false, null, null, project);
- }
-
- /**
- * 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 dest
file should be made
- * equal to the last modified time of source
.
- *
- * @param source the Resource to copy from.
- * Must not be null
.
- * @param dest the Resource to copy to.
- * Must not be null
.
- * @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 void copyResource(Resource source, Resource dest,
- FilterSetCollection filters, Vector filterChains,
- boolean overwrite, boolean preserveLastModified,
- String inputEncoding, String outputEncoding,
- Project project)
- throws IOException {
- if (!overwrite) {
- long slm = source.getLastModified();
- if (dest.isExists() && slm != 0
- && dest.getLastModified() > slm) {
- return;
- }
- }
- final boolean filterSetsAvailable = (filters != null
- && filters.hasFilters());
- final boolean filterChainsAvailable = (filterChains != null
- && filterChains.size() > 0);
- if (filterSetsAvailable) {
- 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);
- OutputStreamWriter osw = null;
- if (outputEncoding == null) {
- osw = new OutputStreamWriter(dest.getOutputStream());
- } else {
- osw = new OutputStreamWriter(dest.getOutputStream(),
- 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 {
- InputStreamReader isr = null;
- if (inputEncoding == null) {
- isr = new InputStreamReader(source.getInputStream());
- } else {
- isr = new InputStreamReader(source.getInputStream(),
- inputEncoding);
- }
- in = new BufferedReader(isr);
- OutputStreamWriter osw = null;
- if (outputEncoding == null) {
- osw = new OutputStreamWriter(dest.getOutputStream());
- } else {
- osw = new OutputStreamWriter(dest.getOutputStream(),
- 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);
- }
- 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 {
- InputStream in = null;
- OutputStream out = null;
- try {
- in = source.getInputStream();
- out = dest.getOutputStream();
-
- byte[] buffer = new byte[BUF_SIZE];
- int count = 0;
- do {
- out.write(buffer, 0, count);
- count = in.read(buffer, 0, buffer.length);
- } while (count != -1);
- } finally {
- close(out);
- close(in);
- }
- }
- if (preserveLastModified && dest instanceof Touchable) {
- setLastModified((Touchable) dest, source.getLastModified());
- }
- }
-
/**
* Calls File.setLastModified(long time). Originally written to
* to dynamically bind to that call on Java1.2+.
@@ -729,19 +532,7 @@ public class FileUtils {
* if this is -1, the current time is used.
*/
public void setFileLastModified(File file, long time) {
- setLastModified(new FileResource(file), time);
- }
-
- /**
- * 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.
- */
- public void setLastModified(Touchable t, long time) {
- t.touch((time < 0) ? System.currentTimeMillis() : time);
+ ResourceUtils.setLastModified(new FileResource(file), time);
}
/**
@@ -897,6 +688,7 @@ public class FileUtils {
* @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) {
char sep = File.separatorChar;
@@ -1063,143 +855,8 @@ public class FileUtils {
* @since Ant 1.6.3
*/
public boolean contentEquals(File f1, File f2, boolean textfile) throws IOException {
- return contentEquals(new FileResource(f1), new FileResource(f2), textfile);
- }
-
- /**
- * 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.6.3
- */
- public boolean contentEquals(Resource r1, Resource r2, 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 && r1.getSize() != r2.getSize()) {
- 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.
- */
- public int compareContent(Resource r1, Resource r2, boolean text) throws IOException {
- if (r1.equals(r2)) {
- return 0;
- }
- boolean e1 = r1.isExists();
- boolean e2 = r2.isExists();
- if (!(e1 || e2)) {
- return 0;
- }
- if (e1 != e2) {
- return e1 ? 1 : -1;
- }
- boolean d1 = r1.isDirectory();
- boolean d2 = r2.isDirectory();
- if (d1 && d2) {
- return 0;
- }
- if (d1 || d2) {
- return d1 ? -1 : 1;
- }
- return text ? textCompare(r1, r2) : binaryCompare(r1, r2);
- }
-
- /**
- * Binary compares the contents of two Resources.
- *
- * simple but sub-optimal comparision algorithm. written for working - * rather than fast. Better would be a block read into buffers followed - * by long comparisions apart from the final 1-7 bytes. - *
- * - * @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. - */ - private int binaryCompare(Resource r1, 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()) { - int b2 = in2.read(); - if (b1 != b2) { - return b1 > b2 ? 1 : -1; - } - } - return in2.read() == -1 ? 0 : -1; - } finally { - close(in1); - 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. - */ - private int textCompare(Resource r1, 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) { - String actual = in2.readLine(); - if (!expected.equals(actual)) { - return expected.compareTo(actual); - } - expected = in1.readLine(); - } - return in2.readLine() == null ? 0 : -1; - } finally { - close(in1); - close(in2); - } + return ResourceUtils.contentEquals( + new FileResource(f1), new FileResource(f2), textfile); } /** diff --git a/src/main/org/apache/tools/ant/util/ResourceUtils.java b/src/main/org/apache/tools/ant/util/ResourceUtils.java index ff79f2bd4..ce3ff8ace 100644 --- a/src/main/org/apache/tools/ant/util/ResourceUtils.java +++ b/src/main/org/apache/tools/ant/util/ResourceUtils.java @@ -17,18 +17,31 @@ package org.apache.tools.ant.util; import java.io.File; +import java.io.Reader; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.BufferedInputStream; import java.util.Arrays; +import java.util.Vector; import java.util.Iterator; 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.Resource; import org.apache.tools.ant.types.TimeComparison; import org.apache.tools.ant.types.ResourceFactory; import org.apache.tools.ant.types.ResourceCollection; +import org.apache.tools.ant.types.FilterSetCollection; import org.apache.tools.ant.types.resources.Union; import org.apache.tools.ant.types.resources.Restrict; import org.apache.tools.ant.types.resources.Resources; +import org.apache.tools.ant.types.resources.Touchable; import org.apache.tools.ant.types.resources.selectors.Or; import org.apache.tools.ant.types.resources.selectors.And; import org.apache.tools.ant.types.resources.selectors.Not; @@ -175,6 +188,360 @@ public class ResourceUtils { 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 benull
.
+ * @param dest the Resource to copy to.
+ * Must not be null
.
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.7
+ */
+ public static void copyResource(Resource source, 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 null
.
+ * @param dest the Resource to copy to.
+ * Must not be null
.
+ * @param project the project instance.
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.7
+ */
+ public static void copyResource(Resource source, Resource dest, Project project)
+ throws IOException {
+ copyResource(source, dest, null, null, false,
+ false, null, null, project);
+ }
+
+ /**
+ * 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 dest
file should be made
+ * equal to the last modified time of source
.
+ *
+ * @param source the Resource to copy from.
+ * Must not be null
.
+ * @param dest the Resource to copy to.
+ * Must not be null
.
+ * @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(Resource source, Resource dest,
+ FilterSetCollection filters, Vector filterChains,
+ boolean overwrite, boolean preserveLastModified,
+ String inputEncoding, String outputEncoding,
+ Project project)
+ throws IOException {
+ if (!overwrite) {
+ long slm = source.getLastModified();
+ if (dest.isExists() && slm != 0
+ && dest.getLastModified() > slm) {
+ return;
+ }
+ }
+ final boolean filterSetsAvailable = (filters != null
+ && filters.hasFilters());
+ final boolean filterChainsAvailable = (filterChains != null
+ && filterChains.size() > 0);
+ if (filterSetsAvailable) {
+ 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);
+ OutputStreamWriter osw = null;
+ if (outputEncoding == null) {
+ osw = new OutputStreamWriter(dest.getOutputStream());
+ } else {
+ osw = new OutputStreamWriter(dest.getOutputStream(),
+ outputEncoding);
+ }
+ out = new BufferedWriter(osw);
+ if (filterChainsAvailable) {
+ ChainReaderHelper crh = new ChainReaderHelper();
+ crh.setBufferSize(FileUtils.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 {
+ FileUtils.close(out);
+ FileUtils.close(in);
+ }
+ } else if (filterChainsAvailable
+ || (inputEncoding != null
+ && !inputEncoding.equals(outputEncoding))
+ || (inputEncoding == null && outputEncoding != null)) {
+ 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);
+ OutputStreamWriter osw = null;
+ if (outputEncoding == null) {
+ osw = new OutputStreamWriter(dest.getOutputStream());
+ } else {
+ osw = new OutputStreamWriter(dest.getOutputStream(),
+ outputEncoding);
+ }
+ out = new BufferedWriter(osw);
+ if (filterChainsAvailable) {
+ ChainReaderHelper crh = new ChainReaderHelper();
+ crh.setBufferSize(FileUtils.BUF_SIZE);
+ crh.setPrimaryReader(in);
+ crh.setFilterChains(filterChains);
+ crh.setProject(project);
+ Reader rdr = crh.getAssembledReader();
+ in = new BufferedReader(rdr);
+ }
+ char[] buffer = new char[FileUtils.BUF_SIZE];
+ while (true) {
+ int nRead = in.read(buffer, 0, buffer.length);
+ if (nRead == -1) {
+ break;
+ }
+ out.write(buffer, 0, nRead);
+ }
+ } finally {
+ FileUtils.close(out);
+ FileUtils.close(in);
+ }
+ } else {
+ InputStream in = null;
+ OutputStream out = null;
+ try {
+ in = source.getInputStream();
+ out = dest.getOutputStream();
+
+ 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);
+ }
+ }
+ if (preserveLastModified && dest instanceof Touchable) {
+ setLastModified((Touchable) dest, source.getLastModified());
+ }
+ }
+
+ /**
+ * 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(Touchable t, 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(Resource r1, Resource r2, 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 && r1.getSize() != r2.getSize()) {
+ 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(Resource r1, Resource r2, boolean text) throws IOException {
+ if (r1.equals(r2)) {
+ return 0;
+ }
+ boolean e1 = r1.isExists();
+ boolean e2 = r2.isExists();
+ if (!(e1 || e2)) {
+ return 0;
+ }
+ if (e1 != e2) {
+ return e1 ? 1 : -1;
+ }
+ boolean d1 = r1.isDirectory();
+ boolean d2 = r2.isDirectory();
+ if (d1 && d2) {
+ return 0;
+ }
+ if (d1 || d2) {
+ return d1 ? -1 : 1;
+ }
+ return text ? textCompare(r1, r2) : binaryCompare(r1, r2);
+ }
+
+ /**
+ * Binary compares the contents of two Resources.
+ * + * simple but sub-optimal comparision algorithm. written for working + * rather than fast. Better would be a block read into buffers followed + * by long comparisions apart from the final 1-7 bytes. + *
+ * + * @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(Resource r1, 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()) { + 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(Resource r1, 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) { + String actual = in2.readLine(); + if (!expected.equals(actual)) { + 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 long the timestamp granularity to use. + * @since Ant 1.7 + */ private static void logFuture(ProjectComponent logTo, ResourceCollection rc, long granularity) { long now = System.currentTimeMillis() + granularity; diff --git a/src/testcases/org/apache/tools/ant/types/ResourceOutputTest.java b/src/testcases/org/apache/tools/ant/types/ResourceOutputTest.java index 9ac58c30f..4c20b5121 100755 --- a/src/testcases/org/apache/tools/ant/types/ResourceOutputTest.java +++ b/src/testcases/org/apache/tools/ant/types/ResourceOutputTest.java @@ -34,6 +34,7 @@ import org.apache.tools.ant.types.resources.StringResource; import org.apache.tools.ant.types.resources.PropertyResource; import org.apache.tools.ant.types.resources.ImmutableResourceException; import org.apache.tools.ant.util.FileUtils; +import org.apache.tools.ant.util.ResourceUtils; public class ResourceOutputTest extends BuildFileTest { @@ -147,7 +148,7 @@ public class ResourceOutputTest extends BuildFileTest { } private void testoutput(Resource dest) throws IOException { - FILE_UTILS.copyResource(new StringResource("foo"), dest, null); + ResourceUtils.copyResource(new StringResource("foo"), dest, null); } }