This is an automated email from the ASF dual-hosted git repository. bodewig pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ant.git
The following commit(s) were added to refs/heads/master by this push: new dc3d7ed34 make xslt use similar out-of-dateness check as other tasks dc3d7ed34 is described below commit dc3d7ed34cd506a5b853af5f6dee25ec9ff8a094 Author: Stefan Bodewig <bode...@apache.org> AuthorDate: Thu Jun 5 20:57:04 2025 +0200 make xslt use similar out-of-dateness check as other tasks https://bz.apache.org/bugzilla/show_bug.cgi?id=65756 --- WHATSNEW | 17 +++++++++ manual/Tasks/style.html | 9 +++++ src/etc/testcases/taskdefs/style/build.xml | 2 +- .../org/apache/tools/ant/taskdefs/XSLTProcess.java | 41 ++++++++++++++++------ .../tools/ant/types/selectors/SelectorUtils.java | 21 ++++++++++- 5 files changed, 78 insertions(+), 12 deletions(-) diff --git a/WHATSNEW b/WHATSNEW index 5095303da..a512e2f62 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -1,6 +1,23 @@ Changes from Ant 1.10.15 TO Ant 1.10.16 ======================================= +Changes that could break older environments: +------------------------------------------- + + * <xslt> now uses the same logic to compare file timestamps when + determining whether a target file is out-of-date with respect to + the source file or stylesheet that most other tasks use. This means + it will assume a default timestamp granularity that depends on the + current operating system. + A new granularity attribute allows you to override the assumed + granularity. + Under certain edge cases this means xslt will now not process files + it would have processed before (when the timestamps of source or + stylesheet are very close or even equal to the timestamp of the + target). In this case you can set granularity to 0 to get back to + the behavior of 1.10.15. + Bugzilla Report 65756 + Fixed bugs: ----------- diff --git a/manual/Tasks/style.html b/manual/Tasks/style.html index 9f0a16c68..6ce33f8c9 100644 --- a/manual/Tasks/style.html +++ b/manual/Tasks/style.html @@ -231,6 +231,15 @@ <h3>Parameters</h3> 1.8.0</em>.</td> <td>No; default is <q>true</q></td> </tr> + <tr> + <td>granularity</td> + <td>The number of milliseconds leeway to give before deciding a + file is out of date with respect of the source file or stylesheet. This is + needed because not every file system supports tracking the last modified time to the + millisecond level. This can also be useful if source and target files live on separate + machines with clocks being out of sync. <em>since Ant 1.10.16</em>.</td> + <td>No; default is 1 second, or 2 seconds on DOS systems</td> + </tr> </table> <h3>Parameters specified as nested elements</h3> diff --git a/src/etc/testcases/taskdefs/style/build.xml b/src/etc/testcases/taskdefs/style/build.xml index 42ad93d92..959e61646 100644 --- a/src/etc/testcases/taskdefs/style/build.xml +++ b/src/etc/testcases/taskdefs/style/build.xml @@ -96,7 +96,7 @@ <antcall target="copyXsl"> <param name="xsl.value" value="new-value"/> </antcall> - <xslt in="data.xml" out="${output}/out.xml" style="tmp.xsl"/> + <xslt in="data.xml" out="${output}/out.xml" style="tmp.xsl" granularity="0"/> <delete file="tmp.xsl"/> </target> diff --git a/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java b/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java index 829ab0006..bdb6bb08d 100644 --- a/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java +++ b/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java @@ -55,6 +55,7 @@ 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.Union; +import org.apache.tools.ant.types.selectors.SelectorUtils; import org.apache.tools.ant.util.ClasspathUtils; import org.apache.tools.ant.util.FileNameMapper; import org.apache.tools.ant.util.FileUtils; @@ -243,6 +244,13 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { */ private TraceConfiguration traceConfiguration; + /** + * Filesystem timestamp granularity in milliseconds. + * + * @since Ant 1.10.16 + */ + private long granularity = FILE_UTILS.getFileTimestampGranularity(); + /** * Whether to style all files in the included directories as well; * optional, default is true. @@ -390,9 +398,7 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { stylesheet = alternative; } } - final FileResource fr = new FileResource(); - fr.setProject(getProject()); - fr.setFile(stylesheet); + final FileResource fr = new FileResource(getProject(), stylesheet); styleResource = fr; } else { styleResource = xslResource; @@ -692,6 +698,19 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { return traceConfiguration; } + /** + * Set the number of milliseconds leeway to give before deciding a + * target is out of date. + * + * <p>Default is 1 second, or 2 seconds on DOS systems.</p> + * @param granularity the granularity used to decide if a target is out of + * date. + * @since Ant 1.10.16 + */ + public void setGranularity(final long granularity) { + this.granularity = granularity; + } + /** * Load processor here instead of in setProcessor - this will be * called from within execute, so we have access to the latest @@ -830,9 +849,11 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { return; } outF = new File(destDir, outFileName[0]); + Resource outR = new FileResource(getProject(), outF); - if (force || inF.lastModified() > outF.lastModified() - || styleSheetLastModified > outF.lastModified()) { + if (force + || SelectorUtils.isOutOfDate(inF, outF, granularity) + || SelectorUtils.isOutOfDate(stylesheet, outR, granularity)) { ensureDirectoryFor(outF); log("Processing " + inF + " to " + outF); configureLiaison(stylesheet); @@ -862,11 +883,13 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { private void process(final File inFile, final File outFile, final Resource stylesheet) throws BuildException { try { final long styleSheetLastModified = stylesheet.getLastModified(); + final Resource outResource = new FileResource(getProject(), outFile); log("In file " + inFile + " time: " + inFile.lastModified(), Project.MSG_DEBUG); log("Out file " + outFile + " time: " + outFile.lastModified(), Project.MSG_DEBUG); log("Style file " + xslFile + " time: " + styleSheetLastModified, Project.MSG_DEBUG); - if (force || inFile.lastModified() >= outFile.lastModified() - || styleSheetLastModified >= outFile.lastModified()) { + if (force + || SelectorUtils.isOutOfDate(inFile, outFile, granularity) + || SelectorUtils.isOutOfDate(stylesheet, outResource, granularity)) { ensureDirectoryFor(outFile); log("Processing " + inFile + " to " + outFile, Project.MSG_INFO); configureLiaison(stylesheet); @@ -1242,9 +1265,7 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { */ @Deprecated protected void configureLiaison(final File stylesheet) throws BuildException { - final FileResource fr = new FileResource(); - fr.setProject(getProject()); - fr.setFile(stylesheet); + final FileResource fr = new FileResource(getProject(), stylesheet); configureLiaison(fr); } diff --git a/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java b/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java index a6af9bcd8..af0f4afcc 100644 --- a/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java +++ b/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java @@ -573,11 +573,30 @@ public final class SelectorUtils { * * @param src the original file * @param target the file being compared against - * @param granularity the amount in milliseconds of slack we will give in + * @param granularity the int amount in milliseconds of slack we will give in * determining out of dateness * @return whether the target is out of date */ public static boolean isOutOfDate(File src, File target, int granularity) { + return isOutOfDate(src, target, (long) granularity); + } + + /** + * Returns dependency information on these two files. If src has been + * modified later than target, it returns true. If target doesn't exist, + * it likewise returns true. Otherwise, target is newer than src and + * is not out of date, thus the method returns false. It also returns + * false if the src file doesn't even exist, since how could the + * target then be out of date. + * + * @param src the original file + * @param target the file being compared against + * @param granularity the amount in milliseconds of slack we will give in + * determining out of dateness + * @return whether the target is out of date + * @since Ant 1.10.16 + */ + public static boolean isOutOfDate(File src, File target, long granularity) { return src.exists() && (!target.exists() || (src.lastModified() - granularity) > target.lastModified()); }