org.roda_project.commons_ip.model.impl.hungarian.HungarianSIP.java Source code

Java tutorial

Introduction

Here is the source code for org.roda_project.commons_ip.model.impl.hungarian.HungarianSIP.java

Source

/**
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE file at the root of the source
 * tree and available online at
 *
 * https://github.com/keeps/commons-ip
 */
package org.roda_project.commons_ip.model.impl.hungarian;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.channels.ClosedByInterruptException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.roda_project.commons_ip.model.IPConstants;
import org.roda_project.commons_ip.model.IPContentType;
import org.roda_project.commons_ip.model.MetsWrapper;
import org.roda_project.commons_ip.model.SIP;
import org.roda_project.commons_ip.model.impl.ModelUtils;
import org.roda_project.commons_ip.utils.IPException;
import org.roda_project.commons_ip.utils.METSZipEntryInfo;
import org.roda_project.commons_ip.utils.ZIPUtils;
import org.roda_project.commons_ip.utils.ZipEntryInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HungarianSIP extends SIP {
    private static final Logger LOGGER = LoggerFactory.getLogger(HungarianSIP.class);

    private static final String SIP_TEMP_DIR = "HungarianSIP";
    private static final String SIP_FILE_EXTENSION = ".zip";
    private static final String TXT_FILE_EXTENSION = ".txt";

    public HungarianSIP() {
        super();
    }

    /**
     * @param sipId
     *          will be used as OBJID in METS (/mets[@OBJID])
     */
    public HungarianSIP(String sipId, IPContentType contentType) {
        super(sipId, contentType);
    }

    /**
     * 
     * build and all build related methods
     * _________________________________________________________________________
     */
    @Override
    public Path build(Path destinationDirectory) throws IPException, InterruptedException {
        return build(destinationDirectory, null);
    }

    /**
     * Builds a SIP.
     *
     * @param destinationDirectory
     *          the {@link Path} where the SIP should be build.
     * @param onlyManifest
     *          build only the manifest file? (<strong>this parameter is
     *          ignored</strong>).
     * @return the {@link Path}.
     * @throws IPException
     *           if some error occurs.
     * @throws InterruptedException
     *           if some error occurs.
     */
    @Override
    public Path build(final Path destinationDirectory, final boolean onlyManifest)
            throws IPException, InterruptedException {
        return build(destinationDirectory, null);
    }

    @Override
    public Path build(Path destinationDirectory, String fileNameWithoutExtension)
            throws IPException, InterruptedException {
        return build(destinationDirectory, fileNameWithoutExtension, false);
    }

    /**
     *
     * build and all build related methods
     * _________________________________________________________________________
     */
    /**
     * Builds a SIP.
     *
     * @param destinationDirectory
     *          the {@link Path} where the SIP should be build.
     * @param fileNameWithoutExtension
     *          the name of the output file without extension.
     * @param onlyManifest
     *          build only the manifest file? (<strong>this parameter is
     *          ignored</strong>).
     * @return the {@link Path}.
     * @throws IPException
     *           if some error occurs.
     * @throws InterruptedException
     *           if some error occurs.
     */
    @Override
    public Path build(final Path destinationDirectory, final String fileNameWithoutExtension,
            final boolean onlyManifest) throws IPException, InterruptedException {
        IPConstants.METS_ENCODE_AND_DECODE_HREF = false;
        Path buildDir = ModelUtils.createBuildDir(SIP_TEMP_DIR);
        Path zipPath = getZipPath(destinationDirectory, fileNameWithoutExtension);
        try {
            Map<String, ZipEntryInfo> zipEntries = getZipEntries();

            MetsWrapper mainMETSWrapper = HungarianMETSUtils.generateMETS(StringUtils.join(this.getIds(), " "),
                    this.getDescription(), this.getType(), this.getProfile(), null, this.getHeader());

            HungarianUtils.addMetadataToMETS(mainMETSWrapper, getDescriptiveMetadata());
            HungarianUtils.addRepresentationsToZipAndMETS(this, getRepresentations(), zipEntries, mainMETSWrapper);
            HungarianUtils.addDocumentationToZipAndMETS(zipEntries, mainMETSWrapper, getDocumentation());
            HungarianUtils.addMainMETSToZip(zipEntries, mainMETSWrapper, buildDir);

            createZipFile(zipEntries, zipPath);
            createTxtFile(destinationDirectory, fileNameWithoutExtension, zipEntries, zipPath);

            return zipPath;
        } catch (InterruptedException e) {
            ModelUtils.cleanUpUponInterrupt(LOGGER, zipPath);
            throw e;
        } finally {
            ModelUtils.deleteBuildDir(buildDir);
        }
    }

    private Path getZipPath(Path destinationDirectory, String fileNameWithoutExtension) throws IPException {
        Path zipPath;
        if (fileNameWithoutExtension != null) {
            zipPath = destinationDirectory.resolve(fileNameWithoutExtension + SIP_FILE_EXTENSION);
        } else {
            zipPath = destinationDirectory.resolve(getId() + SIP_FILE_EXTENSION);
        }

        try {
            if (Files.exists(zipPath)) {
                Files.delete(zipPath);
            }
        } catch (IOException e) {
            throw new IPException("Error deleting already existing ZIP", e);
        }

        return zipPath;
    }

    private void createZipFile(Map<String, ZipEntryInfo> zipEntries, Path zipPath)
            throws IPException, InterruptedException {
        try {
            notifySipBuildPackagingStarted(zipEntries.size());
            ZIPUtils.zip(zipEntries, Files.newOutputStream(zipPath), this, false, false);
        } catch (ClosedByInterruptException e) {
            throw new InterruptedException();
        } catch (IOException e) {
            throw new IPException("Error generating Hungarian SIP ZIP file. Reason: " + e.getMessage(), e);
        } finally {
            notifySipBuildPackagingEnded();
        }
    }

    private void createTxtFile(Path destinationDirectory, String fileNameWithoutExtension,
            Map<String, ZipEntryInfo> zipEntries, Path zipPath) {
        Path txtPath;
        if (fileNameWithoutExtension != null) {
            txtPath = destinationDirectory.resolve(fileNameWithoutExtension + TXT_FILE_EXTENSION);
        } else {
            txtPath = destinationDirectory.resolve(getId() + TXT_FILE_EXTENSION);
        }

        try (PrintWriter writer = new PrintWriter(txtPath.toFile())) {
            ZipEntryInfo zipEntryInfo = zipEntries.get(IPConstants.HUNGARIAN_METADATA_FILE);
            if (zipEntryInfo != null && zipEntryInfo instanceof METSZipEntryInfo) {
                METSZipEntryInfo metsEntry = (METSZipEntryInfo) zipEntryInfo;
                Map<String, String> checksums = metsEntry.getChecksums();
                long size = metsEntry.getSize();
                final String separator = ": ";

                writer.println(IPConstants.METADATA_FILE + separator + size);
                writer.println(IPConstants.CHECKSUM_MD5_ALGORITHM + separator
                        + checksums.get(IPConstants.CHECKSUM_MD5_ALGORITHM));
                writer.println(IPConstants.CHECKSUM_SHA_1_ALGORITHM + separator
                        + checksums.get(IPConstants.CHECKSUM_SHA_1_ALGORITHM));

                try (FileInputStream zipStream = new FileInputStream(zipPath.toFile())) {
                    Set<String> zipChecksums = new HashSet<>();
                    zipChecksums.add(IPConstants.CHECKSUM_MD5_ALGORITHM);
                    zipChecksums.add(IPConstants.CHECKSUM_SHA_1_ALGORITHM);
                    Map<String, String> calculateChecksums = ZIPUtils.calculateChecksums(Optional.empty(),
                            zipStream, zipChecksums);

                    writer.println(zipPath.getFileName().toString() + separator + zipPath.toFile().length());
                    writer.println(IPConstants.CHECKSUM_MD5_ALGORITHM + separator
                            + calculateChecksums.get(IPConstants.CHECKSUM_MD5_ALGORITHM));
                    writer.println(IPConstants.CHECKSUM_SHA_1_ALGORITHM + separator
                            + calculateChecksums.get(IPConstants.CHECKSUM_SHA_1_ALGORITHM));
                } catch (NoSuchAlgorithmException e) {
                    LOGGER.error("Wrong checksum name used", e);
                } catch (IOException e) {
                    LOGGER.error("Could not open zip file", e);
                }

            }
        } catch (FileNotFoundException e) {
            LOGGER.error("Could not write SIP information to txt file", e);
        }
    }

    @Override
    public Set<String> getExtraChecksumAlgorithms() {
        Set<String> algorithms = new HashSet<>();
        algorithms.add(IPConstants.CHECKSUM_MD5_ALGORITHM);
        algorithms.add(IPConstants.CHECKSUM_SHA_1_ALGORITHM);
        return algorithms;
    }

}