blob: 206a162d3ce66a9a121ee0f3927c60a8601f836f [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 static org.apache.jena.riot.resultset.ResultSetLang.SPARQLResultSetCSV;
import static org.apache.jena.riot.resultset.ResultSetLang.SPARQLResultSetJSON;
import static org.apache.jena.riot.resultset.ResultSetLang.SPARQLResultSetTSV;
import static org.apache.jena.riot.resultset.ResultSetLang.SPARQLResultSetXML;
import java.io.ByteArrayOutputStream ;
import java.io.OutputStream ;
import java.io.UnsupportedEncodingException ;
import java.nio.charset.StandardCharsets ;
import java.util.ArrayList ;
import java.util.Iterator ;
import java.util.List ;
import org.apache.jena.atlas.io.IndentedWriter;
import org.apache.jena.atlas.json.JsonObject;
import org.apache.jena.atlas.logging.Log ;
import org.apache.jena.rdf.model.RDFNode ;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.ResultSetMgr ;
import org.apache.jena.riot.resultset.rw.ResultsWriter;
import org.apache.jena.shared.PrefixMapping ;
import org.apache.jena.sparql.ARQException ;
import org.apache.jena.sparql.ARQNotImplemented ;
import org.apache.jena.sparql.core.Prologue ;
import org.apache.jena.sparql.resultset.ResultsFormat;
import org.apache.jena.sparql.resultset.TextOutput;
import org.apache.jena.sparql.resultset.XMLOutput;
import org.apache.jena.sparql.serializer.SerializationContext ;
import org.apache.jena.sys.JenaSystem;
/** ResultSetFormatter - Convenience ways to call the various output formatters.
* in various formats.
* @see ResultSetMgr
*/
public class ResultSetFormatter {
static { JenaSystem.init(); }
// See also ResultSetMgr -- this post-dates this code.
// Ideally, the operation here should call ResultSetMgr.
private ResultSetFormatter() {}
/**
* Output a result set in a text format. The result set is consumed.
* Use @see{ResultSetFactory.makeRewindable(ResultSet)} for a rewindable one.
* <p>
* This caches the entire results in memory in order to determine the appropriate
* column widths and therefore may exhaust memory for large results
* </p>
* @param qresults result set
*/
public static void out(ResultSet qresults)
{ out(System.out, qresults) ; }
/**
* Output a result set in a text format. The result set is consumed.
* Use @see{ResultSetFactory.makeRewindable(ResultSet)} for a rewindable one.
* <p>
* This caches the entire results in memory in order to determine the appropriate
* column widths and therefore may exhaust memory for large results
* </p>
* @param out OutputStream
* @param qresults result set
*/
public static void out(OutputStream out, ResultSet qresults)
{ out(out, qresults, (PrefixMapping)null) ; }
/**
* Output a result set in a text format. The result set is consumed.
* Use @see{ResultSetFactory.makeRewindable(ResultSet)} for a rewindable one.
* <p>
* This caches the entire results in memory in order to determine the appropriate
* column widths and therefore may exhaust memory for large results
* </p>
* @param qresults result set
* @param query May be used to abbreviate URIs
*/
public static void out(ResultSet qresults, Query query)
{ out(System.out, qresults, query) ; }
/**
* Output a result set in a text format. The result set is consumed.
* Use @see{ResultSetFactory.makeRewindable(ResultSet)} for a rewindable one.
* <p>
* This caches the entire results in memory in order to determine the appropriate
* column widths and therefore may exhaust memory for large results
* </p>
* @param qresults result set
* @param prologue May be used to abbreviate URIs
*/
public static void out(ResultSet qresults, Prologue prologue)
{ out(System.out, qresults, prologue) ; }
// /**
// * Output a result set in a text format.
// * @param out OutputStream
// * @param qresults result set
// * @param query May be used to abbreviate URIs
// */
// public static void out(OutputStream out, ResultSet qresults, Query query)
// { out(out, qresults, query.getPrefixMapping()) ; }
/**
* Output a result set in a text format. The result set is consumed.
* Use @see{ResultSetFactory.makeRewindable(ResultSet)} for a rewindable one.
* <p>
* This caches the entire results in memory in order to determine the appropriate
* column widths and therefore may exhaust memory for large results
* </p>
* @param qresults result set
* @param pmap Prefix mapping for abbreviating URIs.
*/
public static void out(ResultSet qresults, PrefixMapping pmap)
{ out(System.out, qresults, pmap) ; }
/**
* Output a result set in a text format. The result set is consumed.
* Use @see{ResultSetFactory.makeRewindable(ResultSet)} for a rewindable one.
* <p>
* This caches the entire results in memory in order to determine the appropriate
* column widths and therefore may exhaust memory for large results
* </p>
* @param out OutputStream
* @param qresults result set
* @param pmap Prefix mapping for abbreviating URIs.
*/
public static void out(OutputStream out, ResultSet qresults, PrefixMapping pmap)
{
TextOutput tFmt = new TextOutput(pmap) ;
tFmt.format(out, qresults) ;
}
/**
* Output a result set in a text format. The result set is consumed.
* Use @see{ResultSetFactory.makeRewindable(ResultSet)} for a rewindable one.
* <p>
* This caches the entire results in memory in order to determine the appropriate
* column widths and therefore may exhaust memory for large results
* </p>
* @param out OutputStream
* @param qresults result set
* @param prologue Prologue, used to abbreviate IRIs
*/
public static void out(OutputStream out, ResultSet qresults, Prologue prologue)
{
TextOutput tFmt = new TextOutput(prologue) ;
tFmt.format(out, qresults) ;
}
/**
* Output an ASK answer
* @param answer The boolean answer
*/
public static void out(boolean answer)
{ out(System.out, answer) ; }
/**
* Output an ASK answer
* @param out OutputStream
* @param answer The boolean answer
*/
public static void out(OutputStream out, boolean answer)
{
TextOutput tFmt = new TextOutput((SerializationContext)null) ;
tFmt.format(out, answer) ;
}
/** Return a string that has the result set serialized as a text table
* <p>
* This caches the entire results in memory in order to determine the appropriate
* column widths and therefore may exhaust memory for large results
* </p>
*
* @param qresults result set
* @return string
*/
public static String asText(ResultSet qresults)
{
ByteArrayOutputStream arr = new ByteArrayOutputStream() ;
out(arr, qresults) ;
return new String(arr.toByteArray(), StandardCharsets.UTF_8) ;
}
/** Return a string that has the result set serialized as a text table
* <p>
* This caches the entire results in memory in order to determine the appropriate
* column widths and therefore may exhaust memory for large results
* </p>
*
* @param qresults result set
* @param prologue Prologue, used to abbreviate IRIs
* @return string
*/
public static String asText(ResultSet qresults, Prologue prologue)
{
ByteArrayOutputStream arr = new ByteArrayOutputStream() ;
out(arr, qresults, prologue) ;
try { return new String(arr.toByteArray(), "UTF-8") ; }
catch (UnsupportedEncodingException e)
{
Log.warn(ResultSetFormatter.class, "UnsupportedEncodingException") ;
return null ;
}
}
// ----------------------------------------------------------------
// Do nothing formatting
/** This operation faithfully walks the results but does nothing with them.
* @return The count of the number of solutions.
*/
public static int consume(ResultSet resultSet)
{
int count = 0 ;
for ( ; resultSet.hasNext() ; )
{
// Force nodes to be materialized.
QuerySolution result = resultSet.nextSolution() ;
materialize(result);
count++ ;
}
return count ;
}
/**
* Turn the result set into a java.util.List
* @param resultSet The result set
* @return List of QuerySolutions
*/
static public List<QuerySolution> toList(ResultSet resultSet)
{
List<QuerySolution> list = new ArrayList<>() ;
for ( ; resultSet.hasNext() ; ) {
QuerySolution result = resultSet.nextSolution() ;
materialize(result);
list.add(result) ;
}
return list ;
}
/** Touch every var/value */
private static void materialize(QuerySolution qs) {
for ( Iterator<String> iter = qs.varNames() ; iter.hasNext() ; ) {
String vn = iter.next();
RDFNode n = qs.get(vn) ;
}
}
/** Output a ResultSet in some format.
*
* @param resultSet Result set
* @param rFmt A format to encode the result set in
*/
static public void output(ResultSet resultSet, ResultsFormat rFmt)
{ output(System.out, resultSet, rFmt) ; }
/** Output a ResultSet in some format.
* To get detailed control over each format, call the appropriate operation directly.
*
* @param outStream Output
* @param resultSet Result set
* @param rFmt A format to encode the result set in
*/
static public void output(OutputStream outStream, ResultSet resultSet, ResultsFormat rFmt) {
Lang lang = ResultsFormat.convert(rFmt);
if ( lang != null ) {
output(outStream, resultSet, lang);
return ;
}
boolean b = ResultsFormat.oldWrite(outStream, rFmt, null, resultSet);
if ( b )
return ;
throw new ARQException("Unknown ResultSet format: " + rFmt) ;
}
// ---- General Output
public static void output(ResultSet resultSet, Lang resultFormat) {
output(System.out, resultSet, resultFormat);
}
public static void output(OutputStream outStream, ResultSet resultSet, Lang resultFormat) {
ResultsWriter.create().lang(resultFormat).write(outStream, resultSet);
}
public static void output(boolean result, Lang resultFormat) {
output(System.out, result, resultFormat);
}
public static void output(OutputStream outStream, boolean result, Lang resultFormat) {
ResultsWriter.create().lang(resultFormat).build().write(outStream, result);
}
/** Output an iterator of JSON values.
*
* @param outStream output stream
* @param jsonItems The JSON values
*/
public static void output(OutputStream outStream, Iterator<JsonObject> jsonItems)
{
IndentedWriter out = new IndentedWriter(outStream) ;
out.println("[") ;
out.incIndent() ;
while (jsonItems.hasNext())
{
JsonObject jsonItem = jsonItems.next() ;
jsonItem.output(out) ;
if ( jsonItems.hasNext() )
out.println(" ,");
else
out.println();
}
out.decIndent();
out.println("]");
out.flush();
}
// ---- General Output
// ---- XML Output
/** Output a result set in the XML format
*
* @param qresults result set
*/
static public void outputAsXML(ResultSet qresults)
{ outputAsXML(System.out, qresults) ; }
/** Output a result set in the XML format
*
* @param outStream output stream
* @param qresults result set
*/
static public void outputAsXML(OutputStream outStream, ResultSet qresults)
{ output(outStream, qresults, SPARQLResultSetXML); }
/** Output a result set in the XML format, inserting a style sheet in the XML output
*
* @param qresults result set
* @param stylesheet The URL of the stylesheet
*/
static public void outputAsXML(ResultSet qresults, String stylesheet)
{ outputAsXML(System.out, qresults, stylesheet); }
/** Output a result set in the XML format, inserting a style sheet in the XML output
*
* @param outStream output stream
* @param qresults result set
* @param stylesheet The URL of the stylesheet
*/
static public void outputAsXML(OutputStream outStream, ResultSet qresults, String stylesheet)
{
XMLOutput xOut = new XMLOutput(stylesheet) ;
xOut.format(outStream, qresults) ;
}
// ---- XML output: ASK
/** Output a boolean result in the XML format
*
* @param booleanResult The boolean result to encode
*/
public static void outputAsXML(boolean booleanResult)
{ outputAsXML(System.out, booleanResult) ; }
/** Output a boolean result in the XML format
*
* @param outStream output stream
* @param booleanResult The boolean result to encode
*/
public static void outputAsXML(OutputStream outStream, boolean booleanResult)
{ output(outStream, booleanResult, SPARQLResultSetXML); }
/** Output a boolean result in the XML format
*
* @param booleanResult
* @param stylesheet The URL of the stylesheet
*/
public static void outputAsXML(boolean booleanResult, String stylesheet)
{ outputAsXML(System.out, booleanResult, stylesheet) ; }
/** Output a boolean result in the XML format
*
* @param outStream output stream
* @param booleanResult
* @param stylesheet The URL of the stylesheet
*/
public static void outputAsXML(OutputStream outStream, boolean booleanResult, String stylesheet) {
XMLOutput xOut = new XMLOutput(stylesheet);
xOut.format(outStream, booleanResult);
}
/** Return a string that has the result set serialized as XML (not RDF)
* <p>
* This builds the string in memory which can lead to memory exhaustion
* for large results. It is generally better to use the
* {@link #outputAsXML(OutputStream, ResultSet)} overload instead
* </p>
*
* @param qresults result set
* @return string
*/
public static String asXMLString(ResultSet qresults)
{
return asXMLString(qresults, null) ;
}
/** Return a string that has the result set serialized as XML (not RDF)
* with a style sheet directive inserted into the XML.
* <p>
* This builds the string in memory which can lead to memory exhaustion
* for large results. It is generally better to use the
* {@link #outputAsXML(OutputStream, ResultSet, String)} overload instead
* </p>
* @param qresults result set
* @param stylesheet
* @return string
*/
public static String asXMLString(ResultSet qresults, String stylesheet)
{
XMLOutput xOut = new XMLOutput(stylesheet) ;
return xOut.asString(qresults) ;
}
/** Return a string that has the result set serialized as XML (not RDF)
* <p>
* This builds the string in memory which can lead to memory exhaustion
* for large results. It is generally better to use the
* {@link #outputAsXML(OutputStream, boolean)} overload instead
* </p>
*
* @param booleanResult The boolean result to encode
* @return string
*/
public static String asXMLString(boolean booleanResult)
{
return asXMLString(booleanResult, null) ;
}
/** Return a string that has the result set serialized as XML (not RDF)
* <p>
* This builds the string in memory which can lead to memory exhaustion
* for large results. It is generally better to use the
* {@link #outputAsXML(OutputStream, boolean, String)} overload instead
* </p>
*
* @param booleanResult The boolean result to encode
* @param stylesheet
* @return string
*/
public static String asXMLString(boolean booleanResult, String stylesheet)
{
XMLOutput xOut = new XMLOutput(stylesheet) ;
return xOut.asString(booleanResult) ;
}
// ---- JSON
/** Output a result set in the JSON format
* Format: <a href="http://www.w3.org/TR/rdf-sparql-json-res/">Serializing SPARQL Query Results in JSON</a>
* JSON: <a href="http://json.org">http://json.org/</a>
* @param resultSet result set
*/
static public void outputAsJSON(ResultSet resultSet)
{ outputAsJSON(System.out, resultSet) ; }
/** Output a result set in the JSON format
* Format: <a href="http://www.w3.org/TR/rdf-sparql-json-res/">Serializing SPARQL Query Results in JSON</a>
* JSON: <a href="http://json.org">http://json.org/</a>
*
* @param outStream output stream
* @param resultSet result set
*/
static public void outputAsJSON(OutputStream outStream, ResultSet resultSet)
{ output(outStream, resultSet, SPARQLResultSetJSON) ; }
/** Output a result set in the JSON format
* Format: <a href="http://www.w3.org/TR/rdf-sparql-json-res/">Serializing SPARQL Query Results in JSON</a>
* JSON: <a href="http://json.org">http://json.org/</a>
*
* @param booleanResult The boolean result to encode
*/
static public void outputAsJSON(boolean booleanResult)
{ outputAsJSON(System.out, booleanResult) ; }
/** Output a result set in the JSON format
* Format: <a href="http://www.w3.org/TR/rdf-sparql-json-res/">Serializing SPARQL Query Results in JSON</a>
* JSON: <a href="http://json.org">http://json.org/</a>
*
* @param outStream output stream
* @param booleanResult The boolean result to encode
*/
static public void outputAsJSON(OutputStream outStream, boolean booleanResult)
{ output(outStream, booleanResult, SPARQLResultSetJSON) ; }
// ---- SSE
/** Output a boolean result in the SSE format
* Format: <a href="http://jena.apache.org/documentation/notes/sse.html">SSE</a>
*
* @param booleanResult The boolean result to encode
*/
static public void outputAsSSE(boolean booleanResult)
{ outputAsSSE(System.out, booleanResult ) ; }
/** Output a boolean result in the SSE format
* Format: <a href="http://jena.apache.org/documentation/notes/sse.html">SSE</a>
*
* @param outStream output stream
* @param booleanResult The boolean result to encode
*/
static public void outputAsSSE(OutputStream outStream, boolean booleanResult)
{
throw new ARQNotImplemented("outputAsSSE") ;
}
/** Output a result set in the SSE format
* Format: <a href="http://jena.apache.org/documentation/notes/sse.html">SSE</a>
* @param resultSet result set
*/
static public void outputAsSSE(ResultSet resultSet)
{ outputAsSSE(System.out, resultSet) ; }
/** Output a result set in the SSE format
* Format: <a href="http://jena.apache.org/documentation/notes/sse.html">SSE</a>
* @param resultSet result set
*/
static public void outputAsSSE(ResultSet resultSet, Prologue prologue)
{ outputAsSSE(System.out, resultSet, prologue) ; }
/** Output a result set in the SSE format
* Format: <a href="http://jena.apache.org/documentation/notes/sse.html">SSE</a>
* @param outStream The output stream
* @param resultSet The result set
*/
static public void outputAsSSE(OutputStream outStream, ResultSet resultSet)
{ outputAsSSE(outStream, resultSet, null) ; }
/** Output a result set in the SSE format
* Format: <a href="http://jena.apache.org/documentation/notes/sse.html">SSE</a>
* @param outStream output stream
* @param resultSet result set
* @param prologue
*/
static public void outputAsSSE(OutputStream outStream, ResultSet resultSet, Prologue prologue)
{
throw new ARQNotImplemented("outputAsSSE") ;
}
// ---- CSV
/** Output a boolean result in CSV format
*
* @param booleanResult The boolean result to encode
*/
static public void outputAsCSV(boolean booleanResult)
{ outputAsCSV(System.out, booleanResult ) ; }
/** Output a boolean result in CSV format
*
* @param outStream output stream
* @param booleanResult The boolean result to encode
*/
static public void outputAsCSV(OutputStream outStream, boolean booleanResult)
{ output(outStream, booleanResult, SPARQLResultSetCSV); }
/** Output a result set in CSV format
* @param resultSet result set
*/
static public void outputAsCSV(ResultSet resultSet)
{ outputAsCSV(System.out, resultSet) ; }
/** Output a result set in CSV format
* @param outStream The output stream
* @param resultSet The result set
*/
static public void outputAsCSV(OutputStream outStream, ResultSet resultSet)
{ output(outStream, resultSet, SPARQLResultSetCSV); }
// ---- TSV
/** Output a boolean result in TSV (tab separated values) format
*
* @param booleanResult The boolean result to encode
*/
static public void outputAsTSV(boolean booleanResult)
{ outputAsTSV(System.out, booleanResult ) ; }
/** Output a boolean result in TSV format
*
* @param outStream output stream
* @param booleanResult The boolean result to encode
*/
static public void outputAsTSV(OutputStream outStream, boolean booleanResult)
{ output(outStream, booleanResult, SPARQLResultSetTSV); }
/** Output a result set in TSV format
* @param resultSet result set
*/
static public void outputAsTSV(ResultSet resultSet)
{ outputAsTSV(System.out, resultSet) ; }
/** Output a result set in TSV format
* @param outStream The output stream
* @param resultSet The result set
*/
static public void outputAsTSV(OutputStream outStream, ResultSet resultSet)
{ output(outStream, resultSet, SPARQLResultSetTSV); }
}