Skip to content

Commit 0174692

Browse files
committed
Merge pull request #37 from LibraryOfCongress/rewrite_extension
merge Rewrite extension
2 parents a05c795 + 8070d4e commit 0174692

23 files changed

+463
-329
lines changed

README.md

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ The "new" bagit interface is very intuitive, but here are some easy to follow ex
3131
File folder = new File("FolderYouWantToBag");
3232
StandardSupportedAlgorithms algorithm = StandardSupportedAlgorithms.MD5;
3333
boolean includeHiddenFiles = false;
34-
Bag bag = BagCreator.bagInPlace(folder, algorithm, includeHiddenFiles);
34+
BagCreator creator = new BagCreator();
35+
Bag bag = creator.bagInPlace(folder, algorithm, includeHiddenFiles);
3536
```
3637
##### Read an existing bag (version 0.93 and higher)
3738
```java
3839
File rootDir = new File("RootDirectoryOfExistingBag");
39-
Bag bag = BagReader.read(rootDir);
40+
BagReader reader = new BagReader();
41+
Bag bag = reader.read(rootDir);
4042
```
4143
##### Write a Bag object to disk
4244
```java
@@ -46,21 +48,50 @@ BagWriter.write(bag, outputDir); //where bag is a Bag object
4648
##### Verify Complete
4749
```java
4850
boolean ignoreHiddenFiles = true;
49-
BagVerifier.isComplete(bag, ignoreHiddenFiles);
51+
BagVerifier verifier = new BagVerifier();
52+
verifier.isComplete(bag, ignoreHiddenFiles);
5053
```
5154
##### Verify Valid
5255
```java
5356
boolean ignoreHiddenFiles = true;
54-
BagVerifier.isValid(bag, ignoreHiddenFiles);
57+
BagVerifier verifier = new BagVerifier();
58+
verifier.isValid(bag, ignoreHiddenFiles);
5559
```
5660
##### Quickly verify by payload-oxum
5761
```java
5862
boolean ignoreHiddenFiles = true;
63+
BagVerifier verifier = new BagVerifier();
5964

60-
if(BagVerifier.canQuickVerify(bag)){
61-
BagVerifier.quicklyVerify(bag, ignoreHiddenFiles);
65+
if(verifier.canQuickVerify(bag)){
66+
verifier.quicklyVerify(bag, ignoreHiddenFiles);
6267
}
6368
```
69+
##### Add other checksum algorithms
70+
You only need to implement 2 interfaces
71+
```java
72+
public class MyNewSupportedAlgorithm implements SupportedAlgorithm {
73+
@Override
74+
public String getMessageDigestName() {
75+
return "SHA3-256";
76+
}
77+
@Override
78+
public String getBagitName() {
79+
return "sha3256";
80+
}
81+
}
82+
83+
public class MyNewNameMapping implements BagitAlgorithmNameToSupportedAlgorithmMapping {
84+
@Override
85+
public SupportedAlgorithm getMessageDigestName(String bagitAlgorithmName) {
86+
if("sha3256".equals(bagitAlgorithmName)){
87+
return new MyNewSupportedAlgorithm();
88+
}
89+
90+
return StandardSupportedAlgorithms.valueOf(bagitAlgorithmName.toUpperCase());
91+
}
92+
}
93+
```
94+
and then add the implemented BagitAlgorithmNameToSupportedAlgorithmMapping class to your BagReader or bagVerifier object before using their methods
6495

