aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Checksum.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Checksum.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Checksum.java712
1 files changed, 0 insertions, 712 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Checksum.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Checksum.java
deleted file mode 100644
index 7a94ca09..00000000
--- a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Checksum.java
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.apache.tools.ant.taskdefs;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.security.DigestInputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.text.MessageFormat;
-import java.text.ParseException;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-
-import org.apache.tools.ant.BuildException;
-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.types.Resource;
-import org.apache.tools.ant.types.ResourceCollection;
-import org.apache.tools.ant.types.resources.FileProvider;
-import org.apache.tools.ant.types.resources.Restrict;
-import org.apache.tools.ant.types.resources.Union;
-import org.apache.tools.ant.types.resources.selectors.Type;
-import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.StringUtils;
-
-/**
- * Used to create or verify file checksums.
- *
- * @since Ant 1.5
- *
- * @ant.task category="control"
- */
-public class Checksum extends MatchingTask implements Condition {
-
- private static final int NIBBLE = 4;
- private static final int WORD = 16;
- private static final int BUFFER_SIZE = 8 * 1024;
- private static final int BYTE_MASK = 0xFF;
-
- private static class FileUnion extends Restrict {
- private Union u;
- FileUnion() {
- u = new Union();
- super.add(u);
- super.add(Type.FILE);
- }
- public void add(ResourceCollection rc) {
- u.add(rc);
- }
- }
-
- /**
- * File for which checksum is to be calculated.
- */
- private File file = null;
-
- /**
- * Root directory in which the checksum files will be written.
- * If not specified, the checksum files will be written
- * in the same directory as each file.
- */
- private File todir;
-
- /**
- * MessageDigest algorithm to be used.
- */
- private String algorithm = "MD5";
- /**
- * MessageDigest Algorithm provider
- */
- private String provider = null;
- /**
- * File Extension that is be to used to create or identify
- * destination file
- */
- private String fileext;
- /**
- * Holds generated checksum and gets set as a Project Property.
- */
- private String property;
- /**
- * Holds checksums for all files (both calculated and cached on disk).
- * Key: java.util.File (source file)
- * Value: java.lang.String (digest)
- */
- private Map<File, byte[]> allDigests = new HashMap<File, byte[]>();
- /**
- * Holds relative file names for all files (always with a forward slash).
- * This is used to calculate the total hash.
- * Key: java.util.File (source file)
- * Value: java.lang.String (relative file name)
- */
- private Map<File, String> relativeFilePaths = new HashMap<File, String>();
- /**
- * Property where totalChecksum gets set.
- */
- private String totalproperty;
- /**
- * Whether or not to create a new file.
- * Defaults to <code>false</code>.
- */
- private boolean forceOverwrite;
- /**
- * Contains the result of a checksum verification. ("true" or "false")
- */
- private String verifyProperty;
- /**
- * Resource Collection.
- */
- private FileUnion resources = null;
- /**
- * Stores SourceFile, DestFile pairs and SourceFile, Property String pairs.
- */
- private Hashtable<File, Object> includeFileMap = new Hashtable<File, Object>();
- /**
- * Message Digest instance
- */
- private MessageDigest messageDigest;
- /**
- * is this task being used as a nested condition element?
- */
- private boolean isCondition;
- /**
- * Size of the read buffer to use.
- */
- private int readBufferSize = BUFFER_SIZE;
-
- /**
- * Formater for the checksum file.
- */
- private MessageFormat format = FormatElement.getDefault().getFormat();
-
- /**
- * Sets the file for which the checksum is to be calculated.
- * @param file a <code>File</code> value
- */
- public void setFile(File file) {
- this.file = file;
- }
-
- /**
- * Sets the root directory where checksum files will be
- * written/read
- * @param todir the directory to write to
- * @since Ant 1.6
- */
- public void setTodir(File todir) {
- this.todir = todir;
- }
-
- /**
- * Specifies the algorithm to be used to compute the checksum.
- * Defaults to "MD5". Other popular algorithms like "SHA" may be used as well.
- * @param algorithm a <code>String</code> value
- */
- public void setAlgorithm(String algorithm) {
- this.algorithm = algorithm;
- }
-
- /**
- * Sets the MessageDigest algorithm provider to be used
- * to calculate the checksum.
- * @param provider a <code>String</code> value
- */
- public void setProvider(String provider) {
- this.provider = provider;
- }
-
- /**
- * Sets the file extension that is be to used to
- * create or identify destination file.
- * @param fileext a <code>String</code> value
- */
- public void setFileext(String fileext) {
- this.fileext = fileext;
- }
-
- /**
- * Sets the property to hold the generated checksum.
- * @param property a <code>String</code> value
- */
- public void setProperty(String property) {
- this.property = property;
- }
-
- /**
- * Sets the property to hold the generated total checksum
- * for all files.
- * @param totalproperty a <code>String</code> value
- *
- * @since Ant 1.6
- */
- public void setTotalproperty(String totalproperty) {
- this.totalproperty = totalproperty;
- }
-
- /**
- * Sets the verify property. This project property holds
- * the result of a checksum verification - "true" or "false"
- * @param verifyProperty a <code>String</code> value
- */
- public void setVerifyproperty(String verifyProperty) {
- this.verifyProperty = verifyProperty;
- }
-
- /**
- * Whether or not to overwrite existing file irrespective of
- * whether it is newer than
- * the source file. Defaults to false.
- * @param forceOverwrite a <code>boolean</code> value
- */
- public void setForceOverwrite(boolean forceOverwrite) {
- this.forceOverwrite = forceOverwrite;
- }
-
- /**
- * The size of the read buffer to use.
- * @param size an <code>int</code> value
- */
- public void setReadBufferSize(int size) {
- this.readBufferSize = size;
- }
-
- /**
- * Select the in/output pattern via a well know format name.
- * @param e an <code>enumerated</code> value
- *
- * @since 1.7.0
- */
- public void setFormat(FormatElement e) {
- format = e.getFormat();
- }
-
- /**
- * Specify the pattern to use as a MessageFormat pattern.
- *
- * <p>{0} gets replaced by the checksum, {1} by the filename.</p>
- * @param p a <code>String</code> value
- *
- * @since 1.7.0
- */
- public void setPattern(String p) {
- format = new MessageFormat(p);
- }
-
- /**
- * Files to generate checksums for.
- * @param set a fileset of files to generate checksums for.
- */
- public void addFileset(FileSet set) {
- add(set);
- }
-
- /**
- * Add a resource collection.
- * @param rc the ResourceCollection to add.
- */
- public void add(ResourceCollection rc) {
- if (rc == null) {
- return;
- }
- resources = (resources == null) ? new FileUnion() : resources;
- resources.add(rc);
- }
-
- /**
- * Calculate the checksum(s).
- * @throws BuildException on error
- */
- public void execute() throws BuildException {
- isCondition = false;
- boolean value = validateAndExecute();
- if (verifyProperty != null) {
- getProject().setNewProperty(
- verifyProperty,
- (value ? Boolean.TRUE.toString() : Boolean.FALSE.toString()));
- }
- }
-
- /**
- * Calculate the checksum(s)
- *
- * @return Returns true if the checksum verification test passed,
- * false otherwise.
- * @throws BuildException on error
- */
- public boolean eval() throws BuildException {
- isCondition = true;
- return validateAndExecute();
- }
-
- /**
- * Validate attributes and get down to business.
- */
- private boolean validateAndExecute() throws BuildException {
- String savedFileExt = fileext;
-
- if (file == null && (resources == null || resources.size() == 0)) {
- throw new BuildException(
- "Specify at least one source - a file or a resource collection.");
- }
- if (!(resources == null || resources.isFilesystemOnly())) {
- throw new BuildException("Can only calculate checksums for file-based resources.");
- }
- if (file != null && file.exists() && file.isDirectory()) {
- throw new BuildException("Checksum cannot be generated for directories");
- }
- if (file != null && totalproperty != null) {
- throw new BuildException("File and Totalproperty cannot co-exist.");
- }
- if (property != null && fileext != null) {
- throw new BuildException("Property and FileExt cannot co-exist.");
- }
- if (property != null) {
- if (forceOverwrite) {
- throw new BuildException(
- "ForceOverwrite cannot be used when Property is specified");
- }
- int ct = 0;
- if (resources != null) {
- ct += resources.size();
- }
- if (file != null) {
- ct++;
- }
- if (ct > 1) {
- throw new BuildException(
- "Multiple files cannot be used when Property is specified");
- }
- }
- if (verifyProperty != null) {
- isCondition = true;
- }
- if (verifyProperty != null && forceOverwrite) {
- throw new BuildException("VerifyProperty and ForceOverwrite cannot co-exist.");
- }
- if (isCondition && forceOverwrite) {
- throw new BuildException(
- "ForceOverwrite cannot be used when conditions are being used.");
- }
- messageDigest = null;
- if (provider != null) {
- try {
- messageDigest = MessageDigest.getInstance(algorithm, provider);
- } catch (NoSuchAlgorithmException noalgo) {
- throw new BuildException(noalgo, getLocation());
- } catch (NoSuchProviderException noprovider) {
- throw new BuildException(noprovider, getLocation());
- }
- } else {
- try {
- messageDigest = MessageDigest.getInstance(algorithm);
- } catch (NoSuchAlgorithmException noalgo) {
- throw new BuildException(noalgo, getLocation());
- }
- }
- if (messageDigest == null) {
- throw new BuildException("Unable to create Message Digest", getLocation());
- }
- if (fileext == null) {
- fileext = "." + algorithm;
- } else if (fileext.trim().length() == 0) {
- throw new BuildException("File extension when specified must not be an empty string");
- }
- try {
- if (resources != null) {
- for (Resource r : resources) {
- File src = r.as(FileProvider.class)
- .getFile();
- if (totalproperty != null || todir != null) {
- // Use '/' to calculate digest based on file name.
- // This is required in order to get the same result
- // on different platforms.
- relativeFilePaths.put(src, r.getName().replace(File.separatorChar, '/'));
- }
- addToIncludeFileMap(src);
- }
- }
- if (file != null) {
- if (totalproperty != null || todir != null) {
- relativeFilePaths.put(
- file, file.getName().replace(File.separatorChar, '/'));
- }
- addToIncludeFileMap(file);
- }
- return generateChecksums();
- } finally {
- fileext = savedFileExt;
- includeFileMap.clear();
- }
- }
-
- /**
- * Add key-value pair to the hashtable upon which
- * to later operate upon.
- */
- private void addToIncludeFileMap(File file) throws BuildException {
- if (file.exists()) {
- if (property == null) {
- File checksumFile = getChecksumFile(file);
- if (forceOverwrite || isCondition
- || (file.lastModified() > checksumFile.lastModified())) {
- includeFileMap.put(file, checksumFile);
- } else {
- log(file + " omitted as " + checksumFile + " is up to date.",
- Project.MSG_VERBOSE);
- if (totalproperty != null) {
- // Read the checksum from disk.
- String checksum = readChecksum(checksumFile);
- byte[] digest = decodeHex(checksum.toCharArray());
- allDigests.put(file, digest);
- }
- }
- } else {
- includeFileMap.put(file, property);
- }
- } else {
- String message = "Could not find file "
- + file.getAbsolutePath()
- + " to generate checksum for.";
- log(message);
- throw new BuildException(message, getLocation());
- }
- }
-
- private File getChecksumFile(File file) {
- File directory;
- if (todir != null) {
- // A separate directory was explicitly declared
- String path = getRelativeFilePath(file);
- directory = new File(todir, path).getParentFile();
- // Create the directory, as it might not exist.
- directory.mkdirs();
- } else {
- // Just use the same directory as the file itself.
- // This directory will exist
- directory = file.getParentFile();
- }
- File checksumFile = new File(directory, file.getName() + fileext);
- return checksumFile;
- }
-
- /**
- * Generate checksum(s) using the message digest created earlier.
- */
- private boolean generateChecksums() throws BuildException {
- boolean checksumMatches = true;
- FileInputStream fis = null;
- FileOutputStream fos = null;
- byte[] buf = new byte[readBufferSize];
- try {
- for (Map.Entry<File, Object> e : includeFileMap.entrySet()) {
- messageDigest.reset();
- File src = e.getKey();
- if (!isCondition) {
- log("Calculating " + algorithm + " checksum for " + src, Project.MSG_VERBOSE);
- }
- fis = new FileInputStream(src);
- DigestInputStream dis = new DigestInputStream(fis,
- messageDigest);
- while (dis.read(buf, 0, readBufferSize) != -1) {
- // Empty statement
- }
- dis.close();
- fis.close();
- fis = null;
- byte[] fileDigest = messageDigest.digest ();
- if (totalproperty != null) {
- allDigests.put(src, fileDigest);
- }
- String checksum = createDigestString(fileDigest);
- //can either be a property name string or a file
- Object destination = e.getValue();
- if (destination instanceof java.lang.String) {
- String prop = (String) destination;
- if (isCondition) {
- checksumMatches
- = checksumMatches && checksum.equals(property);
- } else {
- getProject().setNewProperty(prop, checksum);
- }
- } else if (destination instanceof java.io.File) {
- if (isCondition) {
- File existingFile = (File) destination;
- if (existingFile.exists()) {
- 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(format.format(new Object[] {
- checksum,
- src.getName(),
- FileUtils
- .getRelativePath(dest
- .getParentFile(),
- src),
- FileUtils
- .getRelativePath(getProject()
- .getBaseDir(),
- src),
- src.getAbsolutePath()
- }).getBytes());
- fos.write(StringUtils.LINE_SEP.getBytes());
- fos.close();
- fos = null;
- }
- }
- }
- if (totalproperty != null) {
- // Calculate the total checksum
- // Convert the keys (source files) into a sorted array.
- File[] keyArray = allDigests.keySet().toArray(new File[allDigests.size()]);
- // File is Comparable, but sort-order is platform
- // dependent (case-insensitive on Windows)
- Arrays.sort(keyArray, new Comparator<File>() {
- public int compare(File f1, File f2) {
- return f1 == null ? (f2 == null ? 0 : -1)
- : (f2 == null ? 1
- : getRelativeFilePath(f1)
- .compareTo(getRelativeFilePath(f2)));
- }
- });
- // Loop over the checksums and generate a total hash.
- messageDigest.reset();
- for (File src : keyArray) {
- // Add the digest for the file content
- byte[] digest = allDigests.get(src);
- messageDigest.update(digest);
-
- // Add the file path
- String fileName = getRelativeFilePath(src);
- messageDigest.update(fileName.getBytes());
- }
- String totalChecksum = createDigestString(messageDigest.digest());
- getProject().setNewProperty(totalproperty, totalChecksum);
- }
- } catch (Exception e) {
- throw new BuildException(e, getLocation());
- } finally {
- FileUtils.close(fis);
- FileUtils.close(fos);
- }
- return checksumMatches;
- }
-
- private String createDigestString(byte[] fileDigest) {
- StringBuffer checksumSb = new StringBuffer();
- for (int i = 0; i < fileDigest.length; i++) {
- String hexStr = Integer.toHexString(BYTE_MASK & fileDigest[i]);
- if (hexStr.length() < 2) {
- checksumSb.append("0");
- }
- checksumSb.append(hexStr);
- }
- return checksumSb.toString();
- }
-
- /**
- * Converts an array of characters representing hexadecimal values into an
- * array of bytes of those same values. The returned array will be half the
- * length of the passed array, as it takes two characters to represent any
- * given byte. An exception is thrown if the passed char array has an odd
- * number of elements.
- *
- * NOTE: This code is copied from jakarta-commons codec.
- * @param data an array of characters representing hexadecimal values
- * @return the converted array of bytes
- * @throws BuildException on error
- */
- public static byte[] decodeHex(char[] data) throws BuildException {
- int l = data.length;
-
- if ((l & 0x01) != 0) {
- throw new BuildException("odd number of characters.");
- }
-
- byte[] out = new byte[l >> 1];
-
- // two characters form the hex value.
- for (int i = 0, j = 0; j < l; i++) {
- int f = Character.digit(data[j++], WORD) << NIBBLE;
- f = f | Character.digit(data[j++], WORD);
- out[i] = (byte) (f & BYTE_MASK);
- }
-
- 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 {
- FileUtils.close(diskChecksumReader);
- }
- }
-
- /**
- * @since Ant 1.8.2
- */
- private String getRelativeFilePath(File f) {
- String path = (String) relativeFilePaths.get(f);
- if (path == null) {
- //bug 37386. this should not occur, but it has, once.
- throw new BuildException("Internal error: "
- + "relativeFilePaths could not match file "
- + f + "\n"
- + "please file a bug report on this");
- }
- return path;
- }
-
- /**
- * Helper class for the format attribute.
- *
- * @since 1.7
- */
- public static class FormatElement extends EnumeratedAttribute {
- private static HashMap<String, MessageFormat> formatMap = new HashMap<String, MessageFormat>();
- 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}"));
- }
-
- /** Constructor for FormatElement */
- public FormatElement() {
- super();
- }
-
- /**
- * Get the default value - CHECKSUM.
- * @return the defaul value.
- */
- public static FormatElement getDefault() {
- FormatElement e = new FormatElement();
- e.setValue(CHECKSUM);
- return e;
- }
-
- /**
- * Convert this enumerated type to a <code>MessageFormat</code>.
- * @return a <code>MessageFormat</code> object.
- */
- public MessageFormat getFormat() {
- return (MessageFormat) formatMap.get(getValue());
- }
-
- /**
- * Get the valid values.
- * @return an array of values.
- */
- public String[] getValues() {
- return new String[] {CHECKSUM, MD5SUM, SVF};
- }
- }
-}