66import java .nio .file .Path ;
77import java .security .MessageDigest ;
88import java .security .NoSuchAlgorithmException ;
9+ import java .text .SimpleDateFormat ;
910import java .util .Collection ;
11+ import java .util .Date ;
12+ import java .util .Locale ;
1013import java .util .Map ;
1114import java .util .ResourceBundle ;
1215
1619import gov .loc .repository .bagit .annotation .Incubating ;
1720import gov .loc .repository .bagit .domain .Bag ;
1821import gov .loc .repository .bagit .domain .Manifest ;
22+ import gov .loc .repository .bagit .domain .Metadata ;
1923import gov .loc .repository .bagit .domain .Version ;
2024import gov .loc .repository .bagit .hash .Hasher ;
2125import gov .loc .repository .bagit .hash .SupportedAlgorithm ;
26+ import gov .loc .repository .bagit .util .PathUtils ;
2227import gov .loc .repository .bagit .writer .BagitFileWriter ;
2328import gov .loc .repository .bagit .writer .ManifestWriter ;
29+ import gov .loc .repository .bagit .writer .MetadataWriter ;
2430
2531/**
2632 * Responsible for creating a bag in place.
2733 */
34+ //TODO look at cleaning up this class so we don't have to ignore CPD
2835public final class BagCreator {
2936 private static final Logger logger = LoggerFactory .getLogger (BagCreator .class );
3037 private static final ResourceBundle messages = ResourceBundle .getBundle ("MessageBundle" );
38+ private static final String DATE_FORMAT = "yyyy-MM-dd" ;
3139
3240 private BagCreator (){}
3341
34- @ SuppressWarnings ("CPD-START" )
3542 /**
36- * Creates a basic(only required elements) bag in place for version 0.97.
43+ * Creates a bag in place for version 0.97.
3744 * This method moves and creates files, thus if an error is thrown during operation it may leave the filesystem
3845 * in an unknown state of transition. Thus this is <b>not thread safe</b>
3946 *
4047 * @param root the directory that will become the base of the bag and where to start searching for content
4148 * @param algorithms an collection of {@link SupportedAlgorithm} implementations
4249 * @param includeHidden to include hidden files when generating the bagit files, like the manifests
50+ * @param metadata the metadata to include when creating the bag. Payload-Oxum and Bagging-Date will be overwritten
51+ *
4352 * @throws NoSuchAlgorithmException if {@link MessageDigest} can't find the algorithm
4453 * @throws IOException if there is a problem writing or moving file(s)
54+ *
4555 * @return a {@link Bag} object representing the newly created bagit bag
4656 */
47- public static Bag bagInPlace (final Path root , final Collection <SupportedAlgorithm > algorithms , final boolean includeHidden ) throws NoSuchAlgorithmException , IOException {
57+ @ SuppressWarnings ("CPD-START" )
58+ public static Bag bagInPlace (final Path root , final Collection <SupportedAlgorithm > algorithms , final boolean includeHidden , final Metadata metadata ) throws NoSuchAlgorithmException , IOException {
4859 final Bag bag = new Bag (new Version (0 , 97 ));
4960 bag .setRootDir (root );
5061 logger .info (messages .getString ("creating_bag" ), bag .getVersion (), root );
5162
5263 final Path dataDir = root .resolve ("data" );
64+ moveFilesToDataDirectory (root , dataDir , includeHidden );
65+
66+ BagitFileWriter .writeBagitFile (bag .getVersion (), bag .getFileEncoding (), root );
67+
68+ createManifests (root , dataDir , bag , algorithms , includeHidden );
69+
70+ createMetadataFile (root , dataDir , bag , metadata );
71+
72+ return bag ;
73+ }
74+
75+ /**
76+ * Creates a bag in place for version 0.97.
77+ * This method moves and creates files, thus if an error is thrown during operation it may leave the filesystem
78+ * in an unknown state of transition. Thus this is <b>not thread safe</b>
79+ *
80+ * @param root the directory that will become the base of the bag and where to start searching for content
81+ * @param algorithms an collection of {@link SupportedAlgorithm} implementations
82+ * @param includeHidden to include hidden files when generating the bagit files, like the manifests
83+ *
84+ * @throws NoSuchAlgorithmException if {@link MessageDigest} can't find the algorithm
85+ * @throws IOException if there is a problem writing or moving file(s)
86+ *
87+ * @return a {@link Bag} object representing the newly created bagit bag
88+ */
89+ public static Bag bagInPlace (final Path root , final Collection <SupportedAlgorithm > algorithms , final boolean includeHidden ) throws NoSuchAlgorithmException , IOException {
90+ return bagInPlace (root , algorithms , includeHidden , new Metadata ());
91+ }
92+
93+ private static void moveFilesToDataDirectory (final Path root , final Path dataDir , final boolean includeHidden ) throws IOException {
5394 Files .createDirectory (dataDir );
5495 try (final DirectoryStream <Path > directoryStream = Files .newDirectoryStream (root )){
5596 for (final Path path : directoryStream ){
@@ -58,14 +99,15 @@ public static Bag bagInPlace(final Path root, final Collection<SupportedAlgorith
5899 }
59100 }
60101 }
61-
102+ }
103+
104+ private static void createManifests (final Path root , final Path dataDir , final Bag bag , final Collection <SupportedAlgorithm > algorithms , final boolean includeHidden ) throws IOException , NoSuchAlgorithmException {
62105 logger .info (messages .getString ("creating_payload_manifests" ));
63106 final Map <Manifest , MessageDigest > payloadFilesMap = Hasher .createManifestToMessageDigestMap (algorithms );
64107 final CreatePayloadManifestsVistor payloadVisitor = new CreatePayloadManifestsVistor (payloadFilesMap , includeHidden );
65108 Files .walkFileTree (dataDir , payloadVisitor );
66109
67110 bag .getPayLoadManifests ().addAll (payloadFilesMap .keySet ());
68- BagitFileWriter .writeBagitFile (bag .getVersion (), bag .getFileEncoding (), root );
69111 ManifestWriter .writePayloadManifests (bag .getPayLoadManifests (), root , root , bag .getFileEncoding ());
70112
71113 logger .info (messages .getString ("creating_tag_manifests" ));
@@ -75,11 +117,22 @@ public static Bag bagInPlace(final Path root, final Collection<SupportedAlgorith
75117
76118 bag .getTagManifests ().addAll (tagFilesMap .keySet ());
77119 ManifestWriter .writeTagManifests (bag .getTagManifests (), root , root , bag .getFileEncoding ());
120+ }
121+
122+ private static void createMetadataFile (final Path root , final Path dataDir , final Bag bag , final Metadata metadata ) throws IOException {
123+ bag .setMetadata (metadata );
78124
79- return bag ;
125+ logger .debug (messages .getString ("calculating_payload_oxum" ), dataDir );
126+ final String payloadOxum = PathUtils .generatePayloadOxum (PathUtils .getDataDir (bag .getVersion (), root ));
127+ bag .getMetadata ().upsertPayloadOxum (payloadOxum );
128+
129+ bag .getMetadata ().remove ("Bagging-Date" );
130+ bag .getMetadata ().add ("Bagging-Date" , new SimpleDateFormat (DATE_FORMAT , Locale .ENGLISH ).format (new Date ()));
131+
132+ logger .info (messages .getString ("creating_metadata_file" ));
133+ MetadataWriter .writeBagMetadata (bag .getMetadata (), bag .getVersion (), root , bag .getFileEncoding ());
80134 }
81135
82- @ SuppressWarnings ("CPD-END" )
83136 /**
84137 * Creates a basic(only required elements) .bagit bag in place.
85138 * This creates files and directories, thus if an error is thrown during operation it may leave the filesystem
@@ -88,11 +141,14 @@ public static Bag bagInPlace(final Path root, final Collection<SupportedAlgorith
88141 * @param root the directory that will become the base of the bag and where to start searching for content
89142 * @param algorithms an collection of {@link SupportedAlgorithm} implementations
90143 * @param includeHidden to include hidden files when generating the bagit files, like the manifests
91- * @return a {@link Bag} object representing the newly created bagit bag
144+ *
92145 * @throws NoSuchAlgorithmException if {@link MessageDigest} can't find the algorithm
93146 * @throws IOException if there is a problem writing files or .bagit directory
147+ *
148+ * @return a {@link Bag} object representing the newly created bagit bag
94149 */
95150 @ Incubating
151+ @ SuppressWarnings ("CPD-END" )
96152 public static Bag createDotBagit (final Path root , final Collection <SupportedAlgorithm > algorithms , final boolean includeHidden ) throws NoSuchAlgorithmException , IOException {
97153 final Bag bag = new Bag (new Version (2 , 0 ));
98154 bag .setRootDir (root );
@@ -120,5 +176,4 @@ public static Bag createDotBagit(final Path root, final Collection<SupportedAlgo
120176
121177 return bag ;
122178 }
123-
124- }
179+ }
0 commit comments