git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@805265 13f79535-47bb-0310-9956-ffa450edef68master
@@ -836,6 +836,9 @@ Other changes: | |||
arbitrary JDBC connection properties. | |||
Bugzilla Report 33452. | |||
* A new islastmodified condition can check the last modified date of | |||
resources. | |||
Changes from Ant 1.7.0 TO Ant 1.7.1 | |||
============================================= | |||
@@ -1007,5 +1007,55 @@ is redundant and will be ignored.</p> | |||
<blockquote><pre> | |||
<hasfreespace partition="c:" needed="100M"/> | |||
</pre></blockquote> | |||
<h4>islastmodified</h4> | |||
<p>Tests the last modified date of a resource. <em>Since Ant | |||
1.8.0</em></p> | |||
<table border="1" cellpadding="2" cellspacing="0"> | |||
<tr> | |||
<td width="12%" valign="top"><b>Attribute</b></td> | |||
<td width="78%" valign="top"><b>Description</b></td> | |||
<td width="10%" valign="top"><b>Required</b></td> | |||
</tr> | |||
<tr> | |||
<td valign="top">millis</td> | |||
<td valign="top">Specifies the expected modification time of the resource | |||
in milliseconds since midnight Jan 1 1970.</td> | |||
<td valign="center" align="center" rowspan="2">Exactly one of the | |||
two.</td> | |||
</tr> | |||
<tr> | |||
<td valign="top">datetime</td> | |||
<td valign="top">Specifies the expected modification time of the | |||
resource. The special value "now" indicates the | |||
current time.</td> | |||
</tr> | |||
<tr> | |||
<td valign="top">pattern</td> | |||
<td valign="top">SimpleDateFormat-compatible pattern string. | |||
Defaults to MM/DD/YYYY HH:MM AM_or_PM or MM/DD/YYYY HH:MM:SS AM_or_PM. | |||
</td> | |||
<td valign="top" align="center">No</td> | |||
</tr> | |||
<tr> | |||
<td valign="top">mode</td> | |||
<td valign="top">How to compare the timestamp. Accepted values | |||
are "equals", "before", "not-before", "after" and "not-after". | |||
<td valign="top">No, defaults to "equals".</td> | |||
</tr> | |||
</table> | |||
<p>The actual resource to test is specified as a nested element.</p> | |||
<p> | |||
An example: | |||
</p> | |||
<blockquote><pre> | |||
<islastmodified dateTime="08/18/2009 04:41:19 AM" mode="not-before"> | |||
<file file="${file}"/> | |||
</islastmodified> | |||
</pre></blockquote> | |||
</body> | |||
</html> |
@@ -54,12 +54,12 @@ import org.apache.tools.ant.util.FileNameMapper; | |||
*/ | |||
public class Touch extends Task { | |||
private interface DateFormatFactory { | |||
public interface DateFormatFactory { | |||
DateFormat getPrimaryFormat(); | |||
DateFormat getFallbackFormat(); | |||
} | |||
private static final DateFormatFactory DEFAULT_DF_FACTORY | |||
public static final DateFormatFactory DEFAULT_DF_FACTORY | |||
= new DateFormatFactory() { | |||
/* | |||
* The initial version used DateFormat.SHORT for the | |||
@@ -0,0 +1,193 @@ | |||
/* | |||
* 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.taskdefs.condition; | |||
import java.text.DateFormat; | |||
import java.text.ParseException; | |||
import java.text.SimpleDateFormat; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.ProjectComponent; | |||
import org.apache.tools.ant.taskdefs.Touch; | |||
import org.apache.tools.ant.types.EnumeratedAttribute; | |||
import org.apache.tools.ant.types.Resource; | |||
/** | |||
* Condition that makes assertions about the last modified date of a | |||
* resource. | |||
* | |||
* @since Ant 1.8.0 | |||
*/ | |||
public class IsLastModified extends ProjectComponent implements Condition { | |||
private long millis = -1; | |||
private String dateTime = null; | |||
private Touch.DateFormatFactory dfFactory = Touch.DEFAULT_DF_FACTORY; | |||
private Resource resource; | |||
private CompareMode mode = CompareMode.EQUALS; | |||
/** | |||
* Set the new modification time of file(s) touched | |||
* in milliseconds since midnight Jan 1 1970. | |||
* @param millis the <code>long</code> timestamp to use. | |||
*/ | |||
public void setMillis(long millis) { | |||
this.millis = millis; | |||
} | |||
/** | |||
* Set the new modification time of file(s) touched | |||
* in the format "MM/DD/YYYY HH:MM AM <i>or</i> PM" | |||
* or "MM/DD/YYYY HH:MM:SS AM <i>or</i> PM". | |||
* @param dateTime the <code>String</code> date in the specified format. | |||
*/ | |||
public void setDatetime(String dateTime) { | |||
this.dateTime = dateTime; | |||
} | |||
/** | |||
* Set the format of the datetime attribute. | |||
* @param pattern the <code>SimpleDateFormat</code>-compatible | |||
* format pattern. | |||
*/ | |||
public void setPattern(final String pattern) { | |||
dfFactory = new Touch.DateFormatFactory() { | |||
public DateFormat getPrimaryFormat() { | |||
return new SimpleDateFormat(pattern); | |||
} | |||
public DateFormat getFallbackFormat() { | |||
return null; | |||
} | |||
}; | |||
} | |||
/** | |||
* The resource to test. | |||
*/ | |||
public void add(Resource r) { | |||
if (resource != null) { | |||
throw new BuildException("only one resource can be tested"); | |||
} | |||
resource = r; | |||
} | |||
/** | |||
* The type of comparison to test. | |||
*/ | |||
public void setMode(CompareMode mode) { | |||
this.mode = mode; | |||
} | |||
/** | |||
* Argument validation. | |||
*/ | |||
protected void validate() throws BuildException { | |||
if (millis >= 0 && dateTime != null) { | |||
throw new BuildException("Only one of dateTime and millis can be" | |||
+ " set"); | |||
} | |||
if (millis < 0 && dateTime == null) { | |||
throw new BuildException("millis or dateTime is required"); | |||
} | |||
if (resource == null) { | |||
throw new BuildException("resource is required"); | |||
} | |||
} | |||
/** | |||
* Calculate timestamp as millis either based on millis or | |||
* dateTime (and pattern) attribute. | |||
*/ | |||
protected long getMillis() throws BuildException { | |||
if (millis >= 0) { | |||
return millis; | |||
} | |||
if ("now".equalsIgnoreCase(dateTime)) { | |||
return System.currentTimeMillis(); | |||
} | |||
DateFormat df = dfFactory.getPrimaryFormat(); | |||
ParseException pe = null; | |||
try { | |||
return df.parse(dateTime).getTime(); | |||
} catch (ParseException peOne) { | |||
df = dfFactory.getFallbackFormat(); | |||
if (df == null) { | |||
pe = peOne; | |||
} else { | |||
try { | |||
return df.parse(dateTime).getTime(); | |||
} catch (ParseException peTwo) { | |||
pe = peTwo; | |||
} | |||
} | |||
} | |||
if (pe != null) { | |||
throw new BuildException(pe.getMessage(), pe, getLocation()); | |||
} | |||
/* NOTREACHED */ | |||
return 0; | |||
} | |||
public boolean eval() throws BuildException { | |||
validate(); | |||
long expected = getMillis(); | |||
long actual = resource.getLastModified(); | |||
if (CompareMode.EQUALS_TEXT.equals(mode.getValue())) { | |||
return expected == actual; | |||
} | |||
if (CompareMode.BEFORE_TEXT.equals(mode.getValue())) { | |||
return expected > actual; | |||
} | |||
if (CompareMode.NOT_BEFORE_TEXT.equals(mode.getValue())) { | |||
return expected <= actual; | |||
} | |||
if (CompareMode.AFTER_TEXT.equals(mode.getValue())) { | |||
return expected < actual; | |||
} | |||
if (CompareMode.NOT_AFTER_TEXT.equals(mode.getValue())) { | |||
return expected >= actual; | |||
} | |||
throw new BuildException("Unknown mode " + mode.getValue()); | |||
} | |||
public static class CompareMode extends EnumeratedAttribute { | |||
private static final String EQUALS_TEXT = "equals"; | |||
private static final String BEFORE_TEXT = "before"; | |||
private static final String AFTER_TEXT = "after"; | |||
private static final String NOT_BEFORE_TEXT = "not-before"; | |||
private static final String NOT_AFTER_TEXT = "not-after"; | |||
private static final CompareMode EQUALS = new CompareMode(EQUALS_TEXT); | |||
public CompareMode() { | |||
this(EQUALS_TEXT); | |||
} | |||
public CompareMode(String s) { | |||
super(); | |||
setValue(s); | |||
} | |||
public String[] getValues() { | |||
return new String[] { | |||
EQUALS_TEXT, BEFORE_TEXT, AFTER_TEXT, NOT_BEFORE_TEXT, | |||
NOT_AFTER_TEXT, | |||
}; | |||
} | |||
} | |||
} |
@@ -21,7 +21,7 @@ | |||
--> | |||
<!-- Ant 1.6+ antlib declaration for conditions: | |||
Use with the declaration xmlns:cond="antlib:org.apache.tools.ant.condition" | |||
Use with the declaration xmlns:cond="antlib:org.apache.tools.ant.types.conditions" | |||
to | |||
trigger Ant's autoload of this file into namespace 'cond' (or whatever name | |||
suits). | |||
@@ -54,6 +54,8 @@ | |||
classname="org.apache.tools.ant.taskdefs.condition.IsFalse"/> | |||
<typedef name="isfileselected" onerror="ignore" | |||
classname="org.apache.tools.ant.taskdefs.condition.IsFileSelected"/> | |||
<typedef name="islastmodified" onerror="ignore" | |||
classname="org.apache.tools.ant.taskdefs.condition.IsLastModified"/> | |||
<typedef name="isreachable" onerror="ignore" | |||
classname="org.apache.tools.ant.taskdefs.condition.IsReachable"/> | |||
<typedef name="isreference" onerror="ignore" | |||
@@ -86,4 +88,4 @@ | |||
classname="org.apache.tools.ant.taskdefs.condition.TypeFound"/> | |||
<typedef name="xor" onerror="ignore" | |||
classname="org.apache.tools.ant.taskdefs.condition.Xor"/> | |||
</antlib> | |||
</antlib> |
@@ -0,0 +1,118 @@ | |||
<?xml version="1.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. | |||
--> | |||
<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit" | |||
xmlns:cond="antlib:org.apache.tools.ant.types.conditions"> | |||
<import file="../../antunit-base.xml"/> | |||
<target name="setUp"> | |||
<mkdir dir="${output}"/> | |||
<property name="file" location="${output}/test.txt"/> | |||
<touch file="${file}" dateTime="08/18/2009 04:41:20 AM"/> | |||
</target> | |||
<target name="testEquals" depends="setUp"> | |||
<au:assertFalse> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:19 AM"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertFalse> | |||
<au:assertTrue> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:20 AM"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertTrue> | |||
<au:assertFalse> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:21 AM"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertFalse> | |||
</target> | |||
<target name="testBefore" depends="setUp"> | |||
<au:assertFalse> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:19 AM" mode="before"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertFalse> | |||
<au:assertFalse> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:20 AM" mode="before"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertFalse> | |||
<au:assertTrue> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:21 AM" mode="before"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertTrue> | |||
</target> | |||
<target name="testAfter" depends="setUp"> | |||
<au:assertTrue> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:19 AM" mode="after"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertTrue> | |||
<au:assertFalse> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:20 AM" mode="after"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertFalse> | |||
<au:assertFalse> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:21 AM" mode="after"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertFalse> | |||
</target> | |||
<target name="testNotBefore" depends="setUp"> | |||
<au:assertTrue> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:19 AM" mode="not-before"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertTrue> | |||
<au:assertTrue> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:20 AM" mode="not-before"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertTrue> | |||
<au:assertFalse> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:21 AM" mode="not-before"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertFalse> | |||
</target> | |||
<target name="testNotAfter" depends="setUp"> | |||
<au:assertFalse> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:19 AM" mode="not-after"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertFalse> | |||
<au:assertTrue> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:20 AM" mode="not-after"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertTrue> | |||
<au:assertTrue> | |||
<cond:islastmodified dateTime="08/18/2009 04:41:21 AM" mode="not-after"> | |||
<file file="${file}"/> | |||
</cond:islastmodified> | |||
</au:assertTrue> | |||
</target> | |||
</project> |