package org.aksw.jena_sparql_api.utils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.util.Iterator;
import org.aksw.commons.util.reflect.MultiMethod;
import org.apache.commons.collections15.Transformer;
import org.apache.jena.atlas.lib.Sink;
import org.apache.jena.riot.out.SinkTripleOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.jena.graph.Triple;
import org.apache.jena.query.ResultSet;
import org.apache.jena.query.ResultSetFormatter;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Statement;
import com.talis.rdfwriters.json.JSONJenaWriter;
/**
* getFormatter(Text, Model).format(Obje)
*
* @author raven
*
*/
public class SparqlFormatterUtils {
public static final Logger logger = LoggerFactory.getLogger(SparqlFormatterUtils.class);
public static Model triplesToModel(Iterator<Triple> iterator) {
Model model = ModelFactory.createDefaultModel();
while(iterator.hasNext()) {
Triple triple = iterator.next();
Statement stmt = org.apache.jena.sparql.util.ModelUtils.tripleToStatement(model, triple);
if(stmt == null) {
logger.warn("Invalid triple detected: " + triple);
continue;
}
model.add(stmt);
}
return model;
}
public static final String FORMAT_XML = "Xml";
public static final String FORMAT_Text = "Text";
public static final String FORMAT_Turtle = "Turtle";
public static final String FORMAT_RdfXml = "RdfXml";
// public static final String FORMAT_ = "";
public static final String FORMAT_Json = "Json";
public static <I, O> Transformer<I, O> wrapMethod(final Method method) {
return method == null ? null : new Transformer<I, O>() {
@SuppressWarnings("unchecked")
@Override
public O transform(I input) {
try {
return (O) method.invoke(null, input);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
}
public static Transformer<Model, String> getModelFormatter(String format) {
Method method = MultiMethod.findMethodByParams(
SparqlFormatterUtils.class, "_format" + format, Model.class);
return wrapMethod(method);
}
public static Transformer<Boolean, String> getBooleanFormatter(String format) {
Method method = MultiMethod.findMethodByParams(
SparqlFormatterUtils.class, "_format" + format, Boolean.class);
return wrapMethod(method);
}
public static Transformer<ResultSet, String> getResultSetFormatter(
String format) {
Method method = MultiMethod
.findMethodByParams(SparqlFormatterUtils.class, "_format"
+ format, ResultSet.class);
return wrapMethod(method);
}
public static <T> Writer<T> wrapAsWriter(final Method method) {
return method == null ? null : new Writer<T>() {
@Override
public void write(OutputStream out, T obj) {
try {
method.invoke(null, out, obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
}
public static Writer<Iterator<Triple>> getTripleWriter(String format) {
Method method = MultiMethod.findMethodByParams(
SparqlFormatterUtils.class, "write" + format,
OutputStream.class, Iterator.class);
return wrapAsWriter(method);
}
public static Writer<Model> getModelWriter(String format) {
Method method = MultiMethod.findMethodByParams(
SparqlFormatterUtils.class, "write" + format,
OutputStream.class, Model.class);
return wrapAsWriter(method);
}
public static Writer<Boolean> getBooleanWriter(String format) {
Method method = MultiMethod.findMethodByParams(
SparqlFormatterUtils.class, "write" + format,
OutputStream.class, Boolean.class);
return wrapAsWriter(method);
}
public static Writer<ResultSet> getResultSetWriter(String format) {
Method method = MultiMethod.findMethodByParams(
SparqlFormatterUtils.class, "write" + format,
OutputStream.class, ResultSet.class);
return wrapAsWriter(method);
}
/*************************************************************************
* XML
*************************************************************************/
// String
// public static String formatXml(Object o) {
// return MultiMethod.invokeStatic(HttpSparqlEndpoint.class, "_formatXml", o);
// }
public static String _formatXml(Boolean value) {
String result = "<sparql xmlns='http://www.w3.org/2005/sparql-results#' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.w3.org/2001/sw/DataAccess/rf1/result2.xsd'>\n"
+ "<head></head>\n"
+ "<boolean>"
+ value
+ "</boolean>"
+ "</sparql>";
return result;
}
public static String _formatXml(Model model) {
return _formatRdfXml(model);
}
public static String _formatRdfXml(Model model) {
return ModelUtils.toString(model, "RDF/XML");
}
public static String _formatXml(ResultSet rs) {
return ResultSetFormatter.asXMLString(rs);
}
// OutputStream
// public static String _writeXml(OutputStream out, Object o) {
// return MultiMethod.invokeStatic(HttpSparqlEndpoint.class, "writeXml",
// out, o);
// }
/**
*
* TODO Add streaming support
*
* @param out
* @param iterator
*/
public static void writeXml(OutputStream out, Iterator<Triple> iterator) {
Model model = triplesToModel(iterator);
writeXml(out, model);
}
public static void writeXml(OutputStream out, Model model) {
writeRdfXml(out, model);
}
public static void writeRdfXml(OutputStream out, Iterator<Triple> iterator) {
Model model = triplesToModel(iterator);
writeXml(out, model);
}
public static void writeRdfXml(OutputStream out, Model model) {
model.write(out, "RDF/XML");
}
public static void writeRdfXml(OutputStream out, ResultSet rs) {
ResultSetFormatter.outputAsXML(out, rs);
}
public static void writeXml(OutputStream out, ResultSet rs) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ResultSetFormatter.outputAsXML(baos, rs);
String str = baos.toString();
PrintStream ps = new PrintStream(out);
ps.println(str);
// TODO Hack: Writing from Jena directly seems to block for same reason
//ResultSetFormatter.outputAsXML(out, rs);
}
public static void writeXml(OutputStream out, Boolean value) throws IOException {
ResultSetFormatter.outputAsXML(out, value);
//out.flush();
}
/*************************************************************************
* Text
*************************************************************************/
// public static String formatText(Object o) {
// return MultiMethod.invokeStatic(HttpSparqlEndpoint.class,
// "_formatText", o);
// }
public static String _formatText(Boolean value) {
String result = "<sparql xmlns='http://www.w3.org/2005/sparql-results#' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.w3.org/2001/sw/DataAccess/rf1/result2.xsd'>\n"
+ "<head></head>\n"
+ "<boolean>"
+ value
+ "</boolean>"
+ "</sparql>";
return result;
}
public static String _formatText(Model model) {
return ModelUtils.toString(model, "N-TRIPLES");
}
public static String _formatText(ResultSet rs) {
return ResultSetFormatter.asText(rs);
}
public static void writeText(OutputStream out, Model model) {
model.write(out, "N-TRIPLES");
}
public static void writeText(OutputStream out, Iterator<Triple> it) {
Sink<Triple> sink = new SinkTripleOutput(out, null, null);
while(it.hasNext()) {
Triple triple = it.next();
sink.send(triple);
}
sink.flush();
//sink.close();
}
public static void writeText(OutputStream out, ResultSet rs) {
ResultSetFormatter.outputAsTSV(out, rs);
}
/*************************************************************************
* JSON
*************************************************************************/
// String
// public static String formatJson(Object o) {
// return MultiMethod.invokeStatic(HttpSparqlEndpoint.class,
// "_formatJson", o);
// }
public static String _formatJson(Boolean value) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
writeJson(out, value);
return out.toString();
}
public static String _formatJson(Model model) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
writeJson(out, model);
return out.toString();
}
public static String _formatJson(ResultSet rs) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
writeJson(out, rs);
return out.toString();
}
// OutputStream
// public static String _writeJson(OutputStream out, Object o) {
// return MultiMethod.invokeStatic(HttpSparqlEndpoint.class, "writeJson",
// out, o);
// }
public static void writeJson(OutputStream out, Boolean value) {
ResultSetFormatter.outputAsJSON(out, value);
}
public static void writeJson(OutputStream out, Iterator<Triple> triples) {
Model model = triplesToModel(triples);
JSONJenaWriter writer = new JSONJenaWriter();
writer.write(model, out, null);
}
public static void writeJson(OutputStream out, Model model) {
JSONJenaWriter writer = new JSONJenaWriter();
writer.write(model, out, null);
}
public static void writeJson(OutputStream out, ResultSet rs) {
ResultSetFormatter.outputAsJSON(out, rs);
}
/*************************************************************************
* TURTLE
*************************************************************************/
// public static String formatTurtle(Object o) {
// // throw new RuntimeException("JSON is not supported yet");
// return MultiMethod.invokeStatic(HttpSparqlEndpoint.class,
// "_formatTurtle", o);
// }
public static String _formatTurtle(Model model) {
return ModelUtils.toString(model, "TTL");
}
public static void writeTurtle(OutputStream out, Iterator<Triple> triples) {
Model model = triplesToModel(triples);
writeTurtle(out, model);
}
public static void writeTurtle(OutputStream out, Model model) {
model.write(out, "TTL");
}
}