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 <[email protected]>
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());
}