You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2012/10/20 22:21:15 UTC
svn commit: r1400510 - in /jena/Experimental/riot-reader: pom.xml
src/main/java/dev/PROJECT_RiotReader.java
src/main/java/org/apache/jena/riot/IO_Dataset.java
src/main/java/org/apache/jena/riot/IO_Jena.java
src/main/java/org/apache/jena/riot/IO_Model.java
Author: andy
Date: Sat Oct 20 20:21:15 2012
New Revision: 1400510
URL: http://svn.apache.org/viewvc?rev=1400510&view=rev
Log:
Experiment - split API in "triples reader" and "quads reader" libraries.
Added:
jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Dataset.java
jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Jena.java
jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Model.java
Modified:
jena/Experimental/riot-reader/pom.xml
jena/Experimental/riot-reader/src/main/java/dev/PROJECT_RiotReader.java
Modified: jena/Experimental/riot-reader/pom.xml
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/pom.xml?rev=1400510&r1=1400509&r2=1400510&view=diff
==============================================================================
--- jena/Experimental/riot-reader/pom.xml (original)
+++ jena/Experimental/riot-reader/pom.xml Sat Oct 20 20:21:15 2012
@@ -29,13 +29,13 @@
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-arq</artifactId>
- <version>2.9.4-SNAPSHOT</version>
+ <version>2.9.5-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-arq</artifactId>
- <version>2.9.4-SNAPSHOT</version>
+ <version>2.9.5-SNAPSHOT</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
@@ -43,7 +43,7 @@
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-core</artifactId>
- <version>2.7.4-SNAPSHOT</version>
+ <version>2.7.5-SNAPSHOT</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
Modified: jena/Experimental/riot-reader/src/main/java/dev/PROJECT_RiotReader.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/dev/PROJECT_RiotReader.java?rev=1400510&r1=1400509&r2=1400510&view=diff
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/dev/PROJECT_RiotReader.java (original)
+++ jena/Experimental/riot-reader/src/main/java/dev/PROJECT_RiotReader.java Sat Oct 20 20:21:15 2012
@@ -23,8 +23,8 @@ public class PROJECT_RiotReader
{
// Replace all manifest test suites in ARQ/RIOT with new code.
// Separate out manifest and junit-direct tests (two packages)
+
// Work out the dependencies on ARQ for splitting out RIOT
- // ModeIO, DatasetIO
// Check ContentType vs MediaType => MediaType (code) , correct name is ?
Added: jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Dataset.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Dataset.java?rev=1400510&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Dataset.java (added)
+++ jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Dataset.java Sat Oct 20 20:21:15 2012
@@ -0,0 +1,216 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.riot;
+
+import static org.apache.jena.riot.IO_Jena.determineCT ;
+import static org.apache.jena.riot.IO_Jena.open ;
+
+import java.io.InputStream ;
+import java.io.Reader ;
+import java.io.StringReader ;
+
+import org.openjena.atlas.lib.Sink ;
+import org.openjena.atlas.web.ContentType ;
+import org.openjena.riot.Lang ;
+import org.openjena.riot.RiotException ;
+import org.openjena.riot.RiotNotFoundException ;
+import org.openjena.riot.RiotReader ;
+import org.openjena.riot.lang.LangRIOT ;
+import org.openjena.riot.lang.SinkQuadsToDataset ;
+import org.openjena.riot.tokens.Tokenizer ;
+import org.openjena.riot.tokens.TokenizerFactory ;
+
+import com.hp.hpl.jena.query.Dataset ;
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+import com.hp.hpl.jena.sparql.core.Quad ;
+import com.hp.hpl.jena.sparql.util.Context ;
+
+/** <p>General purpose reader framework for RDF quad syntaxes.</p>
+ * <ul>
+ * <li>HTTP Content negotiation</li>
+ * <li>File type hint by the extension</li>
+ * <li>Application language hint</li>
+ * </ul>
+ * <p>
+ * It also provide a way to lookup names in different
+ * locations and to remap URIs to other URIs.
+ * </p>
+ * <p>
+ * Extensible - a new syntax can be added to the framework.
+ * </p>
+ *
+ * @See WebReader2
+ */
+
+public class IO_Dataset
+{
+ /* Maybe:
+ * static for global (singleton) and locally tailored.
+ */
+ /** Read quads into a Dataset from the given location, with hint of langauge.
+ * @see #read(Dataset, String, String, Lang2, Context)
+ * @param dataset Destination
+ * @param uri URI to read from (includes file: and a plain file name).
+ * @param hintLang Language syntax
+ */
+ public static void read(Dataset dataset, String uri, Lang2 hintLang)
+ {
+ read(dataset, uri, hintLang, null) ;
+ }
+
+ /** Read quads or triples into a Dataset from the given location.
+ * @see #read(Dataset, String, String, Lang2, Context)
+ * @param dataset Destination
+ * @param uri URI to read from (includes file: and a plain file name).
+ * @param hintLang Language syntax
+ */
+ public static void read(Dataset dataset, String uri, Lang2 hintLang, Context context)
+ {
+ read(dataset, uri, uri, hintLang, context) ;
+ }
+
+ /** Read quads or triples into a Dataset from the given location.
+ * @see #read(Dataset, String, String, Lang2, Context)
+ * @param dataset Destination
+ * @param uri URI to read from (includes file: and a plain file name).
+ * @param hintLang Language syntax
+ * @throws RiotNotFoundException if the location is not found - the model is unchanged.
+ * Throws parse errors depending on the language and reader; the Model model may be partially updated.
+ */
+
+ public static void read(Dataset dataset, String uri, String base, Lang2 hintLang, Context context)
+ {
+ DatasetGraph dsg = dataset.asDatasetGraph() ;
+ Sink<Quad> sink = new SinkQuadsToDataset(dsg) ;
+ readQuads(sink, uri, base, hintLang, context) ;
+ }
+
+ /** Read quads or triples into a dataset with bytes from an input stream.
+ * @param dataset Destination
+ * @param in InputStream
+ * @param lang Language syntax
+ */
+ public static void read(Dataset dataset, InputStream in, Lang2 lang)
+ {
+ read(dataset, in, null, lang) ;
+ }
+
+ /** Read quads or triples into a dataset with bytes from an input stream.
+ * @param dataset Destination
+ * @param in InputStream
+ * @param base Base URI
+ * @param lang Language syntax
+ */
+ public static void read(Dataset dataset, InputStream in, String base, Lang2 lang)
+ {
+ DatasetGraph dsg = dataset.asDatasetGraph() ;
+ Sink<Quad> sink = new SinkQuadsToDataset(dsg) ;
+ processQuads(sink, base, new TypedInputStream2(in), lang, null) ;
+ }
+
+ /** Read quads into a dataset with chars from an Reader.
+ * Use java.io.Readers is not encouraged - use with a StringReader is the primary use case.
+ * For files, open a {@link java.io.FileInputStream} to ensure correct character set handling.
+ * @param dataset Destination
+ * @param in InputStream
+ * @param base Base URI
+ * @param lang Language syntax
+ * @deprecated use an InputStream or a StringReader.
+ */
+ @Deprecated
+ public static void read(Dataset dataset, Reader in, String base, Lang2 lang)
+ {
+ DatasetGraph dsg = dataset.asDatasetGraph() ;
+ Sink<Quad> sink = new SinkQuadsToDataset(dsg) ;
+ processQuads(sink, base, in, lang, null) ;
+ }
+
+ /** Read quads into a dataset with chars from a StringReader.
+ * Use java.io.Readers is not encouraged - use with a StringReader is the primary use case.
+ * For files, open a {@link java.io.FileInputStream} to ensure correct character set handling.
+ * @param dataset Destination
+ * @param in InputStream
+ * @param base Base URI
+ * @param lang Language syntax
+ */
+ public static void read(Dataset dataset, StringReader in, String base, Lang2 lang)
+ {
+ DatasetGraph dsg = dataset.asDatasetGraph() ;
+ Sink<Quad> sink = new SinkQuadsToDataset(dsg) ;
+ processQuads(sink, base, in, lang, null) ;
+ }
+
+ /** Read quads - send to a sink.
+ * @param sink Destination for the RDF read.
+ * @param uri URI to read from (includes file: and a plain file name).
+ * @param hintLang Hint for the syntax
+ * @param context Content object to control reading process.
+ */
+ public static void readQuads(Sink<Quad> sink, String uri, Lang2 hintLang, Context context)
+ {
+ readQuads(sink, uri, uri, hintLang, context) ;
+ }
+
+ /** Read quads - send to a sink.
+ * @param sink Destination for the RDF read.
+ * @param uri URI to read from (includes file: and a plain file name).
+ * @param base Base URI (defaults to uri).
+ * @param hintLang Hint for the syntax
+ * @param context Content object to control reading process.
+ */
+ public static void readQuads(Sink<Quad> sink, String uri, String base, Lang2 hintLang, Context context)
+ {
+ TypedInputStream2 in = open(uri, context) ;
+ if ( in == null )
+ throw new RiotException("Not found: "+uri) ;
+ processQuads(sink, base, in, hintLang, context) ;
+ in.close() ;
+ }
+
+ private static void processQuads(Sink<Quad> sink, String uri, TypedInputStream2 in, Lang2 hintLang, Context context)
+ {
+ ContentType ct = determineCT(uri, in.getContentType(), hintLang ) ;
+ if ( ct == null )
+ throw new RiotException("Failed to determine the quads content type: (URI="+uri+" : stream="+in.getContentType()+" : hint="+hintLang+")") ;
+ ReaderRIOT<Quad> reader = getReaderQuads(ct) ;
+ if ( reader == null )
+ throw new RiotException("No quads reader for content type: "+ct) ;
+
+ reader.read(in.getInput(), uri, ct, sink, context) ;
+ }
+
+ private static ReaderRIOT<Quad> getReaderQuads(ContentType ct)
+ {
+ Lang2 lang = Langs.contentTypeToLang(ct) ;
+ ReaderRIOTFactory<Quad> r = Langs.getFactoryQuads(lang) ;
+ if ( r == null )
+ return null ;
+ return r.create(lang) ;
+ }
+
+ // java.io.Readers are NOT preferred.
+ private static void processQuads(Sink<Quad> sink, String base, Reader in, Lang2 hintLang, Context context)
+ {
+ Tokenizer tokenizer = TokenizerFactory.makeTokenizer(in) ;
+ Lang lang = Langs.convert(hintLang) ;
+ LangRIOT parser = RiotReader.createParserQuads(tokenizer, lang, base, sink) ;
+ parser.parse() ;
+ }
+}
+
Added: jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Jena.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Jena.java?rev=1400510&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Jena.java (added)
+++ jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Jena.java Sat Oct 20 20:21:15 2012
@@ -0,0 +1,170 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.riot;
+
+import org.apache.jena.riot.stream.StreamManager ;
+import org.openjena.atlas.web.ContentType ;
+import org.openjena.riot.RiotNotFoundException ;
+import org.openjena.riot.SysRIOT ;
+import org.openjena.riot.WebContent ;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+
+import com.hp.hpl.jena.rdf.model.impl.RDFReaderFImpl ;
+import com.hp.hpl.jena.sparql.util.Context ;
+import com.hp.hpl.jena.sparql.util.Symbol ;
+import com.hp.hpl.jena.sparql.util.Utils ;
+
+/** common material between ModelIO and DatasetIO */
+
+abstract class IO_Jena
+{
+ static Logger log = LoggerFactory.getLogger(IO_Model.class) ;
+
+ private static String riotBase = "http://jena.apache.org/riot/" ;
+ private static String streamManagerSymbolStr = riotBase+"streammanager" ;
+ public static Symbol streamManagerSymbol = Symbol.create(streamManagerSymbolStr) ;
+
+ public static void wireIntoJena()
+ {
+// // Wire in generic
+// String readerRDF = RDFReaderRIOT.class.getName() ;
+// RDFReaderFImpl.setBaseReaderClassName("RDF/XML", readerRDF) ; // And default
+// RDFReaderFImpl.setBaseReaderClassName("RDF/XML-ABBREV", readerRDF) ;
+//
+// RDFReaderFImpl.setBaseReaderClassName("N-TRIPLES", readerRDF) ;
+// RDFReaderFImpl.setBaseReaderClassName("N-TRIPLE", readerRDF) ;
+// RDFReaderFImpl.setBaseReaderClassName("N3", readerRDF) ;
+// RDFReaderFImpl.setBaseReaderClassName("TURTLE", readerRDF) ;
+// RDFReaderFImpl.setBaseReaderClassName("Turtle", readerRDF) ;
+// RDFReaderFImpl.setBaseReaderClassName("TTL", readerRDF) ;
+// RDFReaderFImpl.setBaseReaderClassName("RDF/JSON", readerRDF) ;
+
+ RDFReaderFImpl.setBaseReaderClassName("RDF/XML", RDFReaderRIOT_RDFXML.class.getName()) ; // And default
+ RDFReaderFImpl.setBaseReaderClassName("RDF/XML-ABBREV", RDFReaderRIOT_RDFXML.class.getName()) ;
+
+ RDFReaderFImpl.setBaseReaderClassName("N-TRIPLES", RDFReaderRIOT_NT.class.getName()) ;
+ RDFReaderFImpl.setBaseReaderClassName("N-TRIPLE", RDFReaderRIOT_NT.class.getName()) ;
+ RDFReaderFImpl.setBaseReaderClassName("N3", RDFReaderRIOT_TTL.class.getName()) ;
+ RDFReaderFImpl.setBaseReaderClassName("TURTLE", RDFReaderRIOT_TTL.class.getName()) ;
+ RDFReaderFImpl.setBaseReaderClassName("Turtle", RDFReaderRIOT_TTL.class.getName()) ;
+ RDFReaderFImpl.setBaseReaderClassName("TTL", RDFReaderRIOT_TTL.class.getName()) ;
+ RDFReaderFImpl.setBaseReaderClassName("RDF/JSON", RDFReaderRIOT_RDFJSON.class.getName()) ;
+ }
+
+ // Yukky hack to integrate into current jena-core where the structure of model.read assumes
+ // the language is determined before the reading process starts.
+
+ static class RDFReaderRIOT_RDFXML extends RDFReaderRIOT { public RDFReaderRIOT_RDFXML() { super("RDF/XML") ; } }
+ static class RDFReaderRIOT_TTL extends RDFReaderRIOT { public RDFReaderRIOT_TTL() { super("TTL") ; } }
+ static class RDFReaderRIOT_NT extends RDFReaderRIOT { public RDFReaderRIOT_NT() { super("N-TRIPLE") ; } }
+ static class RDFReaderRIOT_RDFJSON extends RDFReaderRIOT { public RDFReaderRIOT_RDFJSON() { super("RDF/JSON") ; } }
+
+
+ public static void resetJenaReaders()
+ {
+ SysRIOT.resetJenaReaders() ;
+ }
+
+ // --- IO
+
+ /** Open a stream to the destination (URI or filename)
+ * Performs content negotition, including looking at file extension.
+ */
+ public static TypedInputStream2 open(String filenameOrURI)
+ { return open(filenameOrURI, (Context)null) ; }
+
+ /** Open a stream to the destination (URI or filename)
+ * Performs content negotition, including looking at file extension.
+ */
+ public static TypedInputStream2 open(String filenameOrURI, Context context)
+ {
+ StreamManager sMgr = StreamManager.get() ;
+ if ( context != null )
+ {
+ try { sMgr = (StreamManager)context.get(streamManagerSymbol, context) ; }
+ catch (ClassCastException ex)
+ { log.warn("Context symbol '"+streamManagerSymbol+"' is not a "+Utils.classShortName(StreamManager.class)) ; }
+ }
+
+ return open(filenameOrURI, sMgr) ;
+ }
+
+ public static TypedInputStream2 open(String filenameOrURI, StreamManager sMgr)
+ {
+ TypedInputStream2 in = sMgr.open(filenameOrURI) ;
+
+ if ( in == null )
+ {
+ if ( log.isDebugEnabled() )
+ //log.debug("Found: "+filenameOrURI+" ("+loc.getName()+")") ;
+ log.debug("Not Found: "+filenameOrURI) ;
+ throw new RiotNotFoundException("Not found: "+filenameOrURI) ;
+ //return null ;
+ }
+ if ( log.isDebugEnabled() )
+ //log.debug("Found: "+filenameOrURI+" ("+loc.getName()+")") ;
+ log.debug("Found: "+filenameOrURI) ;
+ return in ;
+ }
+
+ protected static ContentType determineCT(String target, String ctStr, Lang2 hintLang)
+ {
+ if ( ctStr != null )
+ ctStr = WebContent.contentTypeCanonical(ctStr) ;
+
+ boolean isTextPlain = WebContent.contentTypeTextPlain.equals(ctStr) ;
+ ContentType ct = (ctStr==null) ? null : ContentType.parse(ctStr) ;
+
+ // It's it's text plain, we ignore it because a lot of naive
+ // server setups return text/plain for any file type.
+
+ if ( ct == null || isTextPlain )
+ {
+ if ( hintLang == null )
+ ct = Langs.guessContentType(target) ;
+ else
+ {
+ ct = hintLang.getContentType() ;
+// if ( ct == null )
+// {
+// // Is the hint a content type?
+// Lang2 lang = Langs.contentTypeToLang(hintLang) ;
+// if ( lang != null )
+// ct = lang.getContentType() ;
+// }
+ }
+ }
+ return ct ;
+ }
+
+ // --- Syntax framework
+// public static void addTripleSyntax(Lang2 language, ContentType contentType, ReaderRIOTFactory<Triple> factory, String ... fileExt )
+// {
+// Langs.addTripleSyntax$(language, contentType, factory, fileExt) ;
+// }
+//
+// public static void addQuadSyntax(Lang2 language, ContentType contentType, ReaderRIOTFactory<Quad> factory, String ... fileExt )
+// {
+// Langs.addQuadSyntax$(language, contentType, factory, fileExt) ;
+// }
+
+
+}
+
Added: jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Model.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Model.java?rev=1400510&view=auto
==============================================================================
--- jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Model.java (added)
+++ jena/Experimental/riot-reader/src/main/java/org/apache/jena/riot/IO_Model.java Sat Oct 20 20:21:15 2012
@@ -0,0 +1,267 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.riot;
+
+import static org.apache.jena.riot.IO_Jena.determineCT ;
+import static org.apache.jena.riot.IO_Jena.open ;
+
+import java.io.InputStream ;
+import java.io.Reader ;
+import java.io.StringReader ;
+
+import org.openjena.atlas.lib.Sink ;
+import org.openjena.atlas.web.ContentType ;
+import org.openjena.riot.* ;
+import org.openjena.riot.lang.LangRDFXML ;
+import org.openjena.riot.lang.LangRIOT ;
+import org.openjena.riot.lang.SinkTriplesToGraph ;
+import org.openjena.riot.tokens.Tokenizer ;
+import org.openjena.riot.tokens.TokenizerFactory ;
+
+import com.hp.hpl.jena.graph.Graph ;
+import com.hp.hpl.jena.graph.Triple ;
+import com.hp.hpl.jena.rdf.model.Model ;
+import com.hp.hpl.jena.sparql.util.Context ;
+
+/** <p>General purpose reader framework for RDF triple syntaxes.</p>
+ * <ul>
+ * <li>HTTP Content negotiation</li>
+ * <li>File type hint by the extension</li>
+ * <li>Application language hint</li>
+ * </ul>
+ * <p>
+ * It also provide a way to lookup names in different
+ * locations and to remap URIs to other URIs.
+ * </p>
+ * <p>
+ * Extensible - a new syntax can be added to the framework.
+ * </p>
+ *
+ * @See WebReader2
+ */
+
+public class IO_Model
+{
+ /** Read triples into a Model from the given location.
+ * The synatx is detemined from input source URI (content negotiation or extension).
+ * @see #read(Model,String,Lang2,Context)
+ * @param model Destination for the RDF read.
+ * @param uri URI to read from (includes file: and a plain file name).
+ */
+ public static void read(Model model, String uri) { read(model, uri, null, null, null) ; }
+
+ /** Read triples into a Model from the given location, with a hint of the language (MIME type)
+ * @see #read(Model,String,String,Lang2,Context)
+ * @param model Destination for the RDF read.
+ * @param uri URI to read from (includes file: and a plain file name).
+ * @param hintLang Hint for the syntax.
+ */
+ public static void read(Model model, String uri, Lang2 hintLang) { read(model, uri, hintLang, null) ; }
+
+ /** Read triples into a Model from the given location, with hint of langauge and the with some parameters for the reader
+ * @see #read(Model,String,String,Lang2,Context)
+ * Throws parse errors depending on the language and reader; the Model model may be partially updated.
+ * @param model Destination for the RDF read.
+ * @param uri URI to read from (includes file: and a plain file name).
+ * @param base Base URI (defaults to uri).
+ * @param hintLang Hint for the syntax
+ * @throws RiotNotFoundException if the location is not found - the model is unchanged.
+ */
+ public static void read(Model model, String uri, String base, Lang2 hintLang) { read(model, uri, base, hintLang, null) ; }
+
+ /** Read triples into a Model from the given location, with some parameters for the reader
+ * @see #read(Model,String,String,Lang2,Context)
+ * @param model Destination for the RDF read
+ * @param uri URI to read from (includes file: and a plain file name).
+ * @param context Content object to control reading process.
+ */
+ public static void read(Model model, String uri, Context context) { read(model, uri, null, context) ; }
+
+ /** Read triples into a Model from the given location, with hint of langauge and the with some parameters for the reader
+ * @see #read(Model,String,String,Lang2,Context)
+ * @param model Destination for the RDF read
+ * @param uri URI to read from (includes file: and a plain file name).
+ * @param hintLang Hint for the syntax
+ * @param context Content object to control reading process.
+ */
+ public static void read(Model model, String uri, Lang2 hintLang, Context context)
+ {
+ read(model, uri, uri, hintLang, context) ;
+ }
+
+ /** Read triples into a Model from the given location, with hint of langauge and the with some parameters for the reader
+ * Throws parse errors depending on the language and reader; the Model model may be partially updated.
+ * @param model Destination for the RDF read.
+ * @param uri URI to read from (includes file: and a plain file name).
+ * @param base Base URI (defaults to uri).
+ * @param hintLang Hint for the syntax
+ * @param context Content object to control reading process.
+ * @throws RiotNotFoundException if the location is not found - the model is unchanged.
+ */
+ public static void read(Model model, String uri, String base, Lang2 hintLang, Context context)
+ {
+ Graph g = model.getGraph() ;
+ Sink<Triple> sink = new SinkTriplesToGraph(g) ;
+ readTriples(sink, uri, base, hintLang, context) ;
+ }
+
+ /** Read triples into a Model with bytes from an InputStream.
+ * A base URI and a syntax can be provided.
+ * The base URI defualts to "no base" in which case the data should have no relative URIs.
+ * The lang gives the syntax of the stream.
+ * @param model Destination for the RDF read.
+ * @param in InputStream
+ * @param lang Language syntax
+ */
+
+ public static void read(Model model, InputStream in, Lang2 lang)
+ {
+ read(model, in, null, lang) ;
+ }
+
+ /** Read triples into a Model with bytes from an InputStream.
+ * A base URI and a syntax can be provided.
+ * The base URI defualts to "no base" in which case the data should have no relative URIs.
+ * The lang gives the syntax of the stream.
+ * @param model Destination for the RDF read.
+ * @param in InputStream
+ * @param base Base URI
+ * @param lang Language syntax
+ */
+ public static void read(Model model, InputStream in, String base, Lang2 lang)
+ {
+ Graph g = model.getGraph() ;
+ Sink<Triple> sink = new SinkTriplesToGraph(g) ;
+ processTriples(sink, base, new TypedInputStream2(in), lang, null) ;
+ }
+
+ /** Read triples into a model with chars from an Reader.
+ * Use java.io.Readers is not encouraged - use with a StringReader is the primary use case.
+ * For files, open a {@link java.io.FileInputStream} to ensure correct character set handling.
+ * @deprecated Use an InputStream or StringReader.
+ * @param model Destination for the RDF read.
+ * @param in Reader
+ * @param base Base URI
+ * @param lang Language syntax
+ */
+ @Deprecated
+ public static void read(Model model, Reader in, String base, Lang2 lang)
+ {
+ Graph g = model.getGraph() ;
+ Sink<Triple> sink = new SinkTriplesToGraph(g) ;
+ processTriples(sink, base, in, lang, null) ;
+ }
+
+ /** Read triples into a model with chars from a StringReader.
+ * @param model Destination for the RDF read.
+ * @param in InputStream
+ * @param base Base URI
+ * @param lang Language syntax
+ */
+ public static void read(Model model, StringReader in, String base, Lang2 lang)
+ {
+ Graph g = model.getGraph() ;
+ Sink<Triple> sink = new SinkTriplesToGraph(g) ;
+ processTriples(sink, base, in, lang, null) ;
+ }
+
+
+
+ /** Read triples - send to a sink.
+ * @param sink Destination for the RDF read.
+ * @param uri URI to read from (includes file: and a plain file name).
+ * @param hintLang Hint for the syntax
+ * @param context Content object to control reading process.
+ */
+ public static void readTriples(Sink<Triple> sink, String uri, Lang2 hintLang, Context context)
+ {
+ readTriples(sink, uri, uri, hintLang, context) ;
+ }
+
+ /** Read triples - send to a sink.
+ * @param sink Destination for the RDF read.
+ * @param uri URI to read from (includes file: and a plain file name).
+ * @param base Base URI (defaults to uri).
+ * @param hintLang Hint for the syntax
+ * @param context Content object to control reading process.
+ */
+ public static void readTriples(Sink<Triple> sink, String uri, String base, Lang2 hintLang, Context context)
+ {
+ TypedInputStream2 in = open(uri, context) ;
+ if ( in == null )
+ throw new RiotException("Not found: "+uri) ;
+ processTriples(sink, base, in, hintLang, context) ;
+ in.close() ;
+ }
+
+ // -----
+ // Readers are algorithms and must be stateless (or they must create a per run
+ // instance of something) because they may be called concurrency from different threads.
+ // The Context Readerobject gives the per-run configuration.
+
+ // Alternative: A two step factory-instance design means
+ // readers can be created and passed around (e,.g. to set specific features)
+ // We could have had two step design - ReaderFactory-ReaderInstance
+ // no - put the bruden on complicated readers, not everyone.
+
+ private static void processTriples(Sink<Triple> sink, String baseUri, TypedInputStream2 in, Lang2 hintLang, Context context)
+ {
+ ContentType ct = determineCT(baseUri, in.getContentType(), hintLang ) ;
+
+ if ( ct == null )
+ throw new RiotException("Failed to determine the triples content type: (URI="+baseUri+" : stream="+in.getContentType()+" : hint="+hintLang+")") ;
+
+ ReaderRIOT<Triple> reader = getReaderTriples(ct) ;
+ if ( reader == null )
+ throw new RiotException("No triples reader for content type: "+ct.getContentType()) ;
+
+ reader.read(in.getInput(), baseUri, ct, sink, context) ;
+ }
+
+ private static ReaderRIOT<Triple> getReaderTriples(ContentType ct)
+ {
+ Lang2 lang = Langs.contentTypeToLang(ct) ;
+ ReaderRIOTFactory<Triple> r = Langs.getFactoryTriples(lang) ;
+ if ( r == null )
+ return null ;
+ return r.create(lang) ;
+ }
+
+ // java.io.Readers are NOT preferred.
+ @SuppressWarnings("deprecation")
+ private static void processTriples(Sink<Triple> sink, String base, Reader in, Lang2 hintLang, Context context)
+ {
+ // Not as good as from an InputStream - RDF/XML not supported
+ ContentType ct = determineCT(base, null, hintLang) ;
+ if ( ct == null )
+ throw new RiotException("Failed to determine the triples content type: (URI="+base+" : hint="+hintLang+")") ;
+
+ Tokenizer tokenizer = TokenizerFactory.makeTokenizer(in) ;
+ if ( hintLang == null )
+ throw new RiotException("No language specificied") ;
+ Lang lang = Langs.convert(hintLang) ;
+ LangRIOT parser ;
+ if ( lang == Lang.RDFXML )
+ parser = LangRDFXML.create(in, base, base, ErrorHandlerFactory.errorHandlerStd, sink) ;
+ else
+ parser = RiotReader.createParserTriples(tokenizer, lang, base, sink) ;
+ parser.parse() ;
+ }
+}
+