Package org.jdesktop.wonderland.web.checksums.utils

Source Code of org.jdesktop.wonderland.web.checksums.utils.ChecksumUtils

/**
* Project Wonderland
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied
* this code.
*/
package org.jdesktop.wonderland.web.checksums.utils;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdesktop.wonderland.common.checksums.Checksum;
import org.jdesktop.wonderland.common.checksums.ChecksumList;

/**
* A collection of utilities to generate checksums.
*
* @author paulby
* @author Jordan Slott <jslott@dev.java.net>
*/
public class ChecksumUtils {
    /* The error logger */
    private static final Logger logger = Logger.getLogger(ChecksumUtils.class.getName());

    /* The SHA-1 checksum algorithm */
    public final static String SHA1_CHECKSUM_ALGORITHM = "SHA-1";

    /**
     * Creates an returns a new instance of the ChecksumList object given
     * a root directory to search, the name of the checksum algorithm, and an
     * array of regular expression to match against file names to include and
     * to exclude.
     * <p>
     * If the list of regular expressions to include is either null or an empty
     * string, all files will be included. If the list of regular expressions
     * to exclude is either null or an empty string, no files are excluded.
     *
     * @param root The root directory from which to label assets
     * @param dir The directory in which to generate checksums
     * @param algorithm The checksum algorithm
     * @param includes An array of regular expressions of files to include
     * @throw NoSuchAlgorithmException If the given checksum algorithm is invalid
     * @throw PatternSynaxException If either includes or excludes is invalid
     */
    public static ChecksumList generate(File root, File dir, String algorithm,
            String[] includes, String excludes[]) throws NoSuchAlgorithmException {
       
        /* Try creating the message digest, throws NoSuchAlgorithmException */
        MessageDigest digest = MessageDigest.getInstance(algorithm);
       
        /* Recursively generate checksums, then convert list to an array */
        HashMap<String, Checksum> list = new HashMap<String, Checksum>();
        list.putAll(ChecksumUtils.generateChecksumForDirectory(root, dir, digest, includes, excludes));

        ChecksumList checksumList = new ChecksumList();
        checksumList.setChecksums(list);
        return checksumList;
    }

    /**
     * Generates a checksum for a given file root as the basis for the name to
     * place in the checksum.
     *
     * @param root The root directory form which to label the asset
     * @param file The file to generate a checksum for
     * @param algorithm The checksum algorithm
     * @throw NoSuchAlgorithmException If the given checksum algorithm is invalid
     */
    public static ChecksumList generate(File root, File file, String algorithm) throws NoSuchAlgorithmException {
        // Generate the checksum for the file, but put it in the list and
        // return
        try {
            MessageDigest digest = MessageDigest.getInstance(algorithm);
            Checksum checksum = computeChecksum(root, file, digest);
            ChecksumList checksumList = new ChecksumList();
            checksumList.putChecksum(checksum);
            return checksumList;
        } catch (java.io.IOException excp) {
            logger.log(Level.WARNING, "Unable to generate checksum for " +
                    file.getAbsolutePath());
            return null;
        }
    }

    /**
     * Recursively generates checksums for the given directory. Returns a hash
     * map of all checksum objects beneath the given root directory.
     */
    private static HashMap<String, Checksum> generateChecksumForDirectory(File root,
            File dir, MessageDigest digest, String[] includes, String[] excludes) {
        /* Put all of the checksums we generate in this linked list */
        HashMap<String, Checksum> list = new HashMap<String, Checksum>();

        /*
         * Loop through all of the files. If it is a directory, then recursively
         * descend into subdirectories. Before computing the checksum make sure
         * the file name satisfies the includes and excludes list.
         */
        File[] files = dir.listFiles();
        if (files == null) {
            /*
             * No files or directory doesn't exist.  Just return an empty
             * map.
             */
            return list;
        }
        for (File file : files) {
            /* If a directory, then recursively descend and append */
            if (file.isDirectory() == true && file.isHidden() == false) {
                HashMap<String, Checksum> rList = ChecksumUtils.generateChecksumForDirectory(
                        root, file, digest, includes, excludes);
                list.putAll(rList);
            }
            else if (file.isFile() == true && file.isHidden() == false) {
                /*
                 * If a normal, non-hidden file, then check whether the name
                 * is included or excluded.
                 */
                if (ChecksumUtils.isAcceptable(file.getName(), includes, excludes) == true) {
                    try {
                        Checksum checksum = computeChecksum(root, file, digest);
                        list.put(checksum.getPathName(), checksum);
                    } catch (java.io.IOException excp) {
                        // Log an error, but continue
                        logger.log(Level.WARNING, "Failed to generate checksum" +
                                " for " + file.getAbsolutePath(), excp);
                    }
                }
            }
        }
        return list;
    }

    /**
     * Generates a checksum for the given file and returns a new Checksum
     * object. Takes the file and root directory
     */
    private static Checksum computeChecksum(File root, File file, MessageDigest digest) throws IOException {
        byte[] buf = new byte[1024 * 1024];
        int bytesRead = 0;
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis);
        InputStream in = new DigestInputStream(bis, digest);

        /* Read in the entire file */
        do {
            bytesRead = in.read(buf);
        } while (bytesRead != -1);
        in.close();

        /* Compute the checksum with the digest */
        byte[] byteChecksum = digest.digest();
        digest.reset();

        /*
         * The relative path name is the absolute path name of the
         * file, stripping off the absolute path name of the root
         */
        String name = file.getAbsolutePath().substring((int) (root.getAbsolutePath().length() + 1));

        /* Make sure the /'s are correct */
        if (File.separatorChar != '/') {
            name = name.replace(File.separatorChar, '/');
        }

        /* Create a new checksum object and add to the list */
        Checksum c = new Checksum();
        c.setLastModified(file.lastModified());
        c.setPathName(name);
        c.setChecksum(Checksum.toHexString(byteChecksum));
        return c;
    }

    /**
     * Given a file name and an array of (possible null) string regular
     * expressions of files patterns to include and exclude, return true if
     * the given file name is acceptable.
     */
    public static boolean isAcceptable(String name, String[] includes, String excludes[]) {
        /* Track whether the file name is acceptable */
        boolean acceptable = true;
       
        /*
         * Check whether the file name is expicitly included. Only do this if
         * includes is either not null and not an empty string. We need to
         * only match one includes to be included.
         */
        if (includes != null && includes.length > 0) {
            acceptable = false;
            for (String include : includes) {
                if (name.matches(include) == true) {
                    acceptable = true;
                    break;
                }
            }
        }
       
        /* If we did match any includes return false */
        if (acceptable == false) {
            return false;
        }
       
        /*
         * Check whether the file name is explicitly excluded. Only do this if
         * excludes is either not null and not an empty string. We need to
         * match only one excludes to be excluded.
         */
        if (excludes != null && excludes.length > 0) {
            for (String exclude: excludes) {
                if (name.matches(exclude) == true) {
                    return false;
                }
            }
        }
        return true;
    }
}
TOP

Related Classes of org.jdesktop.wonderland.web.checksums.utils.ChecksumUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.