001/* 002 * Copyright 2015 DuraSpace, Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.fcrepo.http.commons.responses; 017 018import static java.util.stream.Stream.of; 019import static com.google.common.util.concurrent.Futures.addCallback; 020import static com.hp.hpl.jena.datatypes.xsd.XSDDatatype.XSDdateTime; 021import static com.hp.hpl.jena.graph.NodeFactory.createLiteral; 022import static com.hp.hpl.jena.graph.NodeFactory.createURI; 023import static com.hp.hpl.jena.graph.Triple.create; 024import static com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel; 025import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty; 026import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource; 027import static com.hp.hpl.jena.rdf.model.ResourceFactory.createTypedLiteral; 028import static javax.ws.rs.core.MediaType.valueOf; 029import static org.fcrepo.http.commons.domain.RDFMediaType.TURTLE_TYPE; 030import static org.fcrepo.http.commons.responses.RdfStreamStreamingOutput.getValueForObject; 031import static org.junit.Assert.assertEquals; 032import static org.junit.Assert.assertFalse; 033import static org.junit.Assert.assertTrue; 034import static org.mockito.Mockito.mock; 035import static org.mockito.MockitoAnnotations.initMocks; 036import static org.openrdf.model.impl.ValueFactoryImpl.getInstance; 037import static org.openrdf.model.util.Literals.createLiteral; 038import static org.slf4j.LoggerFactory.getLogger; 039 040import java.io.ByteArrayInputStream; 041import java.io.ByteArrayOutputStream; 042import java.io.IOException; 043import java.io.InputStream; 044import java.io.OutputStream; 045import java.util.HashMap; 046import java.util.Map; 047import java.util.stream.Stream; 048 049import javax.jcr.Session; 050import javax.ws.rs.WebApplicationException; 051import javax.ws.rs.core.MediaType; 052 053import com.hp.hpl.jena.rdf.model.RDFNode; 054import org.fcrepo.kernel.api.rdf.DefaultRdfStream; 055import org.fcrepo.kernel.api.RdfStream; 056import org.junit.Before; 057import org.junit.Test; 058import org.mockito.Mock; 059import org.mockito.stubbing.Answer; 060import org.openrdf.model.Value; 061import org.openrdf.model.ValueFactory; 062import org.openrdf.rio.RDFHandlerException; 063import org.slf4j.Logger; 064 065import com.google.common.util.concurrent.FutureCallback; 066import com.hp.hpl.jena.graph.Node; 067import com.hp.hpl.jena.graph.Triple; 068import com.hp.hpl.jena.rdf.model.Model; 069 070/** 071 * <p>RdfStreamStreamingOutputTest class.</p> 072 * 073 * @author ajs6f 074 */ 075public class RdfStreamStreamingOutputTest { 076 077 private RdfStreamStreamingOutput testRdfStreamStreamingOutput; 078 079 private static final Triple triple = create(createURI("info:testSubject"), 080 createURI("info:testPredicate"), createURI("info:testObject")); 081 082 @Mock 083 private Node mockNode; 084 085 private final RdfStream testRdfStream = new DefaultRdfStream(triple.getSubject(), of(triple)); 086 087 private final Map<String, String> testNamespaces = new HashMap<>(); 088 089 @Mock 090 private RdfStream mockRdfStream; 091 092 @Mock 093 private Session mockSession; 094 095 private final MediaType testMediaType = valueOf("application/rdf+xml"); 096 097 private static final ValueFactory vf = getInstance(); 098 099 private static final Logger LOGGER = 100 getLogger(RdfStreamStreamingOutputTest.class); 101 102 @Before 103 public void setUp() { 104 initMocks(this); 105 testRdfStreamStreamingOutput = 106 new RdfStreamStreamingOutput(testRdfStream, testNamespaces, testMediaType); 107 } 108 109 @Test 110 public void testGetValueForObjectWithResource() { 111 final Node resource = createURI("info:test"); 112 final Value result = getValueForObject(resource); 113 assertEquals("Created bad Value!", vf.createURI("info:test"), result); 114 } 115 116 @Test 117 public void testGetValueForObjectWithLiteral() { 118 final Node resource = createLiteral("test"); 119 final Value result = getValueForObject(resource); 120 assertEquals("Created bad Value!", createLiteral(vf, "test"), result); 121 } 122 123 @Test 124 public void testWrite() throws IOException { 125 assertOutputContainsTriple(triple); 126 } 127 128 public void assertOutputContainsTriple(final Triple expected) throws IOException { 129 try (final RdfStream input = new DefaultRdfStream(expected.getSubject(), of(expected)); 130 final ByteArrayOutputStream output = new ByteArrayOutputStream()) { 131 new RdfStreamStreamingOutput(input, testNamespaces, testMediaType).write(output); 132 try ( final InputStream resultStream = new ByteArrayInputStream(output.toByteArray())) { 133 final Model result = createDefaultModel().read(resultStream, null); 134 assertTrue("Didn't find our test triple!", result.contains(result.asStatement(expected))); 135 } 136 } 137 } 138 139 @Test 140 public void testWriteWithNamespace() throws IOException { 141 final Map<String, String> namespaces = new HashMap<>(); 142 namespaces.put("a", "info:a"); 143 try (final RdfStream input = new DefaultRdfStream(triple.getSubject(), of(triple)); 144 final ByteArrayOutputStream output = new ByteArrayOutputStream()) { 145 new RdfStreamStreamingOutput(input, namespaces, TURTLE_TYPE).write(output); 146 final String s = output.toString("UTF-8"); 147 assertTrue(s.contains("@prefix a: <info:a>")); 148 } 149 } 150 151 152 @Test 153 public void testWriteWithXmlnsNamespace() throws IOException { 154 final Map<String, String> namespaces = new HashMap<>(); 155 namespaces.put("xmlns", "info:a"); 156 try (final RdfStream input = new DefaultRdfStream(triple.getSubject(), of(triple)); 157 final ByteArrayOutputStream output = new ByteArrayOutputStream()) { 158 new RdfStreamStreamingOutput(input, namespaces, TURTLE_TYPE).write(output); 159 final String s = output.toString("UTF-8"); 160 assertFalse(s.contains("@prefix xmlns")); 161 } 162 } 163 164 @Test 165 public void testWriteWithTypedObject() throws IOException { 166 assertOutputContainsTriple(create(createURI("info:testSubject"), 167 createURI("info:testPredicate"), 168 createTypedLiteral(0).asNode())); 169 } 170 171 @Test 172 public void testWriteWithBlankSubject() throws IOException { 173 try (final RdfStream input = new DefaultRdfStream(createResource().asNode(), of(create(createResource() 174 .asNode(), createURI("info:testPredicate"), createTypedLiteral(0).asNode()))); 175 final ByteArrayOutputStream output = new ByteArrayOutputStream()) { 176 new RdfStreamStreamingOutput(input, testNamespaces, testMediaType).write(output); 177 try (final InputStream resultStream = new ByteArrayInputStream(output.toByteArray())) { 178 final Model result = createDefaultModel().read(resultStream, null); 179 assertTrue(result.contains(null, createProperty("info:testPredicate"), createTypedLiteral(0))); 180 } 181 } 182 } 183 184 185 @Test 186 public void testWriteWithBlankObject() throws IOException { 187 final Stream<Triple> triples = 188 of(create(createResource().asNode(), createURI("info:testPredicate"), createResource().asNode())); 189 try (final RdfStream input = new DefaultRdfStream(createResource().asNode(), triples); 190 final ByteArrayOutputStream output = new ByteArrayOutputStream()) { 191 new RdfStreamStreamingOutput(input, testNamespaces, testMediaType).write(output); 192 try (final InputStream resultStream = new ByteArrayInputStream(output.toByteArray())) { 193 final Model result = createDefaultModel().read(resultStream, null); 194 assertTrue(result.contains(null, createProperty("info:testPredicate"), (RDFNode) null)); 195 } 196 } 197 } 198 199 @Test 200 public void testWriteWithDatetimeObject() throws IOException { 201 assertOutputContainsTriple(create(createURI("info:testSubject"), 202 createURI("info:testPredicate"), createLiteral("2014-01-01T01:02:03Z", XSDdateTime))); 203 } 204 205 @Test 206 public void testWriteWithLanguageLiteral() throws IOException { 207 assertOutputContainsTriple(create(createURI("info:testSubject"), 208 createURI("info:testPredicate"), 209 createLiteral("french string", "fr"))); 210 } 211 212 @Test(expected = WebApplicationException.class) 213 public void testWriteWithException() throws IOException { 214 215 final FutureCallback<Void> callback = new FutureCallback<Void>() { 216 217 @Override 218 public void onSuccess(final Void v) { 219 throw new AssertionError("Should never happen!"); 220 } 221 222 @Override 223 public void onFailure(final Throwable e) { 224 LOGGER.debug("Got exception:", e); 225 assertTrue("Got wrong kind of exception!", e instanceof RDFHandlerException); 226 } 227 }; 228 addCallback(testRdfStreamStreamingOutput, callback); 229 try (final OutputStream mockOutputStream = mock(OutputStream.class, (Answer<Object>) invocation -> { 230 throw new IOException("Expected."); 231 })) { 232 testRdfStreamStreamingOutput.write(mockOutputStream); 233 } 234 } 235}