/* The contents of this file are subject to the license and copyright terms * detailed in the license directory at the root of the source tree (also * available online at http://fedora-commons.org/license/). */ package org.fcrepo.server.storage.translation; import static org.fcrepo.common.Constants.METS; import static org.fcrepo.common.Constants.XLINK; import static org.fcrepo.common.Models.FEDORA_OBJECT_3_0; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.xml.transform.TransformerException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.custommonkey.xmlunit.NamespaceContext; import org.custommonkey.xmlunit.SimpleNamespaceContext; import org.custommonkey.xmlunit.XMLUnit; import org.custommonkey.xmlunit.exceptions.XpathException; import org.fcrepo.server.storage.types.Datastream; import org.fcrepo.server.storage.types.DatastreamManagedContent; import org.fcrepo.server.storage.types.DatastreamReferencedContent; import org.fcrepo.server.storage.types.DatastreamXMLMetadata; import org.fcrepo.server.storage.types.DigitalObject; import org.fcrepo.utilities.TestBase64; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.NodeList; /** * Common unit tests for METSFedoraExt serializers. * * @author Chris Wilper */ public abstract class TestMETSFedoraExtDOSerializer extends TestXMLDOSerializer { protected static final String ROOT_PATH = "/" + METS.METS.qName; protected static final String AMDSEC_PATH = ROOT_PATH + "/" + METS.AMD_SEC.qName; protected static final String SERIALIZED_DS_CONTENT = "<" + METS.prefix + ":FContent> \n " + TestBase64.FOO_STRING_ENCODED + "\n</" + METS.prefix + ":FContent>\n"; TestMETSFedoraExtDOSerializer(DOSerializer serializer) { super(serializer); } //--- // Setup/Teardown //--- @Before @Override public void setUp() throws Exception { super.setUp(); Map<String, String> nsMap = new HashMap<String, String>(); nsMap.put(METS.prefix, METS.uri); NamespaceContext ctx = new SimpleNamespaceContext(nsMap); XMLUnit.setXpathNamespaceContext(ctx); } @Override @After public void tearDown() { XMLUnit.setXpathNamespaceContext(SimpleNamespaceContext.EMPTY_CONTEXT); } //--- // Tests //--- @Test public void testOBJIDAttribute() throws TransformerException, XpathException { DigitalObject obj = createTestObject(FEDORA_OBJECT_3_0); Document xml = doSerializeOrFail(obj); assertXpathExists(ROOT_PATH + "[@OBJID='" + TEST_PID + "']", xml); } //@Test /* FIXME: not sure how this one is supposed to work in METS... */ //public void testCommonFedoraObjectTypes() throws TransformerException { // DigitalObject obj; // Document xml; // obj = createTestObject(DigitalObject.FEDORA_OBJECT); // xml = doSerializeOrFail(obj); // assertXpathExists(ROOT_PATH + "[@TYPE='" + MODEL.DATA_OBJECT.localName // + "']", xml); // obj = createTestObject(DigitalObject.FEDORA_SERVICE_DEPLOYMENT_OBJECT); // xml = doSerializeOrFail(obj); // assertXpathExists(ROOT_PATH + "[@TYPE='" // + MODEL.SERVICE_DEPLOYMENT_OBJECT.localName + "']", xml); // obj = createTestObject(DigitalObject.FEDORA_SERVICE_DEFINITION_OBJECT); // xml = doSerializeOrFail(obj); // assertXpathExists(ROOT_PATH + "[@TYPE='" // + MODEL.SERVICE_DEFINITION_OBJECT.localName + "']", xml); //} @Test public void testNoDatastreams() throws TransformerException, XpathException { DigitalObject obj = createTestObject(FEDORA_OBJECT_3_0); Document xml = doSerializeOrFail(obj); /* rels-ext */ assertXpathEvaluatesTo("1", "count(" + AMDSEC_PATH + ")", xml); } @Test public void testTwoInlineDatastreams() throws TransformerException, XpathException, XPathExpressionException { DigitalObject obj = createTestObject(FEDORA_OBJECT_3_0); final String dsID1 = "DS1"; DatastreamXMLMetadata ds1 = createXDatastream(dsID1); final String dsID2 = "DS2"; DatastreamXMLMetadata ds2 = createXDatastream(dsID2); obj.addDatastreamVersion(ds1, true); obj.addDatastreamVersion(ds2, true); Document xml = doSerializeOrFail(obj); assertXpathEvaluatesTo("3", "count(" + AMDSEC_PATH + ")", xml); } @Test public void testTwoDataStreamsVersion() throws TransformerException, XpathException, XPathExpressionException { DigitalObject obj = createTestObject(FEDORA_OBJECT_3_0); final String dsID1 = "DS1"; final String dsID2 = "DS2"; // hugely randomly generated test data DatastreamManagedContent ds1 = createMDatastream(dsID1, "aölksdiudshfljdsfnalj mdscmjlfjaö nsaölkjfsölkjfsöldkjfaöslfjasödflaöl".getBytes()); DatastreamManagedContent ds2 = createMDatastream(dsID2, "älkfddöslfjsölkfjäaoiam,yjöoicncäaskcäaäöl kf,jvdhfkjh".getBytes()); obj.addDatastreamVersion(ds1, true); obj.addDatastreamVersion(ds2, true); Document xml = doSerializeOrFail(obj); // was unable to do this with assertXpathsNotEqual() method // therefore do the assertions by xpath manually XPath xp = XPathFactory.newInstance().newXPath(); xp.setNamespaceContext(new javax.xml.namespace.NamespaceContext() { @Override public Iterator<String> getPrefixes(String namespaceURI) { // TODO Auto-generated method stub return null; } @Override public String getPrefix(String namespaceURI) { return "METS"; } @Override public String getNamespaceURI(String prefix) { return "http://www.loc.gov/METS/"; } }); XPathExpression expr = xp.compile("//METS:fileGrp[@ID='DS1']/METS:file"); NodeList list = (NodeList) expr.evaluate(xml, XPathConstants.NODESET); String checksum1 = list.item(0).getAttributes().getNamedItem("CHECKSUM").toString(); expr = xp.compile("//METS:fileGrp[@ID='DS2']/METS:file"); list = (NodeList) expr.evaluate(xml, XPathConstants.NODESET); String checkSum2 = list.item(0).getAttributes().getNamedItem("CHECKSUM").toString(); assertFalse(checksum1.equals(checkSum2)); } @Test public void testDatastreamContentSerialization() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Datastream dsc = createMDatastream("DS1", TestBase64.FOO_BYTES); ByteArrayOutputStream bos = new ByteArrayOutputStream(); PrintWriter pw = new PrintWriter(bos); Method testMethod = METSFedoraExtDOSerializer.class.getDeclaredMethod("serializeDatastreamContent", Datastream.class, PrintWriter.class); boolean accessible = testMethod.isAccessible(); if ( !accessible ) testMethod.setAccessible(true); try{ testMethod.invoke(this.m_serializer, dsc, pw); } finally { if ( !accessible ) testMethod.setAccessible( accessible ); } pw.flush(); String actual = bos.toString(); assertEquals(SERIALIZED_DS_CONTENT, actual); } //--- // Instance Helpers //--- protected void doTestXLinkNamespace() throws TransformerException, XpathException { DigitalObject obj = createTestObject(FEDORA_OBJECT_3_0); final String url = "http://example.org/DS1"; DatastreamReferencedContent ds = createRDatastream("DS1", url); obj.addDatastreamVersion(ds, true); Document xml = doSerializeOrFail(obj); String xpath = ROOT_PATH + "/" + METS.FILE_SEC.qName + "/" + METS.FILE_GRP.qName + "[@ID='DATASTREAMS']" + "/" + METS.FILE_GRP.qName + "[@ID='DS1']" + "/" + METS.FILE.qName + "/" + METS.FLOCAT.qName + "[@" + XLINK.HREF.qName + "='" + url + "']"; assertXpathExists(xpath, xml); } }