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 }