View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.commons.rdf.simple.experimental;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertNull;
23  import static org.junit.Assert.assertTrue;
24  
25  import java.io.ByteArrayInputStream;
26  import java.io.IOException;
27  import java.io.InputStream;
28  import java.nio.file.Files;
29  import java.nio.file.Path;
30  import java.util.concurrent.TimeUnit;
31  
32  import org.apache.commons.rdf.api.Graph;
33  import org.apache.commons.rdf.api.IRI;
34  import org.apache.commons.rdf.api.Literal;
35  import org.apache.commons.rdf.api.RDFSyntax;
36  import org.apache.commons.rdf.api.RDFTerm;
37  import org.apache.commons.rdf.api.RDF;
38  import org.apache.commons.rdf.api.Triple;
39  import org.apache.commons.rdf.experimental.RDFParser;
40  import org.apache.commons.rdf.simple.DummyRDFParserBuilder;
41  import org.apache.commons.rdf.simple.SimpleRDF;
42  import org.apache.commons.rdf.simple.Types;
43  import org.junit.After;
44  import org.junit.Before;
45  import org.junit.Rule;
46  import org.junit.Test;
47  import org.junit.rules.ExpectedException;
48  
49  public class AbstractRDFParserTest {
50  
51      private final RDF factory = new SimpleRDF();
52  
53      private final DummyRDFParserBuilder dummyParser = new DummyRDFParserBuilder();
54      private Path testNt;
55      private Path testTtl;
56      private Path testXml;
57  
58      @Before
59      public void createTempFile() throws IOException {
60          testNt = Files.createTempFile("test", ".nt");
61          testTtl = Files.createTempFile("test", ".ttl");
62          testXml = Files.createTempFile("test", ".xml");
63  
64          // No need to populate the files as the dummy parser
65          // doesn't actually read anything
66      }
67  
68      @After
69      public void deleteTempFiles() throws IOException {
70          Files.deleteIfExists(testNt);
71          Files.deleteIfExists(testTtl);
72          Files.deleteIfExists(testXml);
73      }
74  
75      @Test
76      public void guessRDFSyntax() throws Exception {
77          assertEquals(RDFSyntax.NTRIPLES, AbstractRDFParser.guessRDFSyntax(testNt).get());
78          assertEquals(RDFSyntax.TURTLE, AbstractRDFParser.guessRDFSyntax(testTtl).get());
79          assertFalse(AbstractRDFParser.guessRDFSyntax(testXml).isPresent());
80      }
81  
82      private void checkGraph(final Graph g) throws Exception {
83          assertTrue(g.size() > 0);
84          final IRI greeting = factory.createIRI("http://example.com/greeting");
85          // Should only have parsed once!
86          assertEquals(1, g.stream(null, greeting, null).count());
87          final Triple triple = g.stream(null, greeting, null).findAny().get();
88          assertTrue(triple.getSubject() instanceof IRI);
89          final IRI parsing = (IRI) triple.getSubject();
90          assertTrue(parsing.getIRIString().startsWith("urn:uuid:"));
91  
92          assertEquals("http://example.com/greeting", triple.getPredicate().getIRIString());
93  
94          assertTrue(triple.getObject() instanceof Literal);
95          final Literal literal = (Literal) triple.getObject();
96          assertEquals("Hello world", literal.getLexicalForm());
97          assertFalse(literal.getLanguageTag().isPresent());
98          assertEquals(Types.XSD_STRING, literal.getDatatype());
99  
100         // Check uniqueness of properties that are always present
101         assertEquals(1, g.stream(null, factory.createIRI("http://example.com/source"), null).count());
102 
103         // Check optional properties that are unique
104         assertTrue(2 > g.stream(null, factory.createIRI("http://example.com/base"), null).count());
105         assertTrue(2 > g.stream(null, factory.createIRI("http://example.com/contentType"), null).count());
106         assertTrue(2 > g.stream(null, factory.createIRI("http://example.com/contentTypeSyntax"), null).count());
107     }
108 
109     @Test
110     public void parseFile() throws Exception {
111         final Graph g = factory.createGraph();
112         final RDFParser parser = dummyParser.source(testNt).target(g);
113         parser.parse().get(5, TimeUnit.SECONDS);
114         checkGraph(g);
115         // FIXME: this could potentially break if the equivalent of /tmp
116         // includes
117         // international characters
118         assertEquals("<" + testNt.toUri().toString() + ">", firstPredicate(g, "source"));
119         // Should be set to the file path
120         assertEquals("<" + testNt.toUri().toString() + ">", firstPredicate(g, "base"));
121 
122         // Should NOT have guessed the content type
123         assertNull(firstPredicate(g, "contentType"));
124         assertNull(firstPredicate(g, "contentTypeSyntax"));
125     }
126 
127     @Test
128     public void parseNoSource() throws Exception {
129         thrown.expect(IllegalStateException.class);
130         dummyParser.parse();
131     }
132 
133     @Test
134     public void parseBaseAndContentTypeNoSource() throws Exception {
135         // Can set the other options, even without source()
136         final IRI base = dummyParser.createRDFTermFactory().createIRI("http://www.example.org/test.rdf");
137         final RDFParser parser = dummyParser.base(base).contentType(RDFSyntax.RDFXML);
138         thrown.expect(IllegalStateException.class);
139         thrown.expectMessage("No source has been set");
140         // but .parse() should fail
141         parser.parse();
142     }
143 
144     @Test
145     public void parseFileMissing() throws Exception {
146         Files.delete(testNt);
147         // This should not fail yet
148         final RDFParser parser = dummyParser.source(testNt);
149         // but here:
150         thrown.expect(IOException.class);
151         parser.parse();
152     }
153 
154     @Test
155     public void parseFileContentType() throws Exception {
156         final Graph g = factory.createGraph();
157         final RDFParser parser = dummyParser.source(testNt).contentType(RDFSyntax.NTRIPLES).target(g);
158         parser.parse().get(5, TimeUnit.SECONDS);
159         checkGraph(g);
160         // FIXME: this could potentially break if the equivalent of /tmp
161         // includes
162         // international characters
163         assertEquals("<" + testNt.toUri().toString() + ">", firstPredicate(g, "source"));
164         assertEquals("<" + testNt.toUri().toString() + ">", firstPredicate(g, "base"));
165         assertEquals("\"NTRIPLES\"", firstPredicate(g, "contentTypeSyntax"));
166         assertEquals("\"application/n-triples\"", firstPredicate(g, "contentType"));
167     }
168 
169     private String firstPredicate(final Graph g, final String pred) {
170         return g.stream(null, factory.createIRI("http://example.com/" + pred), null).map(Triple::getObject)
171                 .map(RDFTerm::ntriplesString).findAny().orElse(null);
172     }
173 
174     @Rule
175     public ExpectedException thrown = ExpectedException.none();
176 
177     @Test
178     public void parseInputStreamFailsIfBaseMissing() throws Exception {
179         final InputStream inputStream = new ByteArrayInputStream(new byte[0]);
180         // Should not fail at this point
181         final RDFParser parser = dummyParser.source(inputStream);
182         // but here:
183         thrown.expect(IllegalStateException.class);
184         thrown.expectMessage("base iri required for inputstream source");
185         parser.parse();
186     }
187 
188     @Test
189     public void parseInputStreamWithBase() throws Exception {
190         final InputStream inputStream = new ByteArrayInputStream(new byte[0]);
191         final IRI base = dummyParser.createRDFTermFactory().createIRI("http://www.example.org/test.rdf");
192         final Graph g = factory.createGraph();
193         final RDFParser parser = dummyParser.source(inputStream).base(base).target(g);
194         parser.parse().get(5, TimeUnit.SECONDS);
195         checkGraph(g);
196         assertEquals("<http://www.example.org/test.rdf>", firstPredicate(g, "base"));
197         // in our particular debug output,
198         // bnode source indicates InputStream
199         assertTrue(firstPredicate(g, "source").startsWith("_:"));
200         assertNull(firstPredicate(g, "contentType"));
201         assertNull(firstPredicate(g, "contentTypeSyntax"));
202     }
203 
204     @Test
205     public void parseInputStreamWithNQuads() throws Exception {
206         final InputStream inputStream = new ByteArrayInputStream(new byte[0]);
207         final Graph g = factory.createGraph();
208         final RDFParser parser = dummyParser.source(inputStream).contentType(RDFSyntax.NQUADS).target(g);
209         parser.parse().get(5, TimeUnit.SECONDS);
210         checkGraph(g);
211         assertNull(firstPredicate(g, "base"));
212         // in our particular debug output,
213         // bnode source indicates InputStream
214         assertTrue(firstPredicate(g, "source").startsWith("_:"));
215         assertEquals("\"application/n-quads\"", firstPredicate(g, "contentType"));
216         assertEquals("\"NQUADS\"", firstPredicate(g, "contentTypeSyntax"));
217     }
218 
219     @Test
220     public void parseIRI() throws Exception {
221         final IRI iri = dummyParser.createRDFTermFactory().createIRI("http://www.example.net/test.ttl");
222         final Graph g = factory.createGraph();
223         final RDFParser parser = dummyParser.source(iri).target(g);
224         parser.parse().get(5, TimeUnit.SECONDS);
225         checkGraph(g);
226         assertEquals("<http://www.example.net/test.ttl>", firstPredicate(g, "source"));
227         // No base - assuming the above IRI is always
228         // the base would break server-supplied base from
229         // any HTTP Location redirects and Content-Location header
230         assertNull(firstPredicate(g, "base"));
231         // ".ttl" in IRI string does not imply any content type
232         assertNull(firstPredicate(g, "contentType"));
233         assertNull(firstPredicate(g, "contentTypeSyntax"));
234 
235     }
236 
237     @Test
238     public void parseIRIBaseContentType() throws Exception {
239         final IRI iri = dummyParser.createRDFTermFactory().createIRI("http://www.example.net/test.ttl");
240         final Graph g = factory.createGraph();
241         final RDFParser parser = dummyParser.source(iri).base(iri).contentType(RDFSyntax.TURTLE).target(g);
242         parser.parse().get(5, TimeUnit.SECONDS);
243         checkGraph(g);
244         assertEquals("<http://www.example.net/test.ttl>", firstPredicate(g, "source"));
245         assertEquals("<http://www.example.net/test.ttl>", firstPredicate(g, "base"));
246         assertEquals("\"TURTLE\"", firstPredicate(g, "contentTypeSyntax"));
247         assertEquals("\"text/turtle\"", firstPredicate(g, "contentType"));
248     }
249 
250 }