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 com.google.common.util.concurrent.Futures.addCallback;
019import static com.hp.hpl.jena.graph.NodeFactory.createURI;
020import static com.hp.hpl.jena.graph.Triple.create;
021import static com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel;
022import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
023import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
024import static com.hp.hpl.jena.rdf.model.ResourceFactory.createTypedLiteral;
025import static javax.ws.rs.core.MediaType.valueOf;
026import static org.fcrepo.http.commons.responses.RdfStreamStreamingOutput.getValueForObject;
027import static org.junit.Assert.assertEquals;
028import static org.junit.Assert.assertFalse;
029import static org.junit.Assert.assertTrue;
030import static org.mockito.Mockito.mock;
031import static org.mockito.MockitoAnnotations.initMocks;
032import static org.openrdf.model.impl.ValueFactoryImpl.getInstance;
033import static org.openrdf.model.util.Literals.createLiteral;
034import static org.slf4j.LoggerFactory.getLogger;
035
036import java.io.ByteArrayInputStream;
037import java.io.ByteArrayOutputStream;
038import java.io.IOException;
039import java.io.InputStream;
040import java.io.OutputStream;
041
042import javax.ws.rs.WebApplicationException;
043import javax.ws.rs.core.MediaType;
044
045import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
046import com.hp.hpl.jena.rdf.model.RDFNode;
047import org.fcrepo.http.commons.domain.RDFMediaType;
048import org.fcrepo.kernel.api.utils.iterators.RdfStream;
049import org.junit.Before;
050import org.junit.Test;
051import org.mockito.Mock;
052import org.mockito.invocation.InvocationOnMock;
053import org.mockito.stubbing.Answer;
054import org.openrdf.model.Value;
055import org.openrdf.model.ValueFactory;
056import org.openrdf.rio.RDFHandlerException;
057import org.slf4j.Logger;
058
059import com.google.common.util.concurrent.FutureCallback;
060import com.hp.hpl.jena.graph.Node;
061import com.hp.hpl.jena.graph.NodeFactory;
062import com.hp.hpl.jena.graph.Triple;
063import com.hp.hpl.jena.rdf.model.Model;
064
065/**
066 * <p>RdfStreamStreamingOutputTest class.</p>
067 *
068 * @author ajs6f
069 */
070public class RdfStreamStreamingOutputTest {
071
072    private RdfStreamStreamingOutput testRdfStreamStreamingOutput;
073
074    private static final Triple triple = create(createURI("info:testSubject"),
075            createURI("info:testPredicate"), createURI("info:testObject"));
076
077    @Mock
078    private Node mockNode;
079
080    private final RdfStream testRdfStream = new RdfStream(triple);
081
082    @Mock
083    private RdfStream mockRdfStream;
084
085    private final MediaType testMediaType = valueOf("application/rdf+xml");
086
087    private static final ValueFactory vf = getInstance();
088
089    private static final Logger LOGGER =
090            getLogger(RdfStreamStreamingOutputTest.class);
091
092    @Before
093    public void setUp() {
094        initMocks(this);
095        testRdfStreamStreamingOutput =
096            new RdfStreamStreamingOutput(testRdfStream, testMediaType);
097    }
098
099    @Test
100    public void testGetValueForObjectWithResource() {
101        final Node resource = createURI("info:test");
102        final Value result = getValueForObject(resource);
103        assertEquals("Created bad Value!", vf.createURI("info:test"), result);
104    }
105
106    @Test
107    public void testGetValueForObjectWithLiteral() {
108        final Node resource = NodeFactory.createLiteral("test");
109        final Value result = getValueForObject(resource);
110        assertEquals("Created bad Value!", createLiteral(vf, "test"), result);
111    }
112
113    @Test
114    public void testWrite() throws IOException {
115        assertOutputContainsTriple(triple);
116    }
117
118    public void assertOutputContainsTriple(final Triple expected) throws IOException {
119        final RdfStream input = new RdfStream(expected);
120        try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) {
121            new RdfStreamStreamingOutput(input, testMediaType).write(output);
122            try (
123                final InputStream resultStream =
124                    new ByteArrayInputStream(output.toByteArray())) {
125                final Model result =
126                    createDefaultModel().read(resultStream, null);
127                assertTrue("Didn't find our test triple!", result
128                        .contains(result.asStatement(expected)));
129            }
130        }
131    }
132
133    @Test
134    public void testWriteWithNamespace() throws IOException {
135        final RdfStream input = new RdfStream().namespace("a", "info:a");
136        try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) {
137            new RdfStreamStreamingOutput(input, RDFMediaType.TURTLE_TYPE).write(output);
138            final String s = output.toString("UTF-8");
139            assertTrue(s.contains("@prefix a: <info:a>"));
140        }
141    }
142
143
144    @Test
145    public void testWriteWithXmlnsNamespace() throws IOException {
146        final RdfStream input = new RdfStream().namespace("xmlns", "info:a");
147        try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) {
148            new RdfStreamStreamingOutput(input, RDFMediaType.TURTLE_TYPE).write(output);
149            final String s = output.toString("UTF-8");
150            assertFalse(s.contains("@prefix xmlns"));
151        }
152    }
153
154    @Test
155    public void testWriteWithTypedObject() throws IOException {
156        assertOutputContainsTriple(create(createURI("info:testSubject"),
157                createURI("info:testPredicate"),
158                createTypedLiteral(0).asNode()));
159    }
160
161    @Test
162    public void testWriteWithBlankSubject() throws IOException {
163
164        final RdfStream input = new RdfStream(create(createResource().asNode(),
165                createURI("info:testPredicate"),
166                createTypedLiteral(0).asNode()));
167        try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) {
168            new RdfStreamStreamingOutput(input, testMediaType).write(output);
169
170            try (final InputStream resultStream = new ByteArrayInputStream(output.toByteArray())) {
171                final Model result = createDefaultModel().read(resultStream, null);
172                assertTrue(result.contains(null, createProperty("info:testPredicate"), createTypedLiteral(0)));
173            }
174        }
175
176    }
177
178
179    @Test
180    public void testWriteWithBlankObject() throws IOException {
181
182        final RdfStream input = new RdfStream(create(createResource().asNode(),
183                createURI("info:testPredicate"),
184                createResource().asNode()));
185        try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) {
186            new RdfStreamStreamingOutput(input, testMediaType).write(output);
187
188            try (final InputStream resultStream = new ByteArrayInputStream(output.toByteArray())) {
189                final Model result = createDefaultModel().read(resultStream, null);
190                assertTrue(result.contains(null, createProperty("info:testPredicate"), (RDFNode)null));
191            }
192        }
193
194    }
195
196
197    @Test
198    public void testWriteWithDatetimeObject() throws IOException {
199
200        assertOutputContainsTriple(create(createURI("info:testSubject"),
201                createURI("info:testPredicate"),
202                NodeFactory.createLiteral("2014-01-01T01:02:03Z", XSDDatatype.XSDdateTime)));
203
204    }
205
206
207    @Test
208    public void testWriteWithLanguageLiteral() throws IOException {
209
210        assertOutputContainsTriple(create(createURI("info:testSubject"),
211                createURI("info:testPredicate"),
212                NodeFactory.createLiteral("french string", "fr")));
213
214    }
215
216    @Test(expected = WebApplicationException.class)
217    public void testWriteWithException() throws IOException {
218
219        final FutureCallback<Void> callback = new FutureCallback<Void>() {
220
221            @Override
222            public void onSuccess(final Void v) {
223                throw new AssertionError("Should never happen!");
224            }
225
226            @Override
227            public void onFailure(final Throwable e) {
228                LOGGER.debug("Got exception:", e);
229                assertTrue("Got wrong kind of exception!", e instanceof RDFHandlerException);
230            }
231
232        };
233        addCallback(testRdfStreamStreamingOutput, callback);
234        try (final OutputStream mockOutputStream =
235                mock(OutputStream.class, new Answer<Object>() {
236
237                    @Override
238                    public Object answer(final InvocationOnMock invocation) throws IOException {
239                        throw new IOException("Expected.");
240                    }
241                })) {
242            testRdfStreamStreamingOutput.write(mockOutputStream);
243        }
244    }
245
246}