pl.psnc.synat.wrdz.mdz.integrity.IntegrityVerifierBean.java Source code

Java tutorial

Introduction

Here is the source code for pl.psnc.synat.wrdz.mdz.integrity.IntegrityVerifierBean.java

Source

/**
 * Copyright 2015 Pozna Supercomputing and Networking Center
 *
 * Licensed under the GNU General Public License, Version 3.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.gnu.org/licenses/gpl-3.0.txt
 *
 * 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 pl.psnc.synat.wrdz.mdz.integrity;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pl.psnc.synat.wrdz.common.exception.WrdzRuntimeException;
import pl.psnc.synat.wrdz.zmd.dto.object.FileHashDto;
import pl.psnc.synat.wrdz.zmd.entity.types.HashType;
import pl.psnc.synat.wrdz.zmd.object.FileHashBrowser;
import pl.psnc.synat.wrdz.zmd.object.ObjectNotFoundException;

/**
 * Default implementation of {@link IntegrityVerifier}.
 */
@Stateless
public class IntegrityVerifierBean implements IntegrityVerifier {

    /** Logger. */
    private static final Logger logger = LoggerFactory.getLogger(IntegrityVerifierBean.class);

    /** Hash browser used to fetch file hashes from ZMD. */
    @EJB(name = "FileHashBrowser")
    private FileHashBrowser hashBrowser;

    @Override
    public boolean isCorrupted(String identifier, File file) {
        ZipFile zip = null;
        try {
            zip = new ZipFile(file);

            List<FileHashDto> fileHashes = hashBrowser.getFileHashes(identifier);
            for (FileHashDto fileHash : fileHashes) {

                ZipEntry entry = zip.getEntry(fileHash.getObjectFilepath());
                if (entry == null) {
                    // file not found in the archive
                    return true;
                }

                String calculatedHash;

                InputStream stream = zip.getInputStream(entry);
                try {
                    calculatedHash = calculateHash(stream, fileHash.getHashType());
                } finally {
                    IOUtils.closeQuietly(stream);
                }

                if (!calculatedHash.equals(fileHash.getHashValue())) {
                    return true;
                }
            }

        } catch (ZipException e) {
            throw new WrdzRuntimeException("Given file is not a valid zip archive", e);
        } catch (NoSuchAlgorithmException e) {
            throw new WrdzRuntimeException("Unable to locate appropriate hashing algorithm classes", e);
        } catch (ObjectNotFoundException e) {
            throw new WrdzRuntimeException("Digital object not found in ZMD", e);
        } catch (IOException e) {
            throw new WrdzRuntimeException("Error while verifying object integrity", e);
        } finally {
            if (zip != null) {
                try {
                    zip.close();
                } catch (IOException e) {
                    logger.warn("Could not close the zip file", e);
                }
            }
        }
        return false;
    }

    /**
     * Calculates the hash value for data from the given stream using the given hash type.
     * 
     * @param stream
     *            data to be hashed
     * @param type
     *            type of hash to calculate
     * @return calculated hash value
     * @throws NoSuchAlgorithmException
     *             if classes for the given type's hashing algorithm could not be found
     * @throws IOException
     *             if there are any problems with the data stream
     */
    private String calculateHash(InputStream stream, HashType type) throws NoSuchAlgorithmException, IOException {
        MessageDigest md = MessageDigest.getInstance(type.getAlgorithmName());
        byte[] dataBytes = new byte[1024];
        int nread = 0;
        while ((nread = stream.read(dataBytes)) != -1) {
            md.update(dataBytes, 0, nread);
        }
        return type.toHexFormat(md.digest());
    }
}