@@ -39,6 +39,7 @@ import org.apache.tools.ant.types.resources.FileProvider; | |||
import org.apache.tools.ant.types.resources.FileResource; | |||
import org.apache.tools.ant.types.resources.Touchable; | |||
import org.apache.tools.ant.types.resources.Union; | |||
import org.apache.tools.ant.util.DateUtils; | |||
import org.apache.tools.ant.util.FileNameMapper; | |||
import org.apache.tools.ant.util.FileUtils; | |||
@@ -59,31 +60,18 @@ public class Touch extends Task { | |||
DateFormat getFallbackFormat(); | |||
} | |||
/** | |||
* Provides access to DateUtils.EN_US_DATE_FORMAT_MIN (primary) and | |||
* DateUtils.EN_US_DATE_FORMAT_SEC (fallback). | |||
*/ | |||
public static final DateFormatFactory DEFAULT_DF_FACTORY | |||
= new DateFormatFactory() { | |||
private ThreadLocal<DateFormat> primary = | |||
new ThreadLocal<DateFormat>() { | |||
@Override | |||
protected DateFormat initialValue() { | |||
return new SimpleDateFormat("MM/dd/yyyy hh:mm a", | |||
Locale.US); | |||
} | |||
}; | |||
private ThreadLocal<DateFormat> fallback = | |||
new ThreadLocal<DateFormat>() { | |||
@Override | |||
protected DateFormat initialValue() { | |||
return new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a", | |||
Locale.US); | |||
} | |||
}; | |||
public DateFormat getPrimaryFormat() { | |||
return primary.get(); | |||
return DateUtils.EN_US_DATE_FORMAT_MIN.get(); | |||
} | |||
public DateFormat getFallbackFormat() { | |||
return fallback.get(); | |||
return DateUtils.EN_US_DATE_FORMAT_SEC.get(); | |||
} | |||
}; | |||
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | |||
@@ -29,8 +29,6 @@ import java.util.TimeZone; | |||
import java.util.regex.Matcher; | |||
import java.util.regex.Pattern; | |||
import org.apache.tools.ant.taskdefs.Touch; | |||
/** | |||
* Helper methods to deal with date/time formatting with a specific | |||
* defined format (<a href="http://www.w3.org/TR/NOTE-datetime">ISO8601</a>) | |||
@@ -93,6 +91,32 @@ public final class DateUtils { | |||
private static final ChoiceFormat SECONDS_FORMAT = | |||
new ChoiceFormat(LIMITS, SECONDS_PART); | |||
/** | |||
* Provides a thread-local US-style date format. Exactly as used by | |||
* {@code <touch>}, to minute precision: | |||
* {@code SimpleDateFormat("MM/dd/yyyy hh:mm a", Locale.US)} | |||
*/ | |||
public static final ThreadLocal<DateFormat> EN_US_DATE_FORMAT_MIN = | |||
new ThreadLocal<DateFormat>() { | |||
@Override | |||
protected DateFormat initialValue() { | |||
return new SimpleDateFormat("MM/dd/yyyy hh:mm a", Locale.US); | |||
} | |||
}; | |||
/** | |||
* Provides a thread-local US-style date format. Exactly as used by | |||
* {@code <touch>}, to second precision: | |||
* {@code SimpleDateFormat("MM/dd/yyyy hh:mm:ss a", Locale.US)} | |||
*/ | |||
public static final ThreadLocal<DateFormat> EN_US_DATE_FORMAT_SEC = | |||
new ThreadLocal<DateFormat>() { | |||
@Override | |||
protected DateFormat initialValue() { | |||
return new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a", Locale.US); | |||
} | |||
}; | |||
static { | |||
MINUTE_SECONDS.setFormat(0, MINUTES_FORMAT); | |||
MINUTE_SECONDS.setFormat(1, SECONDS_FORMAT); | |||
@@ -332,11 +356,11 @@ public final class DateUtils { | |||
} catch (NumberFormatException nfe) {} | |||
try { | |||
return Touch.DEFAULT_DF_FACTORY.getPrimaryFormat().parse(dateStr); | |||
return EN_US_DATE_FORMAT_MIN.get().parse(dateStr); | |||
} catch (ParseException pe) {} | |||
try { | |||
return Touch.DEFAULT_DF_FACTORY.getFallbackFormat().parse(dateStr); | |||
return EN_US_DATE_FORMAT_SEC.get().parse(dateStr); | |||
} catch (ParseException pe) {} | |||
Matcher m = iso8601normalizer.matcher(dateStr); | |||
@@ -182,4 +182,24 @@ | |||
<fileset dir="${basedir}" includes="zip-test.xml"/> | |||
</zip> | |||
</target> | |||
<target name="testSetZipModTime"> | |||
<mkdir dir="${input}/"/> | |||
<touch file="${input}/test1.txt"/> | |||
<mkdir dir="${output}"/> | |||
<zip destfile="${output}/test.zip" basedir="${input}" modificationtime="2016-01-01 00:00"> | |||
<fileset dir="${input}"/> | |||
</zip> | |||
<checksum file="${output}/test.zip" property="testSetZipModTime_hash" /> | |||
<delete file="${output}/test.zip" /> | |||
<touch file="${input}/test1.txt"/> | |||
<zip destfile="${output}/test.zip" basedir="${input}" modificationtime="2016-01-01 00:00"> | |||
<fileset dir="${input}"/> | |||
</zip> | |||
<checksum file="${output}/test.zip" property="testSetZipModTime_hash" verifyproperty="testSetZipModTime_okay" /> | |||
<au:assertTrue> | |||
<equals arg1="${testSetZipModTime_okay}" arg2="true" /> | |||
</au:assertTrue> | |||
</target> | |||
</project> |