Skip to content

Commit 474d511

Browse files
committed
fixed error with not being able to repeat metadata
1 parent dbb063f commit 474d511

8 files changed

Lines changed: 104 additions & 52 deletions

File tree

src/main/java/gov/loc/repository/bagit/domain/Bag.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
import java.nio.charset.StandardCharsets;
55
import java.util.ArrayList;
66
import java.util.HashSet;
7-
import java.util.LinkedHashMap;
87
import java.util.List;
98
import java.util.Objects;
109
import java.util.Set;
1110

11+
import javafx.util.Pair;
12+
1213
/**
1314
* The main representation of the bagit spec.
1415
*/
@@ -29,7 +30,7 @@ public class Bag {
2930
private List<FetchItem> itemsToFetch = new ArrayList<>();
3031

3132
//equivalent to the bag-info.txt
32-
private LinkedHashMap<String, String> metadata = new LinkedHashMap<>();
33+
private List<Pair<String, String>> metadata = new ArrayList<>();
3334

3435
//the current location of the bag on the filesystem
3536
private File rootDir;
@@ -79,11 +80,11 @@ public void setItemsToFetch(List<FetchItem> itemsToFetch) {
7980
this.itemsToFetch = itemsToFetch;
8081
}
8182

82-
public LinkedHashMap<String, String> getMetadata() {
83+
public List<Pair<String, String>> getMetadata() {
8384
return metadata;
8485
}
8586

86-
public void setMetadata(LinkedHashMap<String, String> metadata) {
87+
public void setMetadata(List<Pair<String, String>> metadata) {
8788
this.metadata = metadata;
8889
}
8990

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package gov.loc.repository.bagit.domain;
2+
3+
import javafx.util.Pair;
4+
5+
public class KeyValuePair extends Pair<String, String> {
6+
private static final long serialVersionUID = 1L;
7+
8+
public KeyValuePair(String key, String value) {
9+
super(key, value);
10+
}
11+
12+
}

src/main/java/gov/loc/repository/bagit/reader/BagReader.java

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
import java.net.URL;
88
import java.nio.file.Files;
99
import java.nio.file.Paths;
10+
import java.util.ArrayList;
1011
import java.util.HashMap;
11-
import java.util.LinkedHashMap;
12+
import java.util.List;
1213

1314
import org.slf4j.Logger;
1415
import org.slf4j.LoggerFactory;
@@ -20,6 +21,7 @@
2021
import gov.loc.repository.bagit.exceptions.UnparsableVersionException;
2122
import gov.loc.repository.bagit.hash.StandardSupportedAlgorithms;
2223
import gov.loc.repository.bagit.verify.PayloadFileExistsInManifestVistor;
24+
import javafx.util.Pair;
2325

2426
/**
2527
* Responsible for reading a bag from the filesystem.
@@ -67,12 +69,20 @@ public static Bag read(File rootDir) throws IOException, UnparsableVersionExcept
6769
*/
6870
public static Bag readBagitTextFile(File bagitFile, Bag bag) throws IOException, UnparsableVersionException{
6971
logger.debug("Reading bagit.txt file");
70-
LinkedHashMap<String, String> map = readKeyValueMapFromFile(bagitFile, ":");
72+
List<Pair<String, String>> pairs = readKeyValuesFromFile(bagitFile, ":");
7173

72-
String version = map.get("BagIt-Version");
73-
logger.debug("BagIt-Version is [{}]", version);
74-
String encoding = map.get("Tag-File-Character-Encoding");
75-
logger.debug("Tag-File-Character-Encoding is [{}]", encoding);
74+
String version = "";
75+
String encoding = "";
76+
for(Pair<String, String> pair : pairs){
77+
if("BagIt-Version".equals(pair.getKey())){
78+
version = pair.getValue();
79+
logger.debug("BagIt-Version is [{}]", version);
80+
}
81+
if("Tag-File-Character-Encoding".equals(pair.getKey())){
82+
encoding = pair.getValue();
83+
logger.debug("Tag-File-Character-Encoding is [{}]", encoding);
84+
}
85+
}
7686

7787
Bag newBag = new Bag(bag);
7888
newBag.setVersion(parseVersion(version));
@@ -178,17 +188,17 @@ protected static HashMap<File, String> readChecksumFileMap(File manifestFile, Fi
178188
public static Bag readBagMetadata(File rootDir, Bag bag) throws IOException{
179189
logger.info("Attempting to read bag metadata file");
180190
Bag newBag = new Bag(bag);
181-
LinkedHashMap<String, String> metadata = new LinkedHashMap<>();
191+
List<Pair<String, String>> metadata = new ArrayList<>();
182192

183193
File bagInfoFile = new File(rootDir, "bag-info.txt");
184194
if(bagInfoFile.exists()){
185195
logger.debug("Found [{}] file", bagInfoFile);
186-
metadata = readKeyValueMapFromFile(bagInfoFile, ":");
196+
metadata = readKeyValuesFromFile(bagInfoFile, ":");
187197
}
188198
File packageInfoFile = new File(rootDir, "package-info.txt"); //onlu exists in versions 0.93 - 0.95
189199
if(packageInfoFile.exists()){
190200
logger.debug("Found [{}] file", packageInfoFile);
191-
metadata = readKeyValueMapFromFile(packageInfoFile, ":");
201+
metadata = readKeyValuesFromFile(packageInfoFile, ":");
192202
}
193203

194204
newBag.setMetadata(metadata);
@@ -225,28 +235,31 @@ public static Bag readFetch(File fetchFile, Bag bag) throws IOException{
225235
return newBag;
226236
}
227237

228-
protected static LinkedHashMap<String, String> readKeyValueMapFromFile(File file, String splitRegex) throws IOException{
229-
LinkedHashMap<String, String> map = new LinkedHashMap<>();
238+
protected static List<Pair<String, String>> readKeyValuesFromFile(File file, String splitRegex) throws IOException{
239+
List<Pair<String, String>> keyValues = new ArrayList<>();
230240
BufferedReader br = Files.newBufferedReader(Paths.get(file.toURI()));
231-
String lastEnteredKey = "";
232241

233242
String line = br.readLine();
234243
while(line != null){
235244
if(line.matches("^\\s+.*")){
236-
logger.debug("Found an indented line - merging it to key [{}]", lastEnteredKey);
237-
map.merge(lastEnteredKey, System.lineSeparator() + line, String::concat);
245+
246+
Pair<String, String> oldKeyValue = keyValues.remove(keyValues.size() -1);
247+
Pair<String, String> newKeyValue = new Pair<String, String>(oldKeyValue.getKey(), oldKeyValue.getValue() + System.lineSeparator() +line);
248+
keyValues.add(newKeyValue);
249+
250+
logger.debug("Found an indented line - merging it with key [{}]", oldKeyValue.getKey());
238251
}
239252
else{
240253
String[] parts = line.split(splitRegex);
241-
lastEnteredKey = parts[0].trim();
254+
String key = parts[0].trim();
242255
String value = parts[1].trim();
243-
logger.debug("Found key [{}] value [{}] in file [{}] using regex [{}]", lastEnteredKey, value, file, splitRegex);
244-
map.put(lastEnteredKey, value);
256+
logger.debug("Found key [{}] value [{}] in file [{}] using regex [{}]", key, value, file, splitRegex);
257+
keyValues.add(new Pair<String, String>(key, value));
245258
}
246259

247260
line = br.readLine();
248261
}
249262

250-
return map;
263+
return keyValues;
251264
}
252265
}

src/main/java/gov/loc/repository/bagit/verify/BagVerifier.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import gov.loc.repository.bagit.reader.BagReader;
3434
import gov.loc.repository.bagit.tasks.CheckIfFileExistsTask;
3535
import gov.loc.repository.bagit.tasks.CheckManifestHashsTask;
36+
import javafx.util.Pair;
3637

3738
/**
3839
* Responsible for verifying if a bag is valid, complete
@@ -50,11 +51,20 @@ public class BagVerifier {
5051
* @return true if the bag can be quickly verified
5152
*/
5253
public static boolean canQuickVerify(Bag bag){
53-
String payloadOxum = bag.getMetadata().get("Payload-Oxum");
54+
String payloadOxum = getPayloadOxum(bag);
5455
logger.debug("Found payload-oxum [{}] for bag [{}]", payloadOxum, bag.getRootDir());
5556
return payloadOxum != null && payloadOxum.matches(PAYLOAD_OXUM_REGEX) && bag.getItemsToFetch().size() == 0;
5657
}
5758

59+
protected static String getPayloadOxum(Bag bag){
60+
for(Pair<String,String> keyValue : bag.getMetadata()){
61+
if("Payload-Oxum".equals(keyValue.getKey())){
62+
return keyValue.getValue();
63+
}
64+
}
65+
return null;
66+
}
67+
5868
/**
5969
*
6070
* @param bag the bag to verify by payload-oxum
@@ -66,7 +76,7 @@ public static boolean canQuickVerify(Bag bag){
6676
* To check, run {@link BagVerifier#canQuickVerify}
6777
*/
6878
public static void quicklyVerify(Bag bag, boolean ignoreHiddenFiles) throws IOException, InvalidPayloadOxumException{
69-
String payloadOxum = bag.getMetadata().get("Payload-Oxum");
79+
String payloadOxum = getPayloadOxum(bag);
7080
if(payloadOxum == null || !payloadOxum.matches(PAYLOAD_OXUM_REGEX)){
7181
throw new PayloadOxumDoesNotExistException("Payload-Oxum does not exist in bag.");
7282
}

src/main/java/gov/loc/repository/bagit/writer/BagWriter.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import java.nio.file.Paths;
1010
import java.nio.file.StandardCopyOption;
1111
import java.nio.file.StandardOpenOption;
12-
import java.util.LinkedHashMap;
1312
import java.util.List;
1413
import java.util.Map.Entry;
1514
import java.util.Set;
@@ -22,6 +21,7 @@
2221
import gov.loc.repository.bagit.domain.Manifest;
2322
import gov.loc.repository.bagit.domain.Version;
2423
import gov.loc.repository.bagit.verify.BagVerifier;
24+
import javafx.util.Pair;
2525

2626
/**
2727
* responsible for writing out a bag.
@@ -166,11 +166,11 @@ protected static void writeManifests(Set<Manifest> manifests, File outputDir, St
166166
* @param charsetName the name of the encoding for the file
167167
* @throws IOException if there was a problem writing a file
168168
*/
169-
public static void writeBagitInfoFile(LinkedHashMap<String, String> metadata, File outputDir, String charsetName) throws IOException{
169+
public static void writeBagitInfoFile(List<Pair<String, String>> metadata, File outputDir, String charsetName) throws IOException{
170170
logger.debug("Writing bag-info.txt to [{}]", outputDir);
171171
Path outputPath = Paths.get(outputDir.getPath(), "bag-info.txt");
172172

173-
for(Entry<String, String> entry : metadata.entrySet()){
173+
for(Pair<String, String> entry : metadata){
174174
String line = entry.getKey() + " : " + entry.getValue() + System.lineSeparator();
175175
logger.debug("Writing [{}] to [{}]", line, outputPath);
176176
Files.write(outputPath, line.getBytes(Charset.forName(charsetName)),

src/test/java/gov/loc/repository/bagit/reader/BagReaderTest.java

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
import java.net.MalformedURLException;
55
import java.net.URL;
66
import java.nio.charset.StandardCharsets;
7+
import java.util.ArrayList;
78
import java.util.Arrays;
8-
import java.util.LinkedHashMap;
99
import java.util.List;
1010

1111
import org.junit.Assert;
@@ -17,6 +17,7 @@
1717
import gov.loc.repository.bagit.domain.Manifest;
1818
import gov.loc.repository.bagit.domain.Version;
1919
import gov.loc.repository.bagit.exceptions.UnparsableVersionException;
20+
import javafx.util.Pair;
2021

2122
public class BagReaderTest extends Assert{
2223
private List<URL> urls;
@@ -97,23 +98,35 @@ public void testReadVersion0_93() throws Exception{
9798
File rootDir = new File(getClass().getClassLoader().getResource("bags/v0_93/bag").getFile());
9899
Bag bag = BagReader.read(rootDir);
99100
assertEquals(new Version(0, 93), bag.getVersion());
100-
assertEquals("25.5", bag.getMetadata().get("Payload-Oxum"));
101+
for(Pair<String, String> keyValue : bag.getMetadata()){
102+
if("Payload-Oxum".equals(keyValue.getKey())){
103+
assertEquals("25.5", keyValue.getValue());
104+
}
105+
}
101106
}
102107

103108
@Test
104109
public void testReadVersion0_94() throws Exception{
105110
File rootDir = new File(getClass().getClassLoader().getResource("bags/v0_94/bag").getFile());
106111
Bag bag = BagReader.read(rootDir);
107112
assertEquals(new Version(0, 94), bag.getVersion());
108-
assertEquals("25.5", bag.getMetadata().get("Payload-Oxum"));
113+
for(Pair<String, String> keyValue : bag.getMetadata()){
114+
if("Payload-Oxum".equals(keyValue.getKey())){
115+
assertEquals("25.5", keyValue.getValue());
116+
}
117+
}
109118
}
110119

111120
@Test
112121
public void testReadVersion0_95() throws Exception{
113122
File rootDir = new File(getClass().getClassLoader().getResource("bags/v0_95/bag").getFile());
114123
Bag bag = BagReader.read(rootDir);
115124
assertEquals(new Version(0, 95), bag.getVersion());
116-
assertEquals("260 GB", bag.getMetadata().get("Package-Size"));
125+
for(Pair<String, String> keyValue : bag.getMetadata()){
126+
if("Package-Size".equals(keyValue.getKey())){
127+
assertEquals("260 GB", keyValue.getValue());
128+
}
129+
}
117130
}
118131

119132
@Test
@@ -148,22 +161,23 @@ public void testReadFetchWithSizeSpecified() throws Exception{
148161

149162
@Test
150163
public void testReadBagMetadata() throws Exception{
151-
LinkedHashMap<String, String> expectedValues = new LinkedHashMap<>();
152-
expectedValues.put("Source-Organization", "Spengler University");
153-
expectedValues.put("Organization-Address", "1400 Elm St., Cupertino, California, 95014");
154-
expectedValues.put("Contact-Name", "Edna Janssen");
155-
expectedValues.put("Contact-Phone", "+1 408-555-1212");
156-
expectedValues.put("Contact-Email", "ej@spengler.edu");
157-
expectedValues.put("External-Description", "Uncompressed greyscale TIFF images from the\n" +
158-
" Yoshimuri papers collection.");
159-
expectedValues.put("Bagging-Date", "2008-01-15");
160-
expectedValues.put("External-Identifier", "spengler_yoshimuri_001");
161-
expectedValues.put("Bag-Size", "260 GB");
162-
expectedValues.put("Bag-Group-Identifier", "spengler_yoshimuri");
163-
expectedValues.put("Bag-Count", "1 of 15");
164-
expectedValues.put("Internal-Sender-Identifier", "/storage/images/yoshimuri");
165-
expectedValues.put("Internal-Sender-Description", "Uncompressed greyscale TIFFs created from\n" +
166-
" microfilm.");
164+
List<Pair<String, String>> expectedValues = new ArrayList<>();
165+
expectedValues.add(new Pair<>("Source-Organization", "Spengler University"));
166+
expectedValues.add(new Pair<>("Organization-Address", "1400 Elm St., Cupertino, California, 95014"));
167+
expectedValues.add(new Pair<>("Contact-Name", "Edna Janssen"));
168+
expectedValues.add(new Pair<>("Contact-Phone", "+1 408-555-1212"));
169+
expectedValues.add(new Pair<>("Contact-Email", "ej@spengler.edu"));
170+
expectedValues.add(new Pair<>("External-Description", "Uncompressed greyscale TIFF images from the\n" +
171+
" Yoshimuri papers collection."));
172+
expectedValues.add(new Pair<>("Bagging-Date", "2008-01-15"));
173+
expectedValues.add(new Pair<>("External-Identifier", "spengler_yoshimuri_001"));
174+
expectedValues.add(new Pair<>("Bag-Size", "260 GB"));
175+
expectedValues.add(new Pair<>("Bag-Group-Identifier", "spengler_yoshimuri"));
176+
expectedValues.add(new Pair<>("Bag-Count", "1 of 15"));
177+
expectedValues.add(new Pair<>("Internal-Sender-Identifier", "/storage/images/yoshimuri"));
178+
expectedValues.add(new Pair<>("Internal-Sender-Description", "Uncompressed greyscale TIFFs created from\n" +
179+
" microfilm."));
180+
expectedValues.add(new Pair<>("Bag-Count", "1 of 15")); //test duplicate
167181

168182
File bagInfoFile = new File(getClass().getClassLoader().getResource("baginfoFiles").getFile());
169183
Bag returnedBag = BagReader.readBagMetadata(bagInfoFile, new Bag());

src/test/java/gov/loc/repository/bagit/writer/BagWriterTest.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
import java.io.IOException;
55
import java.net.URL;
66
import java.nio.charset.StandardCharsets;
7+
import java.util.ArrayList;
78
import java.util.Arrays;
89
import java.util.HashSet;
9-
import java.util.LinkedHashMap;
1010
import java.util.List;
1111
import java.util.Set;
1212

@@ -21,6 +21,7 @@
2121
import gov.loc.repository.bagit.domain.Version;
2222
import gov.loc.repository.bagit.hash.StandardSupportedAlgorithms;
2323
import gov.loc.repository.bagit.reader.BagReader;
24+
import javafx.util.Pair;
2425

2526
public class BagWriterTest extends Assert {
2627
@Rule
@@ -79,10 +80,10 @@ public void testWriteBagitFile() throws Exception{
7980
public void testWriteBagitInfoFile() throws IOException{
8081
File rootDir = folder.newFolder();
8182
File bagInfo = new File(rootDir, "bag-info.txt");
82-
LinkedHashMap<String, String> metadata = new LinkedHashMap<>();
83-
metadata.put("key1", "value1");
84-
metadata.put("key2", "value2");
85-
metadata.put("key3", "value3");
83+
List<Pair<String, String>> metadata = new ArrayList<>();
84+
metadata.add(new Pair<>("key1", "value1"));
85+
metadata.add(new Pair<>("key2", "value2"));
86+
metadata.add(new Pair<>("key3", "value3"));
8687

8788
assertFalse(bagInfo.exists());
8889
BagWriter.writeBagitInfoFile(metadata, rootDir, StandardCharsets.UTF_8.name());

src/test/resources/baginfoFiles/bag-info.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ Bag-Count: 1 of 15
1313
Internal-Sender-Identifier: /storage/images/yoshimuri
1414
Internal-Sender-Description: Uncompressed greyscale TIFFs created from
1515
microfilm.
16+
Bag-Count: 1 of 15

0 commit comments

Comments
 (0)