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            tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
037            tar.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
038            final List<Path> files = Files.walk(root).collect(Collectors.toList());
039            for (Path bagEntry : files) {
040                final String name = parent.relativize(bagEntry).toString();
041                final ArchiveEntry entry = tar.createArchiveEntry(bagEntry.toFile(), name);
042                tar.putArchiveEntry(entry);
043                if (bagEntry.toFile().isFile()) {
044                    try (InputStream inputStream = Files.newInputStream(bagEntry)) {
045                        IOUtils.copy(inputStream, tar);
046                    }
047                }
048                tar.closeArchiveEntry();
049            }
050        }
051
052        return serializedBag;
053    }
054
055}