1 package com.imcode.ant.tasks; 2 3 import org.apache.tools.ant.BuildException; 4 import org.apache.tools.ant.DirectoryScanner; 5 import org.apache.tools.ant.Task; 6 import org.apache.tools.ant.types.FileSet; 7 import org.apache.commons.lang.StringUtils; 8 9 import java.io.*; 10 import java.security.MessageDigest; 11 import java.security.NoSuchAlgorithmException; 12 import java.text.DateFormat; 13 import java.text.SimpleDateFormat; 14 import java.util.*; 15 import java.math.BigInteger; 16 17 public class ChecksumFiles extends Task { 18 19 private List fileSets = new ArrayList(); 20 private File destFile; 21 private boolean append = false ; 22 private String digest; 23 24 public void addFileset( FileSet fileSet ) { 25 fileSets.add( fileSet ); 26 } 27 28 public void setDestFile( File destFile ) { 29 this.destFile = destFile; 30 } 31 32 public void setAppend( boolean append ) { 33 this.append = append ; 34 } 35 36 public void setDigest(String digest) { 37 this.digest = digest ; 38 } 39 40 public void execute() { 41 validateAttributes(); 42 BufferedWriter fileWriter = openDestFile( destFile ); 43 DateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); 44 for ( Iterator iterator = fileSets.iterator(); iterator.hasNext(); ) { 45 FileSet fileSet = (FileSet)iterator.next(); 46 outputDataAboutFileSet( fileSet, fileWriter, dateFormat ); 47 48 } 49 closeDestFile( fileWriter ); 50 } 51 52 private void closeDestFile( BufferedWriter fileWriter ) { 53 try { 54 fileWriter.close(); 55 } catch ( IOException e ) { 56 throw new BuildException( e ) ; 57 } 58 } 59 60 private BufferedWriter openDestFile( File destFile ) { 61 try { 62 return new BufferedWriter( new FileWriter( destFile, append ) ); 63 } catch ( IOException e ) { 64 throw new BuildException( e ); 65 } 66 } 67 68 private void outputDataAboutFileSet( FileSet fileSet, BufferedWriter destWriter, DateFormat dateFormat ) { 69 DirectoryScanner directoryScanner = fileSet.getDirectoryScanner( fileSet.getProject() ); 70 File baseDir = directoryScanner.getBasedir(); 71 String[] includedRelativeFilenames = directoryScanner.getIncludedFiles(); 72 outputDataAboutFilesRelativeToBaseDir( baseDir, includedRelativeFilenames, dateFormat, destWriter ); 73 } 74 75 private void outputDataAboutFilesRelativeToBaseDir( File baseDir, String[] relativeFilenames, 76 DateFormat dateFormat, BufferedWriter destWriter ) { 77 for ( int i = 0; i < relativeFilenames.length; i++ ) { 78 String relativeFilename = relativeFilenames[i]; 79 outputDataAboutFileRelativeToBaseDir( baseDir, relativeFilename, dateFormat, destWriter ); 80 } 81 } 82 83 private void outputDataAboutFileRelativeToBaseDir( File baseDir, String relativeFilename, DateFormat dateFormat, 84 BufferedWriter destWriter ) { 85 File file = new File( baseDir, relativeFilename ); 86 String digestString = digestFile( file ); 87 digestString = StringUtils.leftPad( digestString, 32 ) ; 88 String fileLength = ""+file.length() ; 89 fileLength = StringUtils.leftPad(fileLength, 8) ; 90 91 String datetime = dateFormat.format( new Date( file.lastModified() ) ); 92 try { 93 destWriter.write( datetime + " " + fileLength + " " + digestString +" "+relativeFilename); 94 destWriter.newLine(); 95 } catch ( IOException e ) { 96 throw new BuildException( e ); 97 } 98 } 99 100 private String digestFile( File includedFile ) { 101 MessageDigest messageDigest = getMessageDigest(); 102 FileInputStream inputStream = openFile( includedFile ); 103 try { 104 byte[] buffer = new byte[16384]; 105 for ( int bytesRead = 0; -1 != ( bytesRead = inputStream.read( buffer ) ); ) { 106 messageDigest.update( buffer, 0, bytesRead ); 107 } 108 } catch ( IOException e ) { 109 throw new BuildException( e ); 110 } 111 byte[] digestBytes = messageDigest.digest(); 112 BigInteger digestInteger = new BigInteger( 1, digestBytes ) ; 113 return digestInteger.toString(16) ; 114 } 115 116 private FileInputStream openFile( File includedFile ) { 117 try { 118 return new FileInputStream( includedFile ); 119 } catch ( FileNotFoundException e ) { 120 throw new BuildException( e ); 121 } 122 } 123 124 private MessageDigest getMessageDigest() { 125 try { 126 return MessageDigest.getInstance( digest ); 127 } catch ( NoSuchAlgorithmException e ) { 128 throw new BuildException( e ); 129 } 130 } 131 132 private void validateAttributes() { 133 if ( fileSets.isEmpty() ) { 134 throw new BuildException( "Specify at least one fileset." ); 135 } 136 if ( null == destFile ) { 137 throw new BuildException( "Specify a destfile." ); 138 } 139 } 140 141 }