package com.yahoo.platform.build.ant; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.FileSet; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.util.Iterator; import java.util.Properties; import java.util.Vector; import java.util.zip.CRC32; import java.util.zip.CheckedInputStream; /** * Use this task like this: *

* *

* * * * * *

* This task will copy the files specified in the nested fileset, will rename them * (replace their base name by the value of their checksum and keep the same extension) * and will set an ant property which name is the base name of the original file, and * the value is the full name of the destination file. */ public class FileTransform extends Task { private String todir; private boolean changefilenames; private String propertiesfile; private Vector filesets = new Vector(); public void setTodir(String todir) { this.todir = todir; } public void setChangefilenames(boolean changefilenames) { this.changefilenames = changefilenames; } public void setPropertiesfile(String propertiesfile) { this.propertiesfile = propertiesfile; } public void addFileset(FileSet fileset) { filesets.add(fileset); } protected void validate() { if (todir == null) throw new BuildException("attribute \"todir\" not set"); File dest = new File(todir); if (!dest.exists() || !dest.isDirectory()) throw new BuildException("the value specified by the attribute \"todir\" is not valid"); if (filesets.size() < 1) throw new BuildException("fileset not set"); } public void execute() { validate(); Properties properties = new Properties(); for (Iterator itFSets = filesets.iterator(); itFSets.hasNext();) { FileSet fs = (FileSet) itFSets.next(); DirectoryScanner ds = fs.getDirectoryScanner(getProject()); String[] includedFiles = ds.getIncludedFiles(); for (int i = 0; i < includedFiles.length; i++) { String srcFilename = includedFiles[i].replace('\\', '/'); srcFilename = srcFilename.substring(srcFilename.lastIndexOf("/") + 1); File srcFile = new File(ds.getBasedir(), includedFiles[i]); try { String dstFilename; if (changefilenames) { // Calculate the CRC-32 checksum of this file CheckedInputStream cis = new CheckedInputStream(new FileInputStream(srcFile), new CRC32()); byte[] tempBuf = new byte[128]; while (cis.read(tempBuf) >= 0) { } long checksum = cis.getChecksum().getValue(); // Get the file extension int idx = srcFilename.lastIndexOf('.'); String extension = ""; if (idx != -1) { extension = srcFilename.substring(idx); } // Compute the new filename dstFilename = String.valueOf(checksum) + extension; } else { dstFilename = srcFilename; } // // Copy the file // File dstDir = new File(todir); File dstFile = new File(dstDir, dstFilename); copy(srcFile, dstFile); // // Set the new property... // String propertyValue = dstFilename; getProject().setNewProperty(srcFilename, propertyValue); properties.setProperty(srcFilename, propertyValue); } catch (IOException e) { e.printStackTrace(); } } } if (propertiesfile != null) { try { properties.store(new FileOutputStream(new File(propertiesfile)), null); } catch (IOException e) { e.printStackTrace(); System.exit(1); } } } private static void copy(File source, File dest) throws IOException { FileChannel in = null, out = null; try { in = new FileInputStream(source).getChannel(); out = new FileOutputStream(dest).getChannel(); long size = in.size(); MappedByteBuffer buf = in.map(FileChannel.MapMode.READ_ONLY, 0, size); out.write(buf); } finally { if (in != null) in.close(); if (out != null) out.close(); } } }