001/*
002 * The contents of this file are subject to the license and copyright detailed
003 * in the LICENSE and NOTICE files at the root of the source tree.
004 */
005package org.duraspace.bagit;
006
007import java.io.BufferedInputStream;
008import java.io.IOException;
009import java.io.InputStream;
010import java.nio.file.FileAlreadyExistsException;
011import java.nio.file.Files;
012import java.nio.file.Path;
013
014import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
015import org.slf4j.Logger;
016import org.slf4j.LoggerFactory;
017
018/**
019 * Deflate a gzipped bag so that the underlying bag can continue to be deserialized.
020 *
021 * @author mikejritter
022 * @since 2020-02-11
023 */
024public class GZipBagDeserializer implements BagDeserializer {
025
026    private final Logger logger = LoggerFactory.getLogger(GZipBagDeserializer.class);
027
028    private final BagProfile profile;
029
030    protected GZipBagDeserializer(final BagProfile profile) {
031        this.profile = profile;
032    }
033
034    @Override
035    public Path deserialize(final Path root) throws IOException {
036        final Path parent = root.getParent();
037        final String nameWithExtension = root.getFileName().toString();
038        final int dotIdx = nameWithExtension.lastIndexOf(".");
039        final String filename = (dotIdx == -1) ? nameWithExtension : nameWithExtension.substring(0, dotIdx);
040        final Path serializedBag = parent.resolve(filename);
041
042        // Deflate the gzip to get the base file
043        logger.info("Deflating gzipped bag: {}", filename);
044        try (InputStream is = Files.newInputStream(root);
045            final InputStream bis = new BufferedInputStream(is);
046            final GzipCompressorInputStream gzipIS = new GzipCompressorInputStream(bis)) {
047
048            Files.copy(gzipIS, serializedBag);
049        } catch (FileAlreadyExistsException ex) {
050            logger.warn("{} already decompressed! Continuing with deserialization.", root);
051        }
052
053        // Get a deserializer for the deflated content
054        final BagDeserializer deserializer = SerializationSupport.deserializerFor(serializedBag, profile);
055        return deserializer.deserialize(serializedBag);
056    }
057}