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.zip.ZipArchiveOutputStream; 017import org.apache.commons.compress.utils.IOUtils; 018 019/** 020 * Serialize a BagIt bag into a zip archive without compression 021 * 022 * @author mikejritter 023 * @since 2020-02-24 024 */ 025public class ZipBagSerializer implements BagSerializer { 026 private final String extension = ".zip"; 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 ZipArchiveOutputStream zip = new ZipArchiveOutputStream(os)) { 036 037 // it would be nice not to have to collect the files which are walked, but we're required to try/catch 038 // inside of a lambda which isn't the prettiest. maybe a result could be returned which contains either a 039 // Path or the Exception thrown... just an idea 040 final List<Path> files = Files.walk(root).collect(Collectors.toList()); 041 for (Path bagEntry : files) { 042 final String name = parent.relativize(bagEntry).toString(); 043 final ArchiveEntry entry = zip.createArchiveEntry(bagEntry.toFile(), name); 044 zip.putArchiveEntry(entry); 045 if (bagEntry.toFile().isFile()) { 046 try (InputStream inputStream = Files.newInputStream(bagEntry)) { 047 IOUtils.copy(inputStream, zip); 048 } 049 } 050 zip.closeArchiveEntry(); 051 } 052 } 053 054 return serializedBag; 055 } 056}