diff --git a/src/main/java/gov/loc/repository/bagit/creator/BagCreator.java b/src/main/java/gov/loc/repository/bagit/creator/BagCreator.java index f48ac031c..e0db15f8d 100644 --- a/src/main/java/gov/loc/repository/bagit/creator/BagCreator.java +++ b/src/main/java/gov/loc/repository/bagit/creator/BagCreator.java @@ -6,7 +6,10 @@ import java.nio.file.Path; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.text.SimpleDateFormat; import java.util.Collection; +import java.util.Date; +import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; @@ -16,40 +19,78 @@ import gov.loc.repository.bagit.annotation.Incubating; import gov.loc.repository.bagit.domain.Bag; import gov.loc.repository.bagit.domain.Manifest; +import gov.loc.repository.bagit.domain.Metadata; import gov.loc.repository.bagit.domain.Version; import gov.loc.repository.bagit.hash.Hasher; import gov.loc.repository.bagit.hash.SupportedAlgorithm; +import gov.loc.repository.bagit.util.PathUtils; import gov.loc.repository.bagit.writer.BagitFileWriter; import gov.loc.repository.bagit.writer.ManifestWriter; +import gov.loc.repository.bagit.writer.MetadataWriter; /** * Responsible for creating a bag in place. */ +//TODO look at cleaning up this class so we don't have to ignore CPD public final class BagCreator { private static final Logger logger = LoggerFactory.getLogger(BagCreator.class); private static final ResourceBundle messages = ResourceBundle.getBundle("MessageBundle"); + private static final String DATE_FORMAT = "yyyy-MM-dd"; private BagCreator(){} - @SuppressWarnings("CPD-START") /** - * Creates a basic(only required elements) bag in place for version 0.97. + * Creates a bag in place for version 0.97. * This method moves and creates files, thus if an error is thrown during operation it may leave the filesystem * in an unknown state of transition. Thus this is not thread safe * * @param root the directory that will become the base of the bag and where to start searching for content * @param algorithms an collection of {@link SupportedAlgorithm} implementations * @param includeHidden to include hidden files when generating the bagit files, like the manifests + * @param metadata the metadata to include when creating the bag. Payload-Oxum and Bagging-Date will be overwritten + * * @throws NoSuchAlgorithmException if {@link MessageDigest} can't find the algorithm * @throws IOException if there is a problem writing or moving file(s) + * * @return a {@link Bag} object representing the newly created bagit bag */ - public static Bag bagInPlace(final Path root, final Collection algorithms, final boolean includeHidden) throws NoSuchAlgorithmException, IOException{ + @SuppressWarnings("CPD-START") + public static Bag bagInPlace(final Path root, final Collection algorithms, final boolean includeHidden, final Metadata metadata) throws NoSuchAlgorithmException, IOException{ final Bag bag = new Bag(new Version(0, 97)); bag.setRootDir(root); logger.info(messages.getString("creating_bag"), bag.getVersion(), root); final Path dataDir = root.resolve("data"); + moveFilesToDataDirectory(root, dataDir, includeHidden); + + BagitFileWriter.writeBagitFile(bag.getVersion(), bag.getFileEncoding(), root); + + createManifests(root, dataDir, bag, algorithms, includeHidden); + + createMetadataFile(root, dataDir, bag, metadata); + + return bag; + } + + /** + * Creates a bag in place for version 0.97. + * This method moves and creates files, thus if an error is thrown during operation it may leave the filesystem + * in an unknown state of transition. Thus this is not thread safe + * + * @param root the directory that will become the base of the bag and where to start searching for content + * @param algorithms an collection of {@link SupportedAlgorithm} implementations + * @param includeHidden to include hidden files when generating the bagit files, like the manifests + * + * @throws NoSuchAlgorithmException if {@link MessageDigest} can't find the algorithm + * @throws IOException if there is a problem writing or moving file(s) + * + * @return a {@link Bag} object representing the newly created bagit bag + */ + public static Bag bagInPlace(final Path root, final Collection algorithms, final boolean includeHidden) throws NoSuchAlgorithmException, IOException{ + return bagInPlace(root, algorithms, includeHidden, new Metadata()); + } + + private static void moveFilesToDataDirectory(final Path root, final Path dataDir, final boolean includeHidden) throws IOException{ Files.createDirectory(dataDir); try(final DirectoryStream directoryStream = Files.newDirectoryStream(root)){ for(final Path path : directoryStream){ @@ -58,14 +99,15 @@ public static Bag bagInPlace(final Path root, final Collection algorithms, final boolean includeHidden) throws IOException, NoSuchAlgorithmException{ logger.info(messages.getString("creating_payload_manifests")); final Map payloadFilesMap = Hasher.createManifestToMessageDigestMap(algorithms); final CreatePayloadManifestsVistor payloadVisitor = new CreatePayloadManifestsVistor(payloadFilesMap, includeHidden); Files.walkFileTree(dataDir, payloadVisitor); bag.getPayLoadManifests().addAll(payloadFilesMap.keySet()); - BagitFileWriter.writeBagitFile(bag.getVersion(), bag.getFileEncoding(), root); ManifestWriter.writePayloadManifests(bag.getPayLoadManifests(), root, root, bag.getFileEncoding()); logger.info(messages.getString("creating_tag_manifests")); @@ -75,11 +117,22 @@ public static Bag bagInPlace(final Path root, final Collection