diff --git a/src/etc/testcases/taskdefs/checksum.xml b/src/etc/testcases/taskdefs/checksum.xml index 8879c1d45..0c1119db1 100644 --- a/src/etc/testcases/taskdefs/checksum.xml +++ b/src/etc/testcases/taskdefs/checksum.xml @@ -4,7 +4,11 @@ - + + + + + @@ -16,6 +20,18 @@ + + + + + + + + + + + + @@ -31,6 +47,17 @@ verifyproperty="no.logo.MD5" /> + + + + + + + + diff --git a/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5 b/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5 index 5c886a5f5..b56119bec 100644 --- a/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5 +++ b/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5 @@ -1 +1 @@ -0541d3df42520911f268abc730f3afe0 \ No newline at end of file +0541d3df42520911f268abc730f3afe0 diff --git a/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5sum b/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5sum new file mode 100644 index 000000000..56c49d331 --- /dev/null +++ b/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5sum @@ -0,0 +1 @@ +0541d3df42520911f268abc730f3afe0 *asf-logo.gif diff --git a/src/etc/testcases/taskdefs/expected/asf-logo.gif.pattern b/src/etc/testcases/taskdefs/expected/asf-logo.gif.pattern new file mode 100644 index 000000000..3a6eb82f7 --- /dev/null +++ b/src/etc/testcases/taskdefs/expected/asf-logo.gif.pattern @@ -0,0 +1 @@ +foo0541d3df42520911f268abc730f3afe0bar diff --git a/src/etc/testcases/taskdefs/expected/asf-logo.gif.svf b/src/etc/testcases/taskdefs/expected/asf-logo.gif.svf new file mode 100644 index 000000000..c7f8ec231 --- /dev/null +++ b/src/etc/testcases/taskdefs/expected/asf-logo.gif.svf @@ -0,0 +1 @@ +MD5 (asf-logo.gif) = 0541d3df42520911f268abc730f3afe0 diff --git a/src/main/org/apache/tools/ant/taskdefs/Checksum.java b/src/main/org/apache/tools/ant/taskdefs/Checksum.java index 0e9db105d..da7fa6c98 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Checksum.java +++ b/src/main/org/apache/tools/ant/taskdefs/Checksum.java @@ -34,12 +34,16 @@ import java.util.Hashtable; import java.util.Enumeration; import java.util.Set; import java.util.Arrays; +import java.text.MessageFormat; +import java.text.ParseException; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.condition.Condition; +import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.util.StringUtils; /** * Used to create or verify file checksums. @@ -126,6 +130,11 @@ public class Checksum extends MatchingTask implements Condition { */ private int readBufferSize = 8 * 1024; + /** + * Formater for the checksum file. + */ + private MessageFormat format = FormatElement.getDefault().getFormat(); + /** * Sets the file for which the checksum is to be calculated. */ @@ -208,6 +217,26 @@ public class Checksum extends MatchingTask implements Condition { this.readBufferSize = size; } + /** + * Select the in/output pattern via a well know format name. + * + * @since 1.7.0 + */ + public void setFormat(FormatElement e) { + format = e.getFormat(); + } + + /** + * Specify the pattern to use as a MessageFormat pattern. + * + *

{0} gets replaced by the checksum, {1} by the filename.

+ * + * @since 1.7.0 + */ + public void setPattern(String p) { + format = new MessageFormat(p); + } + /** * Files to generate checksums for. */ @@ -223,7 +252,7 @@ public class Checksum extends MatchingTask implements Condition { boolean value = validateAndExecute(); if (verifyProperty != null) { getProject().setNewProperty(verifyProperty, - new Boolean(value).toString()); + new Boolean(value).toString()); } } @@ -246,39 +275,39 @@ public class Checksum extends MatchingTask implements Condition { if (file == null && filesets.size() == 0) { throw new BuildException( - "Specify at least one source - a file or a fileset."); + "Specify at least one source - a file or a fileset."); } if (file != null && file.exists() && file.isDirectory()) { throw new BuildException( - "Checksum cannot be generated for directories"); + "Checksum cannot be generated for directories"); } if (file != null && totalproperty != null) { throw new BuildException( - "File and Totalproperty cannot co-exist."); + "File and Totalproperty cannot co-exist."); } if (property != null && fileext != null) { throw new BuildException( - "Property and FileExt cannot co-exist."); + "Property and FileExt cannot co-exist."); } if (property != null) { if (forceOverwrite) { throw new BuildException( - "ForceOverwrite cannot be used when Property is specified"); + "ForceOverwrite cannot be used when Property is specified"); } if (file != null) { if (filesets.size() > 0) { throw new BuildException("Multiple files cannot be used " - + "when Property is specified"); + + "when Property is specified"); } } else { if (filesets.size() > 1) { throw new BuildException("Multiple files cannot be used " - + "when Property is specified"); + + "when Property is specified"); } } } @@ -289,12 +318,12 @@ public class Checksum extends MatchingTask implements Condition { if (verifyProperty != null && forceOverwrite) { throw new BuildException( - "VerifyProperty and ForceOverwrite cannot co-exist."); + "VerifyProperty and ForceOverwrite cannot co-exist."); } if (isCondition && forceOverwrite) { throw new BuildException("ForceOverwrite cannot be used when " - + "conditions are being used."); + + "conditions are being used."); } messageDigest = null; @@ -323,7 +352,7 @@ public class Checksum extends MatchingTask implements Condition { fileext = "." + algorithm; } else if (fileext.trim().length() == 0) { throw new BuildException( - "File extension when specified must not be an empty string"); + "File extension when specified must not be an empty string"); } try { @@ -371,15 +400,7 @@ public class Checksum extends MatchingTask implements Condition { Project.MSG_VERBOSE); if (totalproperty != null) { // Read the checksum from disk. - String checksum = null; - try { - BufferedReader diskChecksumReader - = new BufferedReader(new FileReader(checksumFile)); - checksum = diskChecksumReader.readLine(); - } catch (IOException e) { - throw new BuildException("Couldn't read checksum file " - + checksumFile, e); - } + String checksum = readChecksum(checksumFile); byte[] digest = decodeHex(checksum.toCharArray()); allDigests.put(file, digest); } @@ -389,8 +410,8 @@ public class Checksum extends MatchingTask implements Condition { } } else { String message = "Could not find file " - + file.getAbsolutePath() - + " to generate checksum for."; + + file.getAbsolutePath() + + " to generate checksum for."; log(message); throw new BuildException(message, getLocation()); } @@ -457,23 +478,26 @@ public class Checksum extends MatchingTask implements Condition { if (isCondition) { File existingFile = (File) destination; if (existingFile.exists()) { - fis = new FileInputStream(existingFile); - InputStreamReader isr = new InputStreamReader(fis); - BufferedReader br = new BufferedReader(isr); - String suppliedChecksum = br.readLine(); - fis.close(); - fis = null; - br.close(); - isr.close(); - checksumMatches = checksumMatches - && checksum.equals(suppliedChecksum); + try { + String suppliedChecksum = + readChecksum(existingFile); + checksumMatches = checksumMatches + && checksum.equals(suppliedChecksum); + } catch (BuildException be) { + // file is on wrong format, swallow + checksumMatches = false; + } } else { checksumMatches = false; } } else { File dest = (File) destination; fos = new FileOutputStream(dest); - fos.write(checksum.getBytes()); + fos.write(format.format(new Object[] { + checksum, + src.getName(), + }).getBytes()); + fos.write(StringUtils.LINE_SEP.getBytes()); fos.close(); fos = null; } @@ -562,4 +586,69 @@ public class Checksum extends MatchingTask implements Condition { return out; } + + /** + * reads the checksum from a file using the specified format. + * + * @since 1.7 + */ + private String readChecksum(File f) { + BufferedReader diskChecksumReader = null; + try { + diskChecksumReader = new BufferedReader(new FileReader(f)); + Object[] result = format.parse(diskChecksumReader.readLine()); + if (result == null || result.length == 0 || result[0] == null) { + throw new BuildException("failed to find a checksum"); + } + return (String) result[0]; + } catch (IOException e) { + throw new BuildException("Couldn't read checksum file " + f, e); + } catch (ParseException e) { + throw new BuildException("Couldn't read checksum file " + f, e); + } finally { + if (diskChecksumReader != null) { + try { + diskChecksumReader.close(); + } catch (IOException e) { + // ignore + } + } + } + } + + /** + * Helper class for the format attribute. + * + * @since 1.7 + */ + public static class FormatElement extends EnumeratedAttribute { + private static HashMap formatMap = new HashMap(); + private static final String CHECKSUM = "CHECKSUM"; + private static final String MD5SUM = "MD5SUM"; + private static final String SVF = "SVF"; + + static { + formatMap.put(CHECKSUM, new MessageFormat("{0}")); + formatMap.put(MD5SUM, new MessageFormat("{0} *{1}")); + formatMap.put(SVF, new MessageFormat("MD5 ({1}) = {0}")); + } + + public FormatElement() { + super(); + } + + public static FormatElement getDefault() { + FormatElement e = new FormatElement(); + e.setValue(CHECKSUM); + return e; + } + + public MessageFormat getFormat() { + return (MessageFormat) formatMap.get(getValue()); + } + + public String[] getValues() { + return new String[] {CHECKSUM, MD5SUM, SVF}; + } + } } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/ChecksumTest.java b/src/testcases/org/apache/tools/ant/taskdefs/ChecksumTest.java index 591cafdfb..88a090df5 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/ChecksumTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/ChecksumTest.java @@ -47,6 +47,27 @@ public class ChecksumTest extends BuildFileTest { project.resolveFile("../asf-logo.gif.MD5"))); } + public void testCreateMD5SUMformat() throws IOException { + FileUtils fileUtils = FileUtils.newFileUtils(); + executeTarget("createMD5SUMformat"); + assertTrue(fileUtils.contentEquals(project.resolveFile("expected/asf-logo.gif.md5sum"), + project.resolveFile("../asf-logo.gif.MD5SUM"))); + } + + public void testCreateSVFformat() throws IOException { + FileUtils fileUtils = FileUtils.newFileUtils(); + executeTarget("createSVFformat"); + assertTrue(fileUtils.contentEquals(project.resolveFile("expected/asf-logo.gif.svf"), + project.resolveFile("../asf-logo.gif.SVF"))); + } + + public void testCreatePattern() throws IOException { + FileUtils fileUtils = FileUtils.newFileUtils(); + executeTarget("createPattern"); + assertTrue(fileUtils.contentEquals(project.resolveFile("expected/asf-logo.gif.pattern"), + project.resolveFile("../asf-logo.gif.PATTERN"))); + } + public void testSetProperty() { executeTarget("setProperty"); assertEquals("0541d3df42520911f268abc730f3afe0", @@ -76,6 +97,12 @@ public class ChecksumTest extends BuildFileTest { assertEquals("false", project.getProperty("no.logo.MD5")); } + public void testVerifyMD5SUMAsTask() { + testVerify("verifyMD5SUMAsTask"); + assertNotNull(project.getProperty("no.logo.MD5")); + assertEquals("false", project.getProperty("no.logo.MD5")); + } + public void testVerifyAsCondition() { testVerify("verifyAsCondition"); assertNull(project.getProperty("no.logo.MD5"));