Skip to content

Commit

Permalink
refactor to use the LOC writers; unit test the BagInfo subclass
Browse files Browse the repository at this point in the history
  • Loading branch information
barmintor committed Apr 11, 2013
1 parent 40628f1 commit 9e3a294
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 45 deletions.
67 changes: 23 additions & 44 deletions src/main/java/org/fcrepo/federation/bagit/BagInfo.java
Expand Up @@ -10,7 +10,9 @@
import java.io.PrintWriter;
import java.util.Map;

import org.fcrepo.federation.bagit.functions.GetBagInfoTxtWriter;
import org.modeshape.jcr.value.Name;
import org.modeshape.jcr.value.NameFactory;
import org.modeshape.jcr.value.Property;
import org.modeshape.jcr.value.PropertyFactory;
import org.modeshape.jcr.value.StringFactory;
Expand All @@ -20,7 +22,9 @@

import gov.loc.repository.bagit.Bag.BagConstants;
import gov.loc.repository.bagit.BagFile;
import gov.loc.repository.bagit.BagInfoTxtWriter;
import gov.loc.repository.bagit.impl.BagInfoTxtImpl;
import gov.loc.repository.bagit.impl.BagInfoTxtWriterImpl;
import gov.loc.repository.bagit.utilities.namevalue.NameValueReader.NameValue;

public class BagInfo extends BagInfoTxtImpl {
Expand All @@ -32,43 +36,40 @@ public class BagInfo extends BagInfoTxtImpl {

private PropertyFactory m_propertyFactory;

private ValueFactories m_valueFactory;

private StringFactory m_stringFactory;

private NameFactory m_nameFactory;

private static final long serialVersionUID = 1L;

static GetBagInfoTxtWriter getBagInfoTxtWriter = new GetBagInfoTxtWriter();

public BagInfo(String bagID, BagFile bagFile, PropertyFactory propertyFactory, ValueFactories valueFactory, BagConstants bagConstants) {
public BagInfo(
String bagID, BagFile bagFile, PropertyFactory propertyFactory,
NameFactory nameFactory, BagConstants bagConstants) {
super(bagFile, bagConstants);
this.bagID = bagID;
m_propertyFactory = propertyFactory;
m_valueFactory = valueFactory;
m_stringFactory = valueFactory.getStringFactory();
}

private OutputStream getOutputStream() throws FileNotFoundException {
return new FileOutputStream(new File(this.getFilepath()));
m_nameFactory = nameFactory;
}

/**
* Stores this bag-info.txt into its bag.
*/
public void save() throws IOException {
try (PrintWriter out = new PrintWriter(getOutputStream())) {
;
try (BagInfoTxtWriter writer = getBagInfoTxtWriter.apply(this.getFilepath())) {
Map<Name, Property> properties = getProperties();
for (Map.Entry<Name, Property> entry : properties.entrySet()) {
Name name = entry.getKey();
Property prop = entry.getValue();
String line =
m_stringFactory.create(name) + ": " +
m_stringFactory.create(prop);
out.println(wrapLine(line));
for (Property jcrProp : properties.values()) {
NameValue prop = toBagitProperty(jcrProp);
writer.write(prop.getName(), prop.getValue());
}
}
}

public boolean delete() throws IOException {
int len = getProperties().size();
for (String key: this.keySet()) {
this.removeAllList(key);
}
setProperties(BagItExtraPropertiesStore.EMPTY);
return len > 0;
}
Expand All @@ -78,7 +79,7 @@ private Property makeProperty(Name name, String value) {
}

private Name toPropertyName(NameValue bagitProperty) {
return m_valueFactory.getNameFactory().create("info:fedora/bagit/", bagitProperty.getName().replace('-', '.'));
return m_nameFactory.create("info:fedora/bagit/", bagitProperty.getName().replace('-', '.'));
}

private Property toJcrProperty(NameValue bagitProperty) {
Expand All @@ -103,33 +104,11 @@ public Map<Name, Property> getProperties() {
}

public void setProperties(Map<Name, Property> properties) {
for(Entry<Name, Property> entry: properties.entrySet()) {
NameValue bagitProperty = toBagitProperty(entry.getValue());
for(Property entry: properties.values()) {
NameValue bagitProperty = toBagitProperty(entry);
this.removeAllList(bagitProperty.getName());
this.putList(bagitProperty);
}
}

private static String wrapLine(String value) {
if (value == null || value.length() < 79) {
return value;
}
StringBuffer wrapped = new StringBuffer();
String[] words = value.split(" ");
StringBuffer line = new StringBuffer(words[0]);
for (int i = 1; i < words.length; i++) {
if (words[i].length() + line.length() < 79) {
line.append(" " + words[i]);
} else {
wrapped.append(line.toString() + "\n");
line.setLength(0);
line.append(" " + words[i]);
}
}
if (line.length() > 0) {
wrapped.append(line.toString());
}
return wrapped.toString();
}

}
22 changes: 22 additions & 0 deletions src/main/java/org/fcrepo/federation/bagit/BagInfoTxtWriter.java
@@ -0,0 +1,22 @@
package org.fcrepo.federation.bagit;

import java.io.Closeable;
import java.io.OutputStream;

import gov.loc.repository.bagit.impl.BagInfoTxtWriterImpl;
/**
* Just a proxy to implement Closeable
* @author ba2213
*
*/
public class BagInfoTxtWriter extends BagInfoTxtWriterImpl implements Closeable {

public BagInfoTxtWriter(OutputStream out, String encoding) {
super(out, encoding);
}

public BagInfoTxtWriter(OutputStream out, String encoding, int lineLength, int indent) {
super(out, encoding, lineLength, indent);
}

}
Expand Up @@ -362,7 +362,10 @@ protected BagInfo getBagInfo(String id) {
File bagInfoFile = bagInfoFileFor(id);
if (bagInfoFile == null) return null;
// really need to get the version from bagit.txt, but start with hard-coding
BagInfo result = new BagInfo(id, new FileBagFile(bagInfoFile.getAbsolutePath(), bagInfoFile), getPropertyFactory(), getValueFactories(), new BagConstantsImpl());
ValueFactories vf = getValueFactories();
BagInfo result =
new BagInfo(id, new FileBagFile(bagInfoFile.getAbsolutePath(), bagInfoFile),
getPropertyFactory(), vf.getNameFactory(), new BagConstantsImpl());
return result;
}
}
@@ -0,0 +1,22 @@
package org.fcrepo.federation.bagit.functions;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import org.fcrepo.federation.bagit.BagInfoTxtWriter;

import com.google.common.base.Function;

public class GetBagInfoTxtWriter implements Function<String, gov.loc.repository.bagit.BagInfoTxtWriter> {

@Override
public BagInfoTxtWriter apply(String input) {
try {
return new BagInfoTxtWriter(new FileOutputStream(new File(input)), "UTF-8", 79, 0); // 79 char length, 0 indent
} catch (FileNotFoundException e) {
throw new IllegalStateException("Could not open BagInfo writer at " + input, e);
}
}

}
115 changes: 115 additions & 0 deletions src/test/java/org/fcrepo/federation/bagit/BagInfoTest.java
@@ -0,0 +1,115 @@
package org.fcrepo.federation.bagit;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;

import org.fcrepo.federation.bagit.functions.GetBagInfoTxtWriter;
import org.junit.Before;
import org.junit.Test;
import org.modeshape.jcr.value.Name;
import org.modeshape.jcr.value.NameFactory;
import org.modeshape.jcr.value.Property;
import org.modeshape.jcr.value.PropertyFactory;
import org.modeshape.jcr.value.StringFactory;

import gov.loc.repository.bagit.Bag.BagConstants;
import gov.loc.repository.bagit.BagFile;

public class BagInfoTest {

private BagFile mockBF;
private PropertyFactory mockPF;
private NameFactory mockNF;
private BagConstants mockBC;
private GetBagInfoTxtWriter mockWriterFunc;
private BagInfo testObj;

@Before
public void setUp() throws IOException {
mockBF = mock(BagFile.class);
ByteArrayInputStream bytes = new ByteArrayInputStream(
"Bag-Count: 1 of 1".getBytes("UTF-8"));
when(mockBF.newInputStream()).thenReturn(bytes);
mockPF = mock(PropertyFactory.class);
mockNF = mock(NameFactory.class);
mockBC = mock(BagConstants.class);
when(mockBC.getBagInfoTxt()).thenReturn("bag-info.txt");
when(mockBC.getBagEncoding()).thenReturn("UTF-8");
mockWriterFunc = mock(GetBagInfoTxtWriter.class);
BagInfo.getBagInfoTxtWriter = mockWriterFunc;
testObj = new BagInfo("/foo", mockBF, mockPF, mockNF, mockBC);
}

// Public API test

@Test
public void testSave() throws IOException {
BagInfoTxtWriter mockWriter = mock(BagInfoTxtWriter.class);
when(mockWriterFunc.apply(any(String.class))).thenReturn(mockWriter);
Property mockProp = mockProperty("Bag.Count", "2 of 5");
when(mockPF.create(any(Name.class), eq("1 of 1"))).thenReturn(mockProp);
testObj.save();
verify(mockWriter).write("Bag-Count", "2 of 5");
}

@Test
public void testDelete() throws IOException {
//nb: this does not save the changes to the file, that's done in save()
Property mockProp = mockProperty("Bag.Count", "2 of 5");
when(mockPF.create(any(Name.class), eq("1 of 1"))).thenReturn(mockProp);
assertEquals(1, testObj.getProperties().size());
testObj.delete();
assertEquals(0, testObj.getProperties().size());
}

@Test
public void testGetProperties() {
Property mockProp = mockProperty("Bag.Count", "2 of 5");
when(mockPF.create(any(Name.class), eq("1 of 1"))).thenReturn(mockProp);
Map<Name, Property> props = testObj.getProperties();
assertEquals(1, props.size());
Property prop = props.values().iterator().next();
assertEquals("Bag.Count", prop.getName().getLocalName());
assertEquals("2 of 5", prop.getString());
}

@Test
public void testSetProperties() {
Property mockProp = mockProperty("Bag.Count", "1 of 5");
Property[] props = new Property[]{mockProp};
Collection<Property> values = Arrays.asList(props);
Map<Name, Property> mockProps = mock(Map.class);
when(mockProps.values()).thenReturn(values);
testObj.setProperties(mockProps);
assertEquals("1 of 5", testObj.get("Bag-Count"));
mockProp = mockProperty("Bag.Count", "2 of 5");
props = new Property[]{mockProp};
values = Arrays.asList(props);
when(mockProps.values()).thenReturn(values);
testObj.setProperties(mockProps);
assertEquals("2 of 5", testObj.get("Bag-Count"));
}

private static Property mockProperty(String name, String value) {
Property mockProp = mock(Property.class);
Name mockName = mock(Name.class);
when(mockName.getLocalName()).thenReturn(name);
when(mockName.getNamespaceUri()).thenReturn("info:fedora/bagit/");
when(mockProp.getName()).thenReturn(mockName);
when(mockProp.getString()).thenReturn(value);
return mockProp;
}

//TODO Conversion methods that should be tested
}

0 comments on commit 9e3a294

Please sign in to comment.