diff --git a/src/main/org/apache/tools/ant/Project.java b/src/main/org/apache/tools/ant/Project.java index 4841bdd91..d84cc2560 100644 --- a/src/main/org/apache/tools/ant/Project.java +++ b/src/main/org/apache/tools/ant/Project.java @@ -107,6 +107,9 @@ public class Project { private Vector listeners = new Vector(); + private static java.lang.reflect.Method setLastModified = null; + private static Object lockReflection = new Object(); + static { // Determine the Java version by looking at available classes @@ -672,6 +675,22 @@ public class Project { overwrite); } + /** + * Convienence 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 destFile file should be made equal + * to the last modified time of sourceFile. + * + * @throws IOException + */ + public void copyFile(String sourceFile, String destFile, boolean filtering, + boolean overwrite, boolean preserveLastModified) + throws IOException { + copyFile(new File(sourceFile), new File(destFile), filtering, + overwrite, preserveLastModified); + } + /** * Convienence method to copy a file from a source to a destination. * No filtering is performed. @@ -689,8 +708,7 @@ public class Project { * @throws IOException */ public void copyFile(File sourceFile, File destFile, boolean filtering) - throws IOException - { + throws IOException { copyFile(sourceFile, destFile, filtering, false); } @@ -703,7 +721,22 @@ public class Project { */ public void copyFile(File sourceFile, File destFile, boolean filtering, boolean overwrite) throws IOException { + copyFile(sourceFile, destFile, filtering, overwrite, false); + } + /** + * Convienence 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 destFile file should be made equal + * to the last modified time of sourceFile. + * + * @throws IOException + */ + public void copyFile(File sourceFile, File destFile, boolean filtering, + boolean overwrite, boolean preserveLastModified) + throws IOException { + if (overwrite || destFile.lastModified() < sourceFile.lastModified()) { log("Copy: " + sourceFile.getAbsolutePath() + " > " @@ -750,6 +783,52 @@ public class Project { in.close(); out.close(); } + + if (preserveLastModified) { + setFileLastModified(destFile, sourceFile.lastModified()); + } + } + } + + /** + * Calls File.setLastModified(long time) in a Java 1.1 compatible way. + */ + void setFileLastModified(File file, long time) throws BuildException { + if (getJavaVersion() == JAVA_1_1) { + log("Cannot change the modification time of " + file + + " in JDK 1.1", Project.MSG_WARN); + return; + } + if (setLastModified == null) { + synchronized (lockReflection) { + if (setLastModified == null) { + try { + setLastModified = + java.io.File.class.getMethod("setLastModified", + new Class[] {Long.TYPE}); + } catch (NoSuchMethodException nse) { + throw new BuildException("File.setlastModified not in JDK > 1.1?", + nse); + } + } + } + } + Long[] times = new Long[1]; + if (time < 0) { + times[0] = new Long(System.currentTimeMillis()); + } else { + times[0] = new Long(time); + } + try { + log("Setting modification time for " + file, MSG_VERBOSE); + setLastModified.invoke(file, times); + } catch (java.lang.reflect.InvocationTargetException ite) { + Throwable nested = ite.getTargetException(); + throw new BuildException("Exception setting the modification time " + + "of " + file, nested); + } catch (Throwable other) { + throw new BuildException("Exception setting the modification time " + + "of " + file, other); } } diff --git a/src/main/org/apache/tools/ant/taskdefs/Copy.java b/src/main/org/apache/tools/ant/taskdefs/Copy.java index 951a49d88..8c1f17c87 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Copy.java +++ b/src/main/org/apache/tools/ant/taskdefs/Copy.java @@ -81,6 +81,7 @@ public class Copy extends Task { protected Vector filesets = new Vector(); protected boolean filtering = false; + protected boolean preserveLastModified = false; protected boolean forceOverwrite = false; protected boolean flatten = false; protected int verbosity = Project.MSG_VERBOSE; @@ -112,6 +113,13 @@ public class Copy extends Task { this.destDir = destDir; } + /** + * Give the copied files the same last modified time as the original files. + */ + public void setPreserveLastModified(String preserve) { + preserveLastModified = Project.toBoolean(preserve); + } + /** * Sets filtering. */ @@ -327,7 +335,8 @@ public class Copy extends Task { project.copyFile(fromFile, toFile, filtering, - forceOverwrite); + forceOverwrite, + preserveLastModified); } catch (IOException ioe) { String msg = "Failed to copy " + fromFile + " to " + toFile + " due to " + ioe.getMessage();