6596
## Developing Bagit-Java
6697
Bagit-Java uses [Gradle](https://gradle.org/) for its build system. Check out the great [documentation](https://docs.gradle.org/current/userguide/userguide_single.html) to learn more.
@@ -80,7 +111,6 @@ Simply run `gradle eclipse` and it will automatically create a eclipse project f
80111
* Further refine reading and writing of bags version 0.93-0.97
81112
* Integrate new proposed specification we are calling "dot bagit"
82113
* Fix bugs/issues reported with new library (on going)
83-
* Add extensions for more than standard supported algorithms
84114

85115
### Support
86116
1. The Digital Curation Google Group (https://groups.google.com/d/forum/digital-curation) is an open discussion list that reaches many of the contributors to and users of this open-source project

build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ repositories {
1919
dependencies {
2020
compile 'org.slf4j:slf4j-api:latest.integration'
2121

22-
testCompile 'junit:junit:4.12', 'org.springframework.boot:spring-boot-starter-logging:1.3.2.RELEASE'
22+
testCompile 'junit:junit:latest.integration',
23+
'org.springframework.boot:spring-boot-starter-logging:latest.integration',
24+
'org.bouncycastle:bcprov-jdk15on:latest.integration'
2325
}
2426

2527
test { //show test output

src/main/java/gov/loc/repository/bagit/creator/AddPayloadToBagManifestVistor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public FileVisitResult visitFile(Path path, BasicFileAttributes attrs)throws IOE
5656
InputStream inputStream = Files.newInputStream(path, StandardOpenOption.READ);
5757
String hash = Hasher.hash(inputStream, messageDigest);
5858
logger.debug("Adding [{}] to manifest with hash [{}]", path, hash);
59-
manifest.getFileToChecksumMap().put(path.toFile(), hash);
59+
manifest.getFileToChecksumMap().put(path, hash);
6060
}
6161

6262
return FileVisitResult.CONTINUE;

src/main/java/gov/loc/repository/bagit/creator/BagCreator.java

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package gov.loc.repository.bagit.creator;
22

3-
import java.io.File;
43
import java.io.IOException;
4+
import java.nio.file.DirectoryStream;
55
import java.nio.file.Files;
66
import java.nio.file.Path;
7-
import java.nio.file.Paths;
87
import java.security.MessageDigest;
98
import java.security.NoSuchAlgorithmException;
109

@@ -37,24 +36,26 @@ public class BagCreator {
3736
* @throws IOException if there is a problem writing or moving file(s)
3837
* @return a {@link Bag} object representing the newly created bagit bag
3938
*/
40-
public static Bag bagInPlace(File root, SupportedAlgorithm algorithm, boolean includeHidden) throws NoSuchAlgorithmException, IOException{
39+
public static Bag bagInPlace(Path root, SupportedAlgorithm algorithm, boolean includeHidden) throws NoSuchAlgorithmException, IOException{
4140
Bag bag = new Bag(new Version(0, 97));
4241
bag.setRootDir(root);
4342
logger.info("Creating a bag with version: [{}] in directory: [{}]", bag.getVersion(), root);
4443

45-
File[] files = root.listFiles();
46-
File dataDir = new File(root, "data");
47-
if(!dataDir.exists() && !dataDir.mkdir()){
48-
throw new IOException("Unable to make " + dataDir);
49-
}
5044

51-
moveFilesToDataDir(files, dataDir);
45+
Path dataDir = root.resolve("data");
46+
Files.createDirectory(dataDir);
47+
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(root);
48+
for(Path path : directoryStream){
49+
if(!path.equals(dataDir) && !Files.isHidden(path) || includeHidden){
50+
Files.move(path, dataDir.resolve(path.getFileName()));
51+
}
52+
}
5253

5354
logger.info("Creating payload manifest");
5455
Manifest manifest = new Manifest(algorithm);
5556
MessageDigest messageDigest = MessageDigest.getInstance(algorithm.getMessageDigestName());
5657
AddPayloadToBagManifestVistor visitor = new AddPayloadToBagManifestVistor(manifest, messageDigest, includeHidden);
57-
Files.walkFileTree(Paths.get(dataDir.toURI()), visitor);
58+
Files.walkFileTree(dataDir, visitor);
5859

5960
bag.getPayLoadManifests().add(manifest);
6061
BagWriter.writeBagitFile(bag.getVersion(), bag.getFileEncoding(), root);
@@ -64,17 +65,6 @@ public static Bag bagInPlace(File root, SupportedAlgorithm algorithm, boolean in
6465
return bag;
6566
}
6667

67-
protected static void moveFilesToDataDir(File[] files, File dataDir) throws IOException{
68-
if(files != null){
69-
logger.info("Moving files to [{}]", dataDir);
70-
for(File file : files){
71-
Path dest = Paths.get(dataDir.getPath(), file.getName());
72-
logger.debug("Moving [{}] to [{}]", file, dest);
73-
Files.move(Paths.get(file.toURI()), dest);
74-
}
75-
}
76-
}
77-
7868
/**
7969
* Creates a basic(only required elements) .bagit bag in place.
8070
* This creates files and directories, thus if an error is thrown during operation it may leave the filesystem
@@ -87,21 +77,19 @@ protected static void moveFilesToDataDir(File[] files, File dataDir) throws IOEx
8777
* @throws IOException if there is a problem writing files or .bagit directory
8878
*/
8979
@Incubating
90-
public static Bag createDotBagit(File root, SupportedAlgorithm algorithm, boolean includeHidden) throws NoSuchAlgorithmException, IOException{
80+
public static Bag createDotBagit(Path root, SupportedAlgorithm algorithm, boolean includeHidden) throws NoSuchAlgorithmException, IOException{
9181
Bag bag = new Bag(new Version(0, 98));
9282
bag.setRootDir(root);
9383
logger.info("Creating a bag with version: [{}] in directory: [{}]", bag.getVersion(), root);
9484

95-
File dotbagitDir = new File(root, ".bagit");
96-
if(!dotbagitDir.mkdir()){
97-
throw new IOException("Was unable to create " + dotbagitDir);
98-
}
85+
Path dotbagitDir = root.resolve(".bagit");
86+
Files.createDirectories(dotbagitDir);
9987

10088
logger.info("Creating payload manifest");
10189
Manifest manifest = new Manifest(algorithm);
10290
MessageDigest messageDigest = MessageDigest.getInstance(algorithm.getMessageDigestName());
10391
AddPayloadToBagManifestVistor visitor = new AddPayloadToBagManifestVistor(manifest, messageDigest, includeHidden);
104-
Files.walkFileTree(Paths.get(root.toURI()), visitor);
92+
Files.walkFileTree(root, visitor);
10593

10694
bag.getPayLoadManifests().add(manifest);
10795
BagWriter.writeBagitFile(bag.getVersion(), bag.getFileEncoding(), dotbagitDir);

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package gov.loc.repository.bagit.domain;
22

3-
import java.io.File;
43
import java.nio.charset.StandardCharsets;
4+
import java.nio.file.Path;
55
import java.util.ArrayList;
66
import java.util.HashSet;
77
import java.util.List;
@@ -33,7 +33,7 @@ public class Bag {
3333
private List<Pair<String, String>> metadata = new ArrayList<>();
3434

3535
//the current location of the bag on the filesystem
36-
private File rootDir;
36+
private Path rootDir;
3737

3838
public Bag(){
3939
}
@@ -142,11 +142,11 @@ public boolean equals(Object obj) {
142142
Objects.equals(this.metadata, other.getMetadata());
143143
}
144144

145-
public File getRootDir() {
145+
public Path getRootDir() {
146146
return rootDir;
147147
}
148148

149-
public void setRootDir(File rootDir) {
149+
public void setRootDir(Path rootDir) {
150150
this.rootDir = rootDir;
151151
}
152152

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
package gov.loc.repository.bagit.domain;
33

4-
import java.io.File;
4+
import java.nio.file.Path;
55
import java.util.HashMap;
66

77
import gov.loc.repository.bagit.hash.SupportedAlgorithm;
@@ -11,17 +11,17 @@
1111
*/
1212
public class Manifest {
1313
private final SupportedAlgorithm algorithm;
14-
private HashMap<File, String> fileToChecksumMap = new HashMap<>();
14+
private HashMap<Path, String> fileToChecksumMap = new HashMap<>();
1515

1616
public Manifest(SupportedAlgorithm algorithm){
1717
this.algorithm = algorithm;
1818
}
1919

20-
public HashMap<File, String> getFileToChecksumMap() {
20+
public HashMap<Path, String> getFileToChecksumMap() {
2121
return fileToChecksumMap;
2222
}
2323

24-
public void setFileToChecksumMap(HashMap<File, String> fileToChecksumMap) {
24+
public void setFileToChecksumMap(HashMap<Path, String> fileToChecksumMap) {
2525
this.fileToChecksumMap = fileToChecksumMap;
2626
}
2727

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package gov.loc.repository.bagit.hash;
2+
3+
/**
4+
* Implement this interface if you need to be able to use other algorithms than the {@link StandardSupportedAlgorithms}
5+
*/
6+
public interface BagitAlgorithmNameToSupportedAlgorithmMapping {
7+
public SupportedAlgorithm getMessageDigestName(String bagitAlgorithmName);
8+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package gov.loc.repository.bagit.hash;
2+
3+
/**
4+
* Provides a mapping between bagit algorithm names and {@link SupportedAlgorithm}
5+
*/
6+
public class StandardBagitAlgorithmNameToSupportedAlgorithmMapping
7+
implements BagitAlgorithmNameToSupportedAlgorithmMapping {
8+
9+
@Override
10+
public SupportedAlgorithm getMessageDigestName(String bagitAlgorithmName) {
11+
return StandardSupportedAlgorithms.valueOf(bagitAlgorithmName.toUpperCase());
12+
}
13+
14+
}

0 commit comments

Comments
 (0)