/** * 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 java.io.* ; import java.util.Iterator ; import java.util.Objects ; import org.apache.jena.atlas.io.IO ; import org.apache.jena.atlas.iterator.IteratorResourceClosing ; import org.apache.jena.atlas.lib.Lib ; import org.apache.jena.atlas.web.ContentType ; import org.apache.jena.atlas.web.TypedInputStream ; import org.apache.jena.graph.Graph ; import org.apache.jena.graph.Triple ; import org.apache.jena.query.Dataset ; import org.apache.jena.query.DatasetFactory ; import org.apache.jena.rdf.model.Model ; import org.apache.jena.rdf.model.ModelFactory ; import org.apache.jena.riot.lang.PipedQuadsStream ; import org.apache.jena.riot.lang.PipedRDFIterator ; import org.apache.jena.riot.lang.PipedTriplesStream ; import org.apache.jena.riot.system.RiotLib ; import org.apache.jena.riot.system.StreamRDF ; import org.apache.jena.riot.system.StreamRDFLib ; import org.apache.jena.riot.system.stream.StreamManager ; import org.apache.jena.riot.writer.NQuadsWriter ; import org.apache.jena.riot.writer.NTriplesWriter ; import org.apache.jena.sparql.core.DatasetGraph ; import org.apache.jena.sparql.core.DatasetGraphFactory ; import org.apache.jena.sparql.core.Quad ; import org.apache.jena.sparql.graph.GraphFactory ; import org.apache.jena.sparql.util.Context ; import org.apache.jena.sparql.util.Symbol ; import org.apache.jena.system.JenaSystem ; import org.slf4j.Logger ; import org.slf4j.LoggerFactory ; /** <p>General purpose reader framework for RDF (triples and quads) 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 provides 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> * <p>Operations fall into the following categories:</p> * <ul> * <li>{@code read} -- Read data from a location into a Model, Dataset, etc. The methods in this class treat all types of Model in the same way. For behavior specific to a subtype of Model, use the methods of that specific class.</li> * <li>{@code loadXXX} -- Read data and return an in-memory object holding the data.</li> * <li>{@code parse} -- Read data and send to an {@link StreamRDF}</li> * <li>{@code open} -- Open a typed input stream to the location, using any alternative locations</li> * <li>{@code write} -- Write Model/Dataset etc</li> * <li>{@code create} -- Create a reader or writer explicitly</li> * </ul> */ public class RDFDataMgr { static { JenaSystem.init() ; } static Logger log = LoggerFactory.getLogger(RDFDataMgr.class) ; private static String riotBase = "http://jena.apache.org/riot/" ; private static String StreamManagerSymbolStr = riotBase+"streamManager" ; public static Symbol streamManagerSymbol = Symbol.create(riotBase+"streamManager") ; /** Read triples into a Model from the given location. * The syntax is detemined from input source URI (content negotiation or extension). * @param model Destination for the RDF read. * @param uri URI to read from (includes file: and a plain file name). * @throws RiotNotFoundException if the location is not found - the model is unchanged. * @see #read(Model,String,Lang,Context) */ public static void read(Model model, String uri) { read(model.getGraph(), uri) ; } /** Read triples into a Model from the given location. * The syntax is detemined from input source URI (content negotiation or extension). * @param graph Destination for the RDF read. * @param uri URI to read from (includes file: and a plain file name). * @throws RiotNotFoundException if the location is not found - the graph is unchanged. * @see #read(Graph,String,Lang,Context) */ public static void read(Graph graph, String uri) { read(graph, uri, defaultBase(uri), defaultLang(uri), (Context)null) ; } /** Read triples into a Model from the given location, with a hint of the language (MIME type) * @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. * @throws RiotNotFoundException if the location is not found - the model is unchanged. * @see #read(Model,String,String,Lang,Context) */ public static void read(Model model, String uri, Lang hintLang) { read(model.getGraph(), uri, hintLang) ; } /** Read triples into a Model from the given location, with a hint of the language (MIME type or short name) * @param graph Destination for the RDF read. * @param uri URI to read from (includes file: and a plain file name). * @param hintLang Hint for the syntax. * @throws RiotNotFoundException if the location is not found - the graph is unchanged. * @see #read(Graph,String,Lang,Context) */ public static void read(Graph graph, String uri, Lang hintLang) { read(graph, uri, hintLang, (Context)null) ; } /** Read triples into a Model from the given location, with hint of language and with some parameters for the reader * @see #read(Model,String,String,Lang,Context) * Throws parse errors depending on the language and reader; the 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, Lang hintLang) { read(model.getGraph(), uri, base, hintLang) ; } /** Read triples into a Model from the given location, with hint of language and the with some parameters for the reader * @see #read(Graph,String,String,Lang,Context) * Throws parse errors depending on the language and reader; the Model model may be partially updated. * @param graph 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 graph is unchanged. */ public static void read(Graph graph, String uri, String base, Lang hintLang) { read(graph, uri, base, hintLang, (Context)null) ; } /** Read triples into a Model from the given location, with some parameters for the reader * @see #read(Model,String,String,Lang,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. * @throws RiotNotFoundException if the location is not found - the model is unchanged. */ public static void read(Model model, String uri, Context context) { read(model.getGraph(), uri, context) ; } /** Read triples into a Model from the given location, with some parameters for the reader * @see #read(Graph,String,String,Lang,Context) * @param graph 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. * @throws RiotNotFoundException if the location is not found - the graph is unchanged. */ public static void read(Graph graph, String uri, Context context) { read(graph, uri, defaultLang(uri), context) ; } /** Read triples into a Model from the given location, with hint of language and the with some parameters for the reader * @see #read(Model,String,String,Lang,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. * @throws RiotNotFoundException if the location is not found - the model is unchanged. */ public static void read(Model model, String uri, Lang hintLang, Context context) { read(model, uri, defaultBase(uri), hintLang, context) ; } /** Read triples into a Model from the given location, with hint of language and with some parameters for the reader * @see #read(Graph,String,String,Lang,Context) * @param graph 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. * @throws RiotNotFoundException if the location is not found - the graph is unchanged. */ public static void read(Graph graph, String uri, Lang hintLang, Context context) { read(graph, uri, defaultBase(uri), hintLang, context) ; } /** Read triples into a Model from the given location, with hint of language * and with some parameters for the reader. * Throws parse errors depending on the language and reader; the 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, Lang hintLang, Context context) { read(model.getGraph(), uri, base, hintLang, context) ; } /** Read triples into a Model from the given location, with hint of language and the with some parameters for the reader * Throws parse errors depending on the language and reader; the graph may be partially updated. * @param graph 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(Graph graph, String uri, String base, Lang hintLang, Context context) { StreamRDF dest = StreamRDFLib.graph(graph) ; parse(dest, 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, Lang lang) { read(model.getGraph(), in, 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 graph Destination for the RDF read. * @param in InputStream * @param lang Language syntax */ public static void read(Graph graph, InputStream in, Lang lang) { read(graph, in, defaultBase(), 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, Lang lang) { read(model.getGraph(), in, base, 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 graph Destination for the RDF read. * @param in InputStream * @param base Base URI * @param lang Language syntax */ public static void read(Graph graph, InputStream in, String base, Lang lang) { Objects.requireNonNull(in, "InputStream is null") ; StreamRDF dest = StreamRDFLib.graph(graph) ; process(dest, new TypedInputStream(in), base, lang, (Context)null) ; } /** Read triples into a model with chars from an Reader. * Use of 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, Lang lang) { read(model.getGraph(), in, base, lang) ; } /** Read triples into a model with chars from an Reader. * Use of 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 graph Destination for the RDF read. * @param in Reader * @param base Base URI * @param lang Language syntax */ @Deprecated public static void read(Graph graph, Reader in, String base, Lang lang) { StreamRDF dest = StreamRDFLib.graph(graph) ; process(dest, in, base, lang, (Context)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, Lang lang) { Graph g = model.getGraph() ; StreamRDF dest = StreamRDFLib.graph(g) ; process(dest, in, base, lang, (Context)null) ; } /** Read triples into a model with chars from a StringReader. * @param graph Destination for the RDF read. * @param in InputStream * @param base Base URI * @param lang Language syntax */ public static void read(Graph graph, StringReader in, String base, Lang lang) { StreamRDF dest = StreamRDFLib.graph(graph) ; process(dest, in, base, lang, (Context)null) ; } private static Model createModel() { return ModelFactory.createDefaultModel() ; } private static Graph createGraph() { return GraphFactory.createDefaultGraph() ; } private static Dataset createDataset() { return DatasetFactory.createTxnMem() ; } private static DatasetGraph createDatasetGraph() { return DatasetGraphFactory.createTxnMem() ; } // Load: /** Create a memory Model and read in some data * @see #read(Model,String) */ public static Model loadModel(String uri) { Model m = createModel() ; read(m, uri) ; return m ; } /** Create a memory Model and read in some data * @see #read(Model,String,Lang) */ public static Model loadModel(String uri, Lang lang) { Model m = createModel() ; read(m, uri,lang) ; return m ; } //public static Model loadModel(String uri, String base) { return null ; } //public static Model loadModel(String uri, String base, Lang lang) { return null ; } /** Create a memory Graph and read in some data * @see #read(Graph,String) */ public static Graph loadGraph(String uri) { Graph g = createGraph() ; read(g, uri) ; return g ; } /** Create a memory Graph and read in some data * @see #read(Graph,String,Lang) */ public static Graph loadGraph(String uri, Lang lang) { Graph g = createGraph() ; read(g, uri, lang) ; return g ; } // public static Graph loadGraph(String uri, String base) { return null ; } // public static Graph loadGraph(String uri, String base, Lang lang) { return null ; } /** Create a memory Dataset and read in some data * @see #read(Dataset,String) */ public static Dataset loadDataset(String uri) { Dataset ds = createDataset() ; read(ds, uri) ; return ds ; } /** Create a memory Dataset and read in some data * @see #read(Dataset,String,Lang) */ public static Dataset loadDataset(String uri, Lang lang) { Dataset ds = createDataset() ; read(ds, uri, lang) ; return ds ; } // public static Dataset loadDataset(String uri, String base) { return null ; } // public static Dataset loadDataset(String uri, String base, Lang lang) { return null ; } // public static Dataset loadDataset(String uri, String base, Lang lang, Context context) { return null ; } /** Create a memory DatasetGraph and read in some data * @see #read(DatasetGraph,String) */ public static DatasetGraph loadDatasetGraph(String uri) { DatasetGraph ds = createDatasetGraph() ; read(ds, uri) ; return ds ; } /** Create a memory DatasetGraph and read in some data * @see #read(DatasetGraph,String,Lang) */ public static DatasetGraph loadDatasetGraph(String uri, Lang lang) { DatasetGraph ds = createDatasetGraph() ; read(ds, uri, lang) ; return ds ; } // public static DatasetGraph loadDatasetGraph(String uri, String base) { return null ; } // public static DatasetGraph loadDatasetGraph(String uri, String base, Lang lang) { return null ; } // public static DatasetGraph loadDatasetGraph(String uri, String base, Lang lang, Context context) { return null ; } /** Read quads or triples into a Dataset from the given location, with hint of language. * @see #read(Dataset, String, String, Lang, Context) * @param dataset Destination * @param uri URI to read from (includes file: and a plain file name). */ public static void read(Dataset dataset, String uri) { read(dataset.asDatasetGraph(), uri) ; } /** Read quads or triples into a Dataset from the given location, with hint of language. * @see #read(DatasetGraph, String, String, Lang, Context) * @param dataset Destination * @param uri URI to read from (includes file: and a plain file name). */ public static void read(DatasetGraph dataset, String uri) { read(dataset, uri, defaultLang(uri)) ; } /** Read quads or triples into a Dataset from the given location, with hint of language. * @see #read(Dataset, String, String, Lang, 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, Lang hintLang) { read(dataset.asDatasetGraph(), uri, hintLang) ; } /** Read quads or triples into a Dataset from the given location, with hint of language. * @see #read(DatasetGraph, String, String, Lang, 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(DatasetGraph dataset, String uri, Lang hintLang) { read(dataset, uri, hintLang, (Context)null) ; } /** Read quads or triples into a Dataset from the given location, with hint of language. * @see #read(Dataset, String, String, Lang, Context) * @param dataset Destination * @param uri URI to read from (includes file: and a plain file name). * @param base Base URI (defaults to uri). * @param hintLang Language syntax */ public static void read(Dataset dataset, String uri, String base, Lang hintLang) { read(dataset.asDatasetGraph(), uri, base, hintLang) ; } /** Read quads or triples into a Dataset from the given location, with hint of language. * @see #read(DatasetGraph, String, String, Lang, Context) * @param dataset Destination * @param uri URI to read from (includes file: and a plain file name). * @param base Base URI (defaults to uri). * @param hintLang Language syntax */ public static void read(DatasetGraph dataset, String uri, String base, Lang hintLang) { read(dataset, uri, base, hintLang, (Context)null) ; } /** Read quads or triples into a Dataset from the given location. * @see #read(Dataset, String, String, Lang, 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, Lang hintLang, Context context) { read(dataset.asDatasetGraph(), uri, hintLang, context) ; } /** Read quads or triples into a Dataset from the given location. * @see #read(DatasetGraph, String, String, Lang, 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(DatasetGraph dataset, String uri, Lang hintLang, Context context) { read(dataset, uri, defaultBase(uri), hintLang, context) ; } /** Read quads or triples into a Dataset from the given location. * @see #read(Dataset, String, String, Lang, Context) * @param dataset Destination * @param uri URI to read from (includes file: and a plain file name). * @param base Base URI (defaults to uri). * @param hintLang Language syntax * @param context Context for the reader * @throws RiotNotFoundException if the location is not found - the dataset is unchanged. * Throws parse errors depending on the language and reader; the dataset may be partially updated. */ public static void read(Dataset dataset, String uri, String base, Lang hintLang, Context context) { read(dataset.asDatasetGraph(), uri, defaultBase(uri), hintLang, context) ; } /** Read quads or triples into a Dataset from the given location. * @see #read(Dataset, String, String, Lang, Context) * @param dataset Destination * @param uri URI to read from (includes file: and a plain file name). * @param base Base URI (defaults to uri). * @param hintLang Language syntax * @param context Context for the reader * @throws RiotNotFoundException if the location is not found - the dataset is unchanged. * Throws parse errors depending on the language and reader; the dataset may be partially updated. */ public static void read(DatasetGraph dataset, String uri, String base, Lang hintLang, Context context) { StreamRDF sink = StreamRDFLib.dataset(dataset) ; parse(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, Lang lang) { read(dataset.asDatasetGraph(), in, lang) ; } /** 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(DatasetGraph dataset, InputStream in, Lang lang) { read(dataset, in, defaultBase(), 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, Lang lang) { read(dataset.asDatasetGraph(), in, base, 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(DatasetGraph dataset, InputStream in, String base, Lang lang) { Objects.requireNonNull(in, "InputStream is null") ; StreamRDF dest = StreamRDFLib.dataset(dataset) ; process(dest, new TypedInputStream(in), base, lang, (Context)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, Lang lang) { read(dataset.asDatasetGraph(), in, base, lang) ; } /** 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(DatasetGraph dataset, Reader in, String base, Lang lang) { StreamRDF dest = StreamRDFLib.dataset(dataset) ; process(dest, in, base, lang, (Context)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, Lang lang) { read(dataset.asDatasetGraph(), in, base, lang) ; } /** 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(DatasetGraph dataset, StringReader in, String base, Lang lang) { StreamRDF dest = StreamRDFLib.dataset(dataset) ; process(dest, in, base, lang, (Context)null) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param uri URI to read from (includes file: and a plain file name). */ public static void parse(StreamRDF sink, String uri) { parse(sink, uri, defaultLang(uri)) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param uri URI to read from (includes file: and a plain file name). * @param lang Hint for the syntax */ public static void parse(StreamRDF sink, String uri, Lang lang) { parse(sink, uri, lang, (Context)null) ; } /** Read RDF data. * @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 parse(StreamRDF sink, String uri, Lang hintLang, Context context) { parse(sink, uri, defaultBase(uri), hintLang, context) ; } /** Read RDF data. * @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 */ public static void parse(StreamRDF sink, String uri, String base, Lang hintLang) { parse(sink, uri, base, hintLang, (Context)null) ; } /** Read RDF data. * @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 parse(StreamRDF sink, String uri, String base, Lang hintLang, Context context) { if ( uri == null ) throw new IllegalArgumentException("URI to read from is null") ; if ( base == null ) base = SysRIOT.chooseBaseIRI(uri) ; if ( hintLang == null ) hintLang = RDFLanguages.filenameToLang(uri) ; TypedInputStream in = open(uri, context) ; if ( in == null ) throw new RiotException("Not found: "+uri) ; process(sink, in, base, hintLang, context) ; IO.close(in) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param in Bytes to read. * @param lang Syntax for the stream. */ public static void parse(StreamRDF sink, InputStream in, Lang lang) { parse(sink, in, defaultBase(), lang, (Context)null) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param in Bytes to read. * @param base Base URI (defaults to uri). * @param hintLang Hint for the syntax */ public static void parse(StreamRDF sink, InputStream in, String base, Lang hintLang) { parse(sink, in, base, hintLang, (Context)null) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param in Bytes to read. * @param base Base URI (defaults to uri). * @param hintLang Hint for the syntax * @param context Content object to control reading process. */ public static void parse(StreamRDF sink, InputStream in, String base, Lang hintLang, Context context) { process(sink, new TypedInputStream(in), base, hintLang, context) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param in StringReader * @param lang Syntax for the stream. */ public static void parse(StreamRDF sink, StringReader in, Lang lang) { parse(sink, in, defaultBase(), lang, (Context)null) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param in Reader * @param base Base URI (defaults to uri). * @param hintLang Hint for the syntax */ public static void parse(StreamRDF sink, StringReader in, String base, Lang hintLang) { parse(sink, in, base, hintLang, (Context)null) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param in StringReader * @param base Base URI (defaults to uri). * @param hintLang Hint for the syntax * @param context Content object to control reading process. */ public static void parse(StreamRDF sink, StringReader in, String base, Lang hintLang, Context context) { process(sink, in, base, hintLang, context) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param in Reader * @param lang Syntax for the stream. * @deprecated Use an InputStream or a StringReader. */ @Deprecated public static void parse(StreamRDF sink, Reader in, Lang lang) { parse(sink, in, defaultBase(), lang, (Context)null) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param in Reader * @param base Base URI (defaults to uri). * @param hintLang Hint for the syntax * @deprecated Use an InputStream or a StringReader. */ @Deprecated public static void parse(StreamRDF sink, Reader in, String base, Lang hintLang) { parse(sink, in, base, hintLang, (Context)null) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param in Reader * @param base Base URI (defaults to uri). * @param hintLang Hint for the syntax * @param context Content object to control reading process. * @deprecated Use an InputStream or a StringReader. */ @Deprecated public static void parse(StreamRDF sink, Reader in, String base, Lang hintLang, Context context) { process(sink, in, base, hintLang, context) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param in Bytes to read. This must include the content type. */ public static void parse(StreamRDF sink, TypedInputStream in) { parse(sink, in, defaultBase()) ; } /** Read RDF data. * @param sink Destination for the RDF read. * @param in Bytes to read. * @param base Base URI */ public static void parse(StreamRDF sink, TypedInputStream in, String base) { parse(sink, in, base, (Context)null); } /** Read RDF data. * @param sink Destination for the RDF read. * @param in Bytes to read. * @param base Base URI * @param context Content object to control reading process. */ public static void parse(StreamRDF sink, TypedInputStream in, String base, Context context) { Objects.requireNonNull(in, "TypedInputStream is null") ; Lang hintLang = RDFLanguages.contentTypeToLang(in.getMediaType()) ; process(sink, in, base, hintLang, context) ; } /** Open a stream to the destination (URI or filename) * Performs content negotiation, including looking at file extension. * @param filenameOrURI * @return TypedInputStream */ public static TypedInputStream open(String filenameOrURI) { return open(filenameOrURI, (Context)null) ; } /** Open a stream to the destination (URI or filename) * Performs content negotiation, including looking at file extension. * @param filenameOrURI * @param context * @return TypedInputStream */ public static TypedInputStream 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 "+Lib.classShortName(StreamManager.class)) ; } } return open(filenameOrURI, sMgr) ; } /** Open a stream to the destination (URI or filename) * Performs content negotiation, including looking at file extension. * @param filenameOrURI * @param streamManager * @return TypedInputStream */ public static TypedInputStream open(String filenameOrURI, StreamManager streamManager) { TypedInputStream in = streamManager.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 ; } // ----- // 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 Reader object gives the per-run // configuration. private static void process(StreamRDF destination, TypedInputStream in, String baseUri, Lang lang, Context context) { Objects.requireNonNull(in, "TypedInputStream is null") ; ContentType ct = WebContent.determineCT(in.getContentType(), lang, baseUri) ; if ( ct == null ) throw new RiotException("Failed to determine the content type: (URI="+baseUri+" : stream="+in.getContentType()+")") ; ReaderRIOT reader = getReader(ct) ; if ( reader == null ) throw new RiotException("No parser registered for content type: "+ct.getContentType()) ; reader.read(in, baseUri, ct, destination, context) ; } // java.io.Readers are NOT preferred. private static void process(StreamRDF destination, Reader in, String baseUri, Lang lang, Context context ) { Objects.requireNonNull(in, "Reader is null") ; ContentType ct = WebContent.determineCT(null, lang, baseUri) ; if ( ct == null ) throw new RiotException("Failed to determine the content type: (URI="+baseUri+" : hint="+lang+")") ; ReaderRIOT reader = getReader(ct) ; if ( reader == null ) throw new RiotException("No parser registered for content type: "+ct.getContentType()) ; reader.read(in, baseUri, ct, destination, context) ; } /** * @see RDFLanguages#shortnameToLang to go from Jena short name to {@link Lang} * @see RDFLanguages#contentTypeToLang to go from content type to {@link Lang} */ public static ReaderRIOT createReader(Lang lang) { if ( lang == null ) throw new NullPointerException("Argument lang can not be null in RDFDataMgr.createReader") ; ReaderRIOTFactory r = RDFParserRegistry.getFactory(lang) ; if ( r == null ) return null ; return r.create(lang) ; } private static ReaderRIOT getReader(ContentType ct) { Lang lang = RDFLanguages.contentTypeToLang(ct) ; if ( lang == null ) return null ; ReaderRIOTFactory r = RDFParserRegistry.getFactory(lang) ; if ( r == null ) return null ; return r.create(lang) ; } // Operations to remove "null"s in the code. /** Default base - no known URI. e.g. input streams */ private static String defaultBase() { return null ; } /** Default base - URI present */ private static String defaultBase(String uri) { return uri ; } /** Default lang - usually left as unknown so that extended content negotation happens */ private static Lang defaultLang(String uri) { return null; } /** Map {@link Lang} to {@link RDFFormat}, or throw an exception. */ private static RDFFormat langToFormatOrException(Lang lang) { RDFFormat serialization = RDFWriterRegistry.defaultSerialization(lang); if ( serialization == null ) throw new RiotException("No output format for "+lang) ; return serialization ; } /** Determine the Lang, given the URI target, any content type header string and a hint */ public static Lang determineLang(String target, String ctStr, Lang hintLang) { ContentType ct = WebContent.determineCT(ctStr, hintLang, target) ; if ( ct == null ) return hintLang ; Lang lang = RDFLanguages.contentTypeToLang(ct) ; if (lang == null ) return hintLang ; return lang ; } // -------- WRITERS /** Write the model to the output stream in the default serialization for the language. * @param out OutputStream * @param model Graph to write * @param lang Language for the seralization. */ public static void write(OutputStream out, Model model, Lang lang) { write(out, model.getGraph(), lang); } /** Write the model to the output stream in the default serialization for the language. * @param out OutputStream * @param model Model to write * @param serialization Serialization format */ public static void write(OutputStream out, Model model, RDFFormat serialization) { write(out, model.getGraph(), serialization); } /** Write the graph to the output stream in the default serialization for the language. * @param out StringWriter * @param model Model to write * @param lang Serialization format */ public static void write(StringWriter out, Model model, Lang lang) { write(out, model.getGraph(), lang); } /** Write the graph to the output stream in the default serialization for the language. * @param out Writer * @param model Model to write * @param lang Serialization format * @deprecated Use of writers is deprecated - use an OutputStream */ @Deprecated public static void write(Writer out, Model model, Lang lang) { write(out, model.getGraph(), lang); } /** Write the graph to the output stream in the default serialization for the language. * @param out StringWriter * @param model Model to write * @param serialization Serialization format */ public static void write(StringWriter out, Model model, RDFFormat serialization) { write(out, model.getGraph(), serialization); } /** Write the graph to the output stream in the default serialization for the language. * @param out OutputStream * @param model Model to write * @param serialization Serialization format * @deprecated Use of writers is deprecated - use an OutputStream */ @Deprecated public static void write(Writer out, Model model, RDFFormat serialization) { write(out, model.getGraph(), serialization); } /** Write the graph to the output stream in the default serialization for the language. * @param out OutputStream * @param graph Graph to write * @param lang Language for the seralization. */ public static void write(OutputStream out, Graph graph, Lang lang) { RDFFormat serialization = langToFormatOrException(lang); write(out, graph, serialization); } /** Write the graph to the output stream in the default serialization for the language. * @param out OutputStream * @param graph Graph to write * @param serialization Serialization format */ public static void write(OutputStream out, Graph graph, RDFFormat serialization) { write$(out, graph, serialization); } /** Write the graph to the output stream in the default serialization for the language. * @param out StringWriter * @param graph Graph to write * @param lang Serialization format */ public static void write(StringWriter out, Graph graph, Lang lang) { // Only known reasonable use of a Writer write$(out, graph, langToFormatOrException(lang)); } /** Write the graph to the output stream in the default serialization for the language. * @param out Writer * @param graph Graph to write * @param lang Serialization format * @deprecated Use of writers is deprecated - use an OutputStream */ @Deprecated public static void write(Writer out, Graph graph, Lang lang) { write$(out, graph, langToFormatOrException(lang)); } /** Write the graph to the output stream in the default serialization for the language. * @param out OutputStream * @param graph Graph to write * @param serialization Serialization format */ public static void write(StringWriter out, Graph graph, RDFFormat serialization) { // Only known reasonable use of a Writer write$(out, graph, serialization); } /** Write the graph to the output stream in the default serialization for the language. * @param out OutputStream * @param graph Graph to write * @param serialization Serialization format * @deprecated Use of writers is deprecated - use an OutputStream */ @Deprecated public static void write(Writer out, Graph graph, RDFFormat serialization) { write$(out, graph, serialization); } /** Write the Dataset to the output stream in the default serialization for the language. * @param out OutputStream * @param dataset Dataset to write * @param lang Language for the seralization. */ public static void write(OutputStream out, Dataset dataset, Lang lang) { write(out, dataset.asDatasetGraph(), lang); } /** Write the graph to the output stream in the default serialization for the language. * @param out OutputStream * @param dataset Dataset to write * @param serialization Serialization format */ public static void write(OutputStream out, Dataset dataset, RDFFormat serialization) { write(out, dataset.asDatasetGraph(), serialization); } /** Write the graph to the output stream in the default serialization for the language. * @param out Writer * @param dataset Dataset to write * @param serialization Serialization format */ public static void write(StringWriter out, Dataset dataset, RDFFormat serialization) { write$(out, dataset.asDatasetGraph(), serialization); } /** Write the graph to the output stream in the default serialization for the language. * @param out StringWriter * @param dataset Dataset to write * @param lang Language for the seralization. */ public static void write(StringWriter out, Dataset dataset, Lang lang) { RDFFormat serialization = langToFormatOrException(lang); write$(out, dataset.asDatasetGraph(), serialization); } /** Write the graph to the output stream in the default serialization for the language. * @param out Writer * @param dataset Dataset to write * @param serialization Serialization format * @deprecated Use of writers is deprecated - use an OutputStream */ @Deprecated public static void write(Writer out, Dataset dataset, RDFFormat serialization) { write$(out, dataset.asDatasetGraph(), serialization); } /** Write the DatasetGraph to the output stream in the default serialization for the language. * @param out OutputStream * @param dataset DatasetGraph to write * @param lang Language for the seralization. */ public static void write(OutputStream out, DatasetGraph dataset, Lang lang) { RDFFormat serialization = langToFormatOrException(lang); write(out, dataset, serialization); } /** Write the graph to the output stream in the default serialization for the language. * @param out OutputStream * @param dataset DatasetGraph to write * @param serialization Serialization format */ public static void write(OutputStream out, DatasetGraph dataset, RDFFormat serialization) { write$(out, dataset, serialization); } /** Write the DatasetGraph to the output stream in the default serialization for the language. * @param out StringWriter * @param dataset DatasetGraph to write * @param lang Language for the seralization. */ public static void write(StringWriter out, DatasetGraph dataset, Lang lang) { RDFFormat serialization = langToFormatOrException(lang); write(out, dataset, serialization); } /** Write the graph to the output stream in the default serialization for the language. * @param out StringWriter * @param dataset DatasetGraph to write * @param serialization Serialization format */ public static void write(StringWriter out, DatasetGraph dataset, RDFFormat serialization) { write$(out, dataset, serialization); } /** Write the graph to the output stream in the default serialization for the language. * @param out Writer * @param dataset DatasetGraph to write * @param serialization Serialization format * @deprecated Use of writers is deprecated - use an OutputStream */ @Deprecated public static void write(Writer out, DatasetGraph dataset, RDFFormat serialization) { write$(out, dataset, serialization); } /** Write an iterator of triples (in N-Triples) * @param out * @param iterator */ public static void writeTriples(OutputStream out, Iterator<Triple> iterator) { NTriplesWriter.write(out, iterator); } /** Write an iterator of quads (in N-Quads) * @param out * @param iterator */ public static void writeQuads(OutputStream out, Iterator<Quad> iterator) { NQuadsWriter.write(out, iterator); } /** Create a writer for an RDF language * @param lang Language for the seralization. * @return WriterGraphRIOT */ public static WriterGraphRIOT createGraphWriter(Lang lang) { RDFFormat serialization = langToFormatOrException(lang); return createGraphWriter$(serialization); } /** Create a writer for an RDF language * @param serialization Serialization format * @return WriterGraphRIOT */ public static WriterGraphRIOT createGraphWriter(RDFFormat serialization) { return createGraphWriter$(serialization); } /** Create a writer for an RDF language * @param lang Language for the seralization. * @return WriterGraphRIOT */ public static WriterDatasetRIOT createDatasetWriter(Lang lang) { RDFFormat serialization = langToFormatOrException(lang); return createDatasetWriter$(serialization); } /** Create a writer for an RDF language * @param serialization Serialization format * @return WriterGraphRIOT */ public static WriterDatasetRIOT createDatasetWriter(RDFFormat serialization) { return createDatasetWriter$(serialization); } private static WriterGraphRIOT createGraphWriter$(RDFFormat serialization) { WriterGraphRIOTFactory wf = RDFWriterRegistry.getWriterGraphFactory(serialization); if ( wf == null ) throw new RiotException("No graph writer for " + serialization); return wf.create(serialization); } private static WriterDatasetRIOT createDatasetWriter$(RDFFormat serialization) { WriterDatasetRIOTFactory wf = RDFWriterRegistry.getWriterDatasetFactory(serialization); if ( wf == null ) throw new RiotException("No dataset writer for " + serialization); return wf.create(serialization); } private static void write$(OutputStream out, Graph graph, RDFFormat serialization) { WriterGraphRIOT w = createGraphWriter$(serialization); w.write(out, graph, RiotLib.prefixMap(graph), null, RIOT.getContext()); } private static void write$(Writer out, Graph graph, RDFFormat serialization) { WriterGraphRIOT w = createGraphWriter$(serialization); w.write(out, graph, RiotLib.prefixMap(graph), null, RIOT.getContext()); } private static void write$(OutputStream out, DatasetGraph dataset, RDFFormat serialization) { WriterDatasetRIOT w = createDatasetWriter$(serialization); w.write(out, dataset, RiotLib.prefixMap(dataset), null, RIOT.getContext()); } private static void write$(Writer out, DatasetGraph dataset, RDFFormat serialization) { WriterDatasetRIOT w = createDatasetWriter$(serialization); w.write(out, dataset, RiotLib.prefixMap(dataset), null, RIOT.getContext()); } /** * Create an iterator over parsing of triples * @param input Input Stream * @param lang Language * @param baseIRI Base IRI * @return Iterator over the triples */ public static Iterator<Triple> createIteratorTriples(InputStream input, Lang lang, String baseIRI) { // Special case N-Triples, because the RIOT reader has a pull interface if ( RDFLanguages.sameLang(RDFLanguages.NTRIPLES, lang) ) return new IteratorResourceClosing<>(org.apache.jena.riot.lang.RiotParsers.createIteratorNTriples(input, null), input); // Otherwise, we have to spin up a thread to deal with it PipedRDFIterator<Triple> it = new PipedRDFIterator<>(); PipedTriplesStream out = new PipedTriplesStream(it); Thread t = new Thread(()->parse(out, input, baseIRI, lang)) ; t.start(); return it; } /** * Creates an iterator over parsing of quads * @param input Input Stream * @param lang Language * @param baseIRI Base IRI * @return Iterator over the quads */ public static Iterator<Quad> createIteratorQuads(InputStream input, Lang lang, String baseIRI) { // Special case N-Quads, because the RIOT reader has a pull interface if ( RDFLanguages.sameLang(RDFLanguages.NQUADS, lang) ) return new IteratorResourceClosing<>(org.apache.jena.riot.lang.RiotParsers.createIteratorNQuads(input, null), input); // Otherwise, we have to spin up a thread to deal with it final PipedRDFIterator<Quad> it = new PipedRDFIterator<>(); final PipedQuadsStream out = new PipedQuadsStream(it); Thread t = new Thread(()->parse(out, input, baseIRI, lang)) ; t.start(); return it; } }