blob: ae94e2e2127c2bee05199c729a4022094746e171 [file] [log] [blame]
/*
* 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.query;
import java.io.IOException;
import java.io.InputStream ;
import java.util.List ;
import org.apache.jena.atlas.io.IO ;
import org.apache.jena.atlas.io.IOX;
import org.apache.jena.atlas.logging.Log ;
import org.apache.jena.rdf.model.Model ;
import org.apache.jena.rdf.model.ModelFactory ;
import org.apache.jena.riot.Lang ;
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.riot.ReadAnything;
import org.apache.jena.riot.ResultSetMgr ;
import org.apache.jena.riot.resultset.ResultSetLang;
import org.apache.jena.riot.resultset.ResultSetOnClose;
import org.apache.jena.sparql.core.Var;
import org.apache.jena.sparql.engine.QueryIterator ;
import org.apache.jena.sparql.engine.ResultSetStream ;
import org.apache.jena.sparql.exec.RowSet;
import org.apache.jena.sparql.graph.GraphFactory ;
import org.apache.jena.sparql.resultset.* ;
/** ResultSetFactory - make result sets from places other than a query. */
public class ResultSetFactory {
// See also ResultSetMgr - which post-dates this code.
// Ideally, read operations here should call ResultSetMgr.
// The exception is XML from a string and the archaic RDF to ResultSet forms.
/**
* Load a result set from file or URL into a result set (memory backed).
*
* @param filenameOrURI
* @return ResultSet
*/
public static ResultSet load(String filenameOrURI) {
return load(filenameOrURI, null);
}
/**
* Load a result set from file or URL into a result set (memory backed).
*
* @param filenameOrURI
* @param format
* @return ResultSet
*/
public static ResultSet load(String filenameOrURI, ResultsFormat format) {
if (format == null)
format = ResultsFormat.guessSyntax(filenameOrURI);
// Result sets are iterators.
// The input stream isn't finished with when the result set is created.
// Close input stream when the result set is finished with
// (exhausted or closed).
InputStream in = IO.openFile(filenameOrURI) ;
ResultSet rs = load(in, format) ;
Runnable onClose = ()-> {
try { in.close(); }
catch (IOException ex) { throw IOX.exception(ex); }
};
ResultSet rs2 = new ResultSetOnClose(rs, onClose);
return rs;
}
/**
* Load a result set from input stream into a result set (memory backed).
*
* @param input
* @param format
* @return ResultSet
*/
public static ResultSet load(InputStream input, ResultsFormat format) {
if (format == null) {
Log.warn(ResultSet.class, "Null format - defaulting to XML");
format = ResultsFormat.FMT_RS_XML;
}
// Old World - new world
Lang lang = ResultsFormat.convert(format) ;
if ( lang != null )
return ResultSetMgr.read(input, lang) ;
if (format.equals(ResultsFormat.FMT_TEXT)) {
Log.warn(ResultSet.class, "Can't read a text result set");
throw new ResultSetException("Can't read a text result set");
}
if (format.equals(ResultsFormat.FMT_RDF_XML)) {
Model m = ModelFactory.createDefaultModel();
m.read(input, null);
return RDFInput.fromRDF(m);
}
if (format.equals(ResultsFormat.FMT_RDF_TTL)) {
Model m = ModelFactory.createDefaultModel();
m.read(input, null, "TURTLE");
return RDFInput.fromRDF(m);
}
if (format.equals(ResultsFormat.FMT_RDF_N3)) {
Model m = ModelFactory.createDefaultModel();
m.read(input, null, "N3");
return RDFInput.fromRDF(m);
}
if (format.equals(ResultsFormat.FMT_RDF_NT)) {
Model m = ModelFactory.createDefaultModel();
m.read(input, null, "N-TRIPLES");
return RDFInput.fromRDF(m);
}
Log.warn(ResultSet.class, "Unknown result set syntax: " + format);
return null;
}
/**
* Load a result set (or any other model) from file or URL
*
* @param filenameOrURI
* @return Model
*/
public static Model loadAsModel(String filenameOrURI) {
return loadAsModel(null, filenameOrURI, null);
}
/**
* Load a result set (or any other model) from file or URL
*
* @param model
* Load into this model (returned)
* @param filenameOrURI
* @return Model
*/
public static Model loadAsModel(Model model, String filenameOrURI) {
return loadAsModel(model, filenameOrURI, null);
}
/**
* Load a result set (or any other model) from file or URL
*
* @param filenameOrURI
* @param format
* @return Model
*/
public static Model loadAsModel(String filenameOrURI, ResultsFormat format) {
return loadAsModel(null, filenameOrURI, format);
}
/**
* Load a result set (or any other model) from file or URL. Does not have to
* be a result set (e.g. CONSTRUCt results) but it does interpret the
* ResultSetFormat possibilities.
*
* @param model
* Load into this model (returned)
* @param filenameOrURI
* @param format
* @return Model
* @deprecated This function will become be internal.
*/
@Deprecated
public static Model loadAsModel(Model model, String filenameOrURI, ResultsFormat format) {
if (model == null)
model = GraphFactory.makeDefaultModel();
if (format == null)
format = ResultsFormat.guessSyntax(filenameOrURI);
if (format == null) {
Log.warn(ResultSet.class, "Null format - defaulting to XML");
format = ResultsFormat.FMT_RS_XML;
}
if (format.equals(ResultsFormat.FMT_TEXT)) {
Log.error(ResultSet.class, "Can't read a text result set");
throw new ResultSetException("Can't read a text result set");
}
if (format.equals(ResultsFormat.FMT_RS_XML) || format.equals(ResultsFormat.FMT_RS_JSON)) {
SPARQLResult x = ReadAnything.read(filenameOrURI);
if (x.isResultSet())
RDFOutput.encodeAsRDF(model, x.getResultSet());
else if ( x.isBoolean() )
RDFOutput.encodeAsRDF(model, x.getBooleanResult());
else
throw new ResultSetException("Not a result set");
return model;
}
if (ResultsFormat.isRDFGraphSyntax(format)) {
RDFDataMgr.read(model, filenameOrURI);
return model;
}
Log.error(ResultSet.class, "Unknown result set syntax: " + format);
return null;
}
/**
* Read in any kind of result kind (result set, boolean, graph) Guess the
* syntax based on filename/URL extension.
*/
public static SPARQLResult result(String filenameOrURI) {
return ReadAnything.read(filenameOrURI);
}
/**
* Read XML which is the format of the SPARQL result set format.
*
* @param in
* InputStream
* @return ResultSet
*/
public static ResultSet fromXML(InputStream in) {
return ResultSetMgr.read(in, ResultSetLang.RS_XML);
}
/**
* Read from an input stream which is the format of the SPARQL result set
* format in JSON.
*
* @param in
* InputStream
* @return ResultSet
*/
public static ResultSet fromJSON(InputStream in) {
return ResultSetMgr.read(in, ResultSetLang.RS_JSON);
}
/**
* Turns an RDF model, with properties and classes from the result set
* vocabulary, into a SPARQL result set. The result set formed is a copy in
* memory.
*
* @param model
* @return ResultSet
*/
public static ResultSet makeResults(Model model) {
return new RDFInput(model);
}
/**
* Turns an RDF model, with properties and classes from the result set
* vocabulary, into a SPARQL result set which is rewindable (has a
* .reset()operation). The result set formed is a copy in memory.
*
* @param model
* @return ResultSetRewindable
*/
public static ResultSetRewindable makeRewindable(Model model) {
return new RDFInput(model);
}
/**
* Turn an existing result set into a rewindable one.
* May take a copy but this is not guaranteed
* Uses up the result set passed in which is no longer valid as a ResultSet.
*
* @param resultSet
* @return ResultSetRewindable
*/
public static ResultSetRewindable makeRewindable(ResultSet resultSet) {
if ( resultSet instanceof ResultSetRewindable ) {
ResultSetRewindable rsw = (ResultSetRewindable)resultSet;
rsw.reset();
return rsw;
}
return new ResultSetMem(resultSet);
}
/**
* Turn a row set into a rewindable ResultSet.
* Uses up the result set passed in which is no longer valid as a RowSet.
*
* @param rowSet
* @return ResultSetRewindable
*/
public static ResultSetRewindable makeRewindable(RowSet rowSet) {
return makeRewindable(ResultSet.adapt(rowSet));
}
/**
* Turns an existing result set into one with peeking capabilities
* <p>
* Using the returned result set consumes the result set passed in, the
* underlying result set must be at the start in order to be made peeking.
* If you create such a result set you should avoid accessing the underlying
* result set directly as this may cause results to be missed or put the
* returned peekable result set into an invalid state.
* </p>
* <p> Note that rewindable results may typically also be peekable so may
* be more broadly applicable if you can afford the cost of loading all the
* results into memory. </p>
*
* @param resultSet
* Result set to wrap
* @return Peekable results
*/
public static ResultSetPeekable makePeekable(ResultSet resultSet) {
return new ResultSetPeeking(resultSet);
}
/** Return a closable resultset for a {@link QueryExecution}.
* The {@link QueryExecution} must be for a {@code SELECT} query.
* <p>
* Example:
* <pre>
* QueryExecution qExec = QueryExecutionFactory.create(...);
* try (ResultSetCloseable rs = ResultSetFactory.closableResultSet(qExec) ) {
* ...
* }
* </pre>
*
* @param queryExecution {@code QueryExecution} must be for a {@code SELECT} query.
* @return ResultSetCloseable
*/
public static ResultSetCloseable closeableResultSet(QueryExecution queryExecution) {
return ResultSetCloseable.closeableResultSet(queryExecution);
}
/**
* Take a copy of a result set - the result set returns is an in-memory
* copy. It is not attached to the original query execution object which can
* be closed.
*
* @param results
* @return ResultSet
*/
public static ResultSetRewindable copyResults(ResultSet results) {
return new ResultSetMem(results);
}
/**
* Build a result set from one of ARQ's lower level query iterator.
*
* @param queryIterator
* @param vars
* List of variables, by name, for the result set
* @return ResultSet
*/
public static ResultSet create(QueryIterator queryIterator, List<String> vars) {
return ResultSetStream.create(Var.varList(vars), queryIterator);
}
}