com.anrisoftware.globalpom.checkfilehash.CheckFileHash.java Source code

Java tutorial

Introduction

Here is the source code for com.anrisoftware.globalpom.checkfilehash.CheckFileHash.java

Source

/*
 * Copyright 2013-2014 Erwin Mller <erwin.mueller@deventm.org>
 *
 * This file is part of globalpomutils-core.
 *
 * globalpomutils-core is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * globalpomutils-core is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with globalpomutils-core. If not, see <http://www.gnu.org/licenses/>.
 */
package com.anrisoftware.globalpom.checkfilehash;

import static org.apache.commons.io.FilenameUtils.getExtension;
import static org.apache.commons.io.IOUtils.readLines;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.concurrent.Callable;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;

import com.google.inject.assistedinject.Assisted;

/**
 * Checks the hash of the specified file.
 *
 * @author Erwin Mueller, erwin.mueller@deventm.org
 * @since 2.3
 */
public class CheckFileHash implements Callable<CheckFileHash> {

    private static final String SEP = " ";

    private static final String HASH_RESOURCE = "hash resource";

    private static final String FILE = "file";

    private final CheckFileHashLogger log;

    private final URI file;

    private final URI hashResource;

    private final HashName hashName;

    private boolean matching;

    /**
     * @see CheckFileHashFactory#create(Map, Object)
     */
    @Inject
    CheckFileHash(CheckFileHashLogger log, @Assisted Map<String, Object> args, @Assisted Object script) {
        this.log = log;
        this.file = log.file(script, args);
        this.hashResource = log.hash(script, args);
        this.hashName = hashName(hashResource);
    }

    private HashName hashName(URI hashResource) {
        if (StringUtils.equals(hashResource.getScheme(), "md5")) {
            return HashName.forExtension("md5");
        } else if (StringUtils.equals(hashResource.getScheme(), "sha1")) {
            return HashName.forExtension("sha1");
        } else {
            String ex = getExtension(hashResource.getPath());
            return HashName.forExtension(ex);
        }
    }

    @Override
    public CheckFileHash call() throws Exception {
        String hashstr = readHash(hashResource, hashName);
        String expectedHashstr = readExpectedHash(hashResource);
        this.matching = hashstr.equals(expectedHashstr);
        log.hashMatching(this, expectedHashstr, hashstr, matching);
        return this;
    }

    /**
     * Returns if the hash of the file and the specified hash is matching.
     *
     * @return {@code true} if the hashes is matching.
     */
    public boolean isMatching() {
        return matching;
    }

    private String readHash(URI hashResource, HashName hashName)
            throws NoSuchAlgorithmException, IOException, MalformedURLException {
        MessageDigest md = MessageDigest.getInstance(hashName.getHashName());
        InputStream fis = file.toURL().openStream();
        byte[] mdbytes = readFile(md, fis);
        String hashstr = toHexString(mdbytes);
        return hashstr;
    }

    private String readExpectedHash(URI hashResource) throws Exception {
        if (StringUtils.equals(hashResource.getScheme(), "md5")) {
            return hashResource.getSchemeSpecificPart();
        } else if (StringUtils.equals(hashResource.getScheme(), "sha1")) {
            return hashResource.getSchemeSpecificPart();
        } else {
            String line = readLines(hashResource.toURL().openStream()).get(0);
            String hash = StringUtils.split(line, SEP)[0];
            return hash;
        }
    }

    private String toHexString(byte[] mdbytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < mdbytes.length; i++) {
            String s = Integer.toString((mdbytes[i] & 0xff) + 0x100, 16);
            sb.append(s.substring(1));
        }
        return sb.toString();
    }

    private byte[] readFile(MessageDigest md, InputStream fis) throws IOException {
        byte[] dataBytes = new byte[1024];
        int nread = 0;
        while ((nread = fis.read(dataBytes)) != -1) {
            md.update(dataBytes, 0, nread);
        }
        return md.digest();
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this).append(FILE, file).append(HASH_RESOURCE, hashResource).toString();
    }
}