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.IOException;
008import java.io.InputStream;
009import java.io.OutputStream;
010import java.nio.file.Files;
011import java.nio.file.Path;
012import java.util.List;
013import java.util.stream.Collectors;
014
015import org.apache.commons.compress.archivers.ArchiveEntry;
016import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
017import org.apache.commons.compress.utils.IOUtils;
018
019/**
020 * Serialize a BagIt Bag into a Tar archive
021 *
022 * @author mikejritter
023 * @since 2020-02-24
024 */
025public class TarBagSerializer implements BagSerializer {
026    private final String extension = ".tar";
027
028    @Override
029    public Path serialize(final Path root) throws IOException {
030        final Path parent = root.getParent().toAbsolutePath();
031        final String bagName = root.getFileName().toString();
032
033        final Path serializedBag = parent.resolve(bagName + extension);
034        try(final OutputStream os = Files.newOutputStream(serializedBag);
035            final TarArchiveOutputStream tar = new TarArchiveOutputStream(os)) {
036            final List<Path> files = Files.walk(root).collect(Collectors.toList());
037            for (Path bagEntry : files) {
038                final String name = parent.relativize(bagEntry).toString();
039                final ArchiveEntry entry = tar.createArchiveEntry(bagEntry.toFile(), name);
040                tar.putArchiveEntry(entry);
041                if (bagEntry.toFile().isFile()) {
042                    try (InputStream inputStream = Files.newInputStream(bagEntry)) {
043                        IOUtils.copy(inputStream, tar);
044                    }
045                }
046                tar.closeArchiveEntry();
047            }
048        }
049
050        return serializedBag;
051    }
052
053}