jena-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a...@apache.org
Subject [04/11] jena git commit: JENA-1454: Introduce builder pattern for result set reading and writing.
Date Sun, 31 Dec 2017 10:52:42 GMT
JENA-1454: Introduce builder pattern for result set reading and writing.


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/716b86cf
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/716b86cf
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/716b86cf

Branch: refs/heads/master
Commit: 716b86cfa300e8829dbc9238b7c67b711cdef1e2
Parents: d516f35
Author: Andy Seaborne <andy@apache.org>
Authored: Mon Dec 18 14:49:40 2017 +0000
Committer: Andy Seaborne <andy@apache.org>
Committed: Fri Dec 22 21:40:42 2017 +0000

----------------------------------------------------------------------
 .../org/apache/jena/query/ResultSetFactory.java |  78 +--
 .../apache/jena/query/ResultSetFormatter.java   | 139 ++--
 .../java/org/apache/jena/riot/ResultSetMgr.java | 270 +++++---
 .../jena/riot/resultset/ResultSetLang.java      |   2 +-
 .../jena/riot/resultset/ResultSetReader.java    |  31 +-
 .../riot/resultset/ResultSetReaderRegistry.java |  70 +-
 .../riot/resultset/ResultSetWriterRegistry.java |  85 +--
 .../riot/resultset/rw/JSONInputIterator.java    | 657 +++++++++++++++++++
 .../jena/riot/resultset/rw/JSONResultsKW.java   |  44 ++
 .../jena/riot/resultset/rw/ReadAnything.java    | 100 +++
 .../riot/resultset/rw/ResultSetReaderJSON.java  | 247 +++++++
 .../resultset/rw/ResultSetReaderThrift.java     |  60 ++
 .../riot/resultset/rw/ResultSetReaderXML.java   |  54 ++
 .../riot/resultset/rw/ResultSetWriterJSON.java  | 305 +++++++++
 .../resultset/rw/ResultSetWriterThrift.java     |  54 ++
 .../riot/resultset/rw/ResultSetWriterXML.java   | 380 +++++++++++
 .../jena/riot/resultset/rw/ResultsMgrX.java     |  69 ++
 .../jena/riot/resultset/rw/ResultsReader.java   | 151 +++++
 .../jena/riot/resultset/rw/ResultsStAX.java     | 473 +++++++++++++
 .../jena/riot/resultset/rw/ResultsWriter.java   | 113 ++++
 .../jena/riot/resultset/rw/XMLResults.java      |  50 ++
 .../jena/riot/system/stream/StreamManager.java  |   5 +-
 .../apache/jena/sparql/resultset/JSONInput.java | 227 +------
 .../sparql/resultset/JSONInputIterator.java     | 657 -------------------
 .../jena/sparql/resultset/JSONOutput.java       |  21 +-
 .../jena/sparql/resultset/JSONOutputASK.java    |  54 --
 .../sparql/resultset/JSONOutputResultSet.java   | 266 --------
 .../jena/sparql/resultset/JSONResultsKW.java    |  43 --
 .../jena/sparql/resultset/SPARQLResult.java     |  20 +-
 .../apache/jena/sparql/resultset/XMLInput.java  |  10 +-
 .../jena/sparql/resultset/XMLInputSAX.java      |  23 +-
 .../jena/sparql/resultset/XMLInputStAX.java     | 516 ---------------
 .../apache/jena/sparql/resultset/XMLOutput.java |  30 +-
 .../jena/sparql/resultset/XMLOutputASK.java     |  74 ---
 .../sparql/resultset/XMLOutputResultSet.java    | 286 --------
 .../jena/sparql/resultset/XMLResults.java       |  50 --
 .../apache/jena/sparql/util/LabelToNodeMap.java |   6 +-
 .../apache/jena/sparql/util/QueryExecUtils.java |   6 -
 .../jena/sparql/resultset/TestResultSet.java    |  10 +-
 39 files changed, 3189 insertions(+), 2547 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/716b86cf/jena-arq/src/main/java/org/apache/jena/query/ResultSetFactory.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/query/ResultSetFactory.java b/jena-arq/src/main/java/org/apache/jena/query/ResultSetFactory.java
index dcf33f5..5682b3d 100644
--- a/jena-arq/src/main/java/org/apache/jena/query/ResultSetFactory.java
+++ b/jena-arq/src/main/java/org/apache/jena/query/ResultSetFactory.java
@@ -27,7 +27,8 @@ 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.ResultSetMgr ;
-import org.apache.jena.shared.NotFoundException ;
+import org.apache.jena.riot.resultset.ResultSetLang;
+import org.apache.jena.riot.resultset.rw.ReadAnything;
 import org.apache.jena.sparql.engine.QueryIterator ;
 import org.apache.jena.sparql.engine.ResultSetStream ;
 import org.apache.jena.sparql.graph.GraphFactory ;
@@ -88,21 +89,6 @@ public class ResultSetFactory {
         if ( lang != null )
             return ResultSetMgr.read(input, lang) ;
 
-        if (format.equals(ResultsFormat.FMT_RS_JSON))
-            return JSONInput.fromJSON(input);
-
-        if (format.equals(ResultsFormat.FMT_RS_TSV))
-            return TSVInput.fromTSV(input);
-
-        if (format.equals(ResultsFormat.FMT_RS_CSV))
-            return CSVInput.fromCSV(input);
-
-        if (format.equals(ResultsFormat.FMT_RS_BIO))
-            return BIOInput.fromBIO(input);
-
-        if (format.equals(ResultsFormat.FMT_RS_XML))
-            return ResultSetFactory.fromXML(input);
-
         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");
@@ -202,27 +188,13 @@ public class ResultSetFactory {
         }
 
         if (format.equals(ResultsFormat.FMT_RS_XML) || format.equals(ResultsFormat.FMT_RS_JSON)) {
-            InputStream in = null;
-            try {
-                in = FileManager.get().open(filenameOrURI);
-                if (in == null)
-                    throw new NotFoundException(filenameOrURI);
-            } catch (NotFoundException ex) {
-                throw new NotFoundException("File not found: " + filenameOrURI);
-            }
-
-            SPARQLResult x = null;
-
-            if (format.equals(ResultsFormat.FMT_RS_JSON))
-                x = JSONInput.make(in, GraphFactory.makeDefaultModel());
-            else
-                x = XMLInput.make(in, GraphFactory.makeDefaultModel());
-
+            SPARQLResult x = ReadAnything.read(filenameOrURI);
             if (x.isResultSet())
                 RDFOutput.encodeAsRDF(model, x.getResultSet());
-            else
+            else if ( x.isBoolean() )
                 RDFOutput.encodeAsRDF(model, x.getBooleanResult());
-
+            else 
+                throw new ResultSetException("Not a result set");
             return model;
         }
 
@@ -243,8 +215,9 @@ public class ResultSetFactory {
 
     /**
      * Read in any kind of result kind (result set, boolean, graph)
+     * @deprecated Use ReadAnything.read(filenameOrURI);
      */
-
+    @Deprecated
     public static SPARQLResult result(String filenameOrURI, ResultsFormat format) {
         if (format == null)
             format = ResultsFormat.guessSyntax(filenameOrURI);
@@ -261,31 +234,8 @@ public class ResultSetFactory {
 
         if (format.equals(ResultsFormat.FMT_RS_XML) || format.equals(ResultsFormat.FMT_RS_JSON)
             || format.equals(ResultsFormat.FMT_RS_TSV) || format.equals(ResultsFormat.FMT_RS_CSV)) {
-            InputStream in = null;
-            try {
-                in = FileManager.get().open(filenameOrURI);
-                if (in == null)
-                    throw new NotFoundException(filenameOrURI);
-            } catch (NotFoundException ex) {
-                throw new NotFoundException("File not found: " + filenameOrURI);
-            }
-
-            SPARQLResult x = null;
-
-            if (format.equals(ResultsFormat.FMT_RS_JSON))
-                return JSONInput.make(in, GraphFactory.makeDefaultModel());
-            else if (format.equals(ResultsFormat.FMT_RS_XML))
-                return XMLInput.make(in, GraphFactory.makeDefaultModel());
-            else if (format.equals(ResultsFormat.FMT_RS_TSV)) {
-                ResultSet rs = TSVInput.fromTSV(in);
-                return new SPARQLResult(rs);
-            } else if (format.equals(ResultsFormat.FMT_RS_CSV)) {
-                ResultSet rs = CSVInput.fromCSV(in);
-                return new SPARQLResult(rs);
-            } else if (format.equals(ResultsFormat.FMT_RS_BIO)) {
-                ResultSet rs = BIOInput.fromBIO(in);
-                return new SPARQLResult(rs);
-            }
+            SPARQLResult x = ReadAnything.read(filenameOrURI);
+            return x;
         }
 
         if (ResultsFormat.isRDFGraphSyntax(format)) {
@@ -305,7 +255,7 @@ public class ResultSetFactory {
      * @return ResultSet
      */
     public static ResultSet fromXML(InputStream in) {
-        return XMLInput.fromXML(in);
+        return ResultSetMgr.read(in, ResultSetLang.SPARQLResultSetXML);
     }
 
     /**
@@ -314,7 +264,9 @@ public class ResultSetFactory {
      * @param str
      *            String to process
      * @return ResultSet
+     * @deprecated
      */
+    @Deprecated
     public static ResultSet fromXML(String str) {
         return XMLInput.fromXML(str);
     }
@@ -328,7 +280,7 @@ public class ResultSetFactory {
      * @return ResultSet
      */
     public static ResultSet fromJSON(InputStream in) {
-        return JSONInput.fromJSON(in);
+        return ResultSetMgr.read(in, ResultSetLang.SPARQLResultSetJSON);
     }
 
     /**
@@ -340,7 +292,7 @@ public class ResultSetFactory {
      * @return ResultSet
      */
     public static ResultSet fromTSV(InputStream in) {
-        return TSVInput.fromTSV(in);
+        return ResultSetMgr.read(in, ResultSetLang.SPARQLResultSetTSV);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/jena/blob/716b86cf/jena-arq/src/main/java/org/apache/jena/query/ResultSetFormatter.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/query/ResultSetFormatter.java b/jena-arq/src/main/java/org/apache/jena/query/ResultSetFormatter.java
index 43bb07b..49b5586 100644
--- a/jena-arq/src/main/java/org/apache/jena/query/ResultSetFormatter.java
+++ b/jena-arq/src/main/java/org/apache/jena/query/ResultSetFormatter.java
@@ -18,6 +18,11 @@
 
 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 ;
@@ -28,16 +33,17 @@ import java.util.List ;
 
 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.core.Var ;
-import org.apache.jena.sparql.engine.binding.Binding ;
-import org.apache.jena.sparql.engine.binding.BindingOutputStream ;
-import org.apache.jena.sparql.engine.binding.BindingUtils ;
-import org.apache.jena.sparql.resultset.* ;
+import org.apache.jena.sparql.resultset.RDFOutput;
+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 ;
 
 /** ResultSetFormatter - Convenience ways to call the various output formatters.
@@ -261,9 +267,6 @@ public class ResultSetFormatter {
         }
     }
     
-    // ----------------------------------------------------------------
-    // As RDF
-    
     /** Output a ResultSet in some format.
      * 
      * @param resultSet Result set
@@ -282,31 +285,13 @@ public class ResultSetFormatter {
      */
     
     static public void output(OutputStream outStream, ResultSet resultSet, ResultsFormat rFmt) {
-        if ( rFmt.equals(ResultsFormat.FMT_RS_XML) ) {
-            outputAsXML(outStream, resultSet) ;
-            return ;
-        }
-
-        if ( rFmt.equals(ResultsFormat.FMT_RS_JSON) ) {
-            outputAsJSON(outStream, resultSet) ;
-            return ;
-        }
-
-        if ( rFmt.equals(ResultsFormat.FMT_RS_CSV) ) {
-            outputAsCSV(outStream, resultSet) ;
-            return ;
-        }
-
-        if ( rFmt.equals(ResultsFormat.FMT_RS_TSV) ) {
-            outputAsTSV(outStream, resultSet) ;
-            return ;
-        }
-
-        if ( rFmt.equals(ResultsFormat.FMT_RS_BIO) ) {
-            outputAsBIO(outStream, resultSet) ;
+        
+        Lang lang = ResultsFormat.convert(rFmt);
+        if ( lang != null ) {
+            output(outStream, resultSet, lang);
             return ;
         }
-
+        
         if ( rFmt.equals(ResultsFormat.FMT_RDF_XML) ) {
             RDFOutput.outputAsRDF(outStream, "RDF/XML-ABBREV", resultSet) ;
             return ;
@@ -324,13 +309,29 @@ public class ResultSetFormatter {
         throw new ARQException("Unknown ResultSet format: " + rFmt) ;
     }
     
-    // ---- XML Output
+    // ---- 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);
+    }
+    // ---- General Output
+    
+    public static void output(OutputStream outStream, boolean result, Lang resultFormat) {
+        ResultsWriter.create().lang(resultFormat).build().write(outStream, result);
+    }
     /** Output a result set in the XML format
      * 
      * @param qresults      result set
      */
     
+    // ---- XML Output
+
     static public void outputAsXML(ResultSet qresults)
     { outputAsXML(System.out, qresults) ; }
 
@@ -341,20 +342,18 @@ public class ResultSetFormatter {
      */
     
     static public void outputAsXML(OutputStream outStream, ResultSet qresults)
-    {
-        outputAsXML(outStream, qresults, (String)null) ;
-    }
+    { output(outStream, qresults, SPARQLResultSetXML); }
     
-    /** Output a result set in the XML format, inserting a style sheet in the XMl output
+    /** 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) ; }
+    { outputAsXML(System.out, qresults, stylesheet); }
 
-    /** Output a result set in the XML format, inserting a style sheet in the XMl output
+    /** Output a result set in the XML format, inserting a style sheet in the XML output
      * 
      * @param outStream     output stream
      * @param qresults      result set
@@ -384,9 +383,7 @@ public class ResultSetFormatter {
      */
     
     public static void outputAsXML(OutputStream outStream, boolean booleanResult)
-    {
-        outputAsXML(outStream, booleanResult, null) ;
-    }
+    { output(outStream, booleanResult, SPARQLResultSetXML); }
 
     /** Output a boolean result in the XML format
      * 
@@ -403,10 +400,9 @@ public class ResultSetFormatter {
      * @param stylesheet    The URL of the stylesheet
      */
     
-    public static void outputAsXML(OutputStream outStream, boolean booleanResult, String stylesheet)
-    {
-        XMLOutputASK fmt = new XMLOutputASK(outStream, stylesheet) ;
-        fmt.exec(booleanResult) ;
+    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)
@@ -477,7 +473,7 @@ public class ResultSetFormatter {
         return xOut.asString(booleanResult) ;
     }
     
-    // ---- JSON (and YAML)
+    // ---- 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> 
@@ -485,7 +481,7 @@ public class ResultSetFormatter {
      * @param resultSet     result set
      */
     
-    static public void outputAsJSON(ResultSet resultSet)
+    static public void outputAsJSON(ResultSet resultSet) 
     { outputAsJSON(System.out, resultSet) ; }
     
     /** Output a result set in the JSON format
@@ -497,10 +493,7 @@ public class ResultSetFormatter {
      */
     
     static public void outputAsJSON(OutputStream outStream, ResultSet resultSet)
-    {
-        JSONOutput jOut = new JSONOutput() ;
-        jOut.format(outStream, 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> 
@@ -510,7 +503,7 @@ public class ResultSetFormatter {
      */
 
     static public void outputAsJSON(boolean booleanResult)
-    { outputAsJSON(System.out, 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> 
@@ -521,10 +514,7 @@ public class ResultSetFormatter {
      */
     
     static public void outputAsJSON(OutputStream outStream, boolean booleanResult)
-    {
-        JSONOutput jOut = new JSONOutput() ;
-        jOut.format(outStream, booleanResult) ; 
-    }
+    { output(outStream, booleanResult, SPARQLResultSetJSON) ; }
     
     // ---- SSE
     
@@ -603,10 +593,7 @@ public class ResultSetFormatter {
      */
     
     static public void outputAsCSV(OutputStream outStream, boolean booleanResult)
-    {
-        CSVOutput fmt = new CSVOutput() ;
-        fmt.format(outStream, booleanResult) ;
-    }
+    { output(outStream, booleanResult, SPARQLResultSetCSV); }
 
     /** Output a result set in CSV format
      *  @param resultSet     result set
@@ -621,10 +608,7 @@ public class ResultSetFormatter {
      */
     
     static public void outputAsCSV(OutputStream outStream, ResultSet resultSet)
-    {
-        CSVOutput fmt = new CSVOutput() ;
-        fmt.format(outStream, resultSet) ;
-    }
+    { output(outStream, resultSet, SPARQLResultSetCSV); }
 
     // ---- TSV
     
@@ -643,10 +627,7 @@ public class ResultSetFormatter {
      */
     
     static public void outputAsTSV(OutputStream outStream, boolean booleanResult)
-    {
-        TSVOutput fmt = new TSVOutput() ;
-        fmt.format(outStream, booleanResult) ;
-    }
+    { output(outStream, booleanResult, SPARQLResultSetTSV); }
 
     /** Output a result set in TSV format
      *  @param resultSet     result set
@@ -661,25 +642,5 @@ public class ResultSetFormatter {
      */
     
     static public void outputAsTSV(OutputStream outStream, ResultSet resultSet)
-    {
-        TSVOutput fmt = new TSVOutput() ;
-        fmt.format(outStream, resultSet) ;
-    }
-    
-    /** Output a result set in BIO format 
-     * @deprecated Experimental - may be removed
-     */
-    @Deprecated
-    public static void outputAsBIO(OutputStream out, ResultSet results)
-    {
-        List<Var> vars = Var.varList(results.getResultVars()) ;
-        
-        BindingOutputStream bout = new BindingOutputStream(out, vars) ;
-        for ( ; results.hasNext() ; )
-        {
-            Binding b = BindingUtils.asBinding(results.next()) ;
-            bout.write(b) ;
-        }
-        bout.flush() ;
-    }
+    { output(outStream, resultSet, SPARQLResultSetTSV); }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/716b86cf/jena-arq/src/main/java/org/apache/jena/riot/ResultSetMgr.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/ResultSetMgr.java b/jena-arq/src/main/java/org/apache/jena/riot/ResultSetMgr.java
index aeb05cc..2c406f1 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/ResultSetMgr.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/ResultSetMgr.java
@@ -18,15 +18,20 @@
 
 package org.apache.jena.riot;
 
+import java.io.ByteArrayOutputStream;
 import java.io.InputStream ;
 import java.io.OutputStream ;
+import java.util.Objects;
 
-import org.apache.jena.atlas.web.ContentType ;
-import org.apache.jena.atlas.web.TypedInputStream ;
+import org.apache.jena.atlas.lib.StrUtils;
 import org.apache.jena.query.ResultSet ;
 import org.apache.jena.query.ResultSetFactory ;
 import org.apache.jena.query.ResultSetFormatter ;
-import org.apache.jena.riot.resultset.* ;
+import org.apache.jena.riot.resultset.ResultSetReaderRegistry;
+import org.apache.jena.riot.resultset.rw.ResultsReader;
+import org.apache.jena.riot.resultset.rw.ResultsWriter;
+import org.apache.jena.sparql.resultset.ResultSetException;
+import org.apache.jena.sparql.resultset.SPARQLResult;
 import org.apache.jena.sparql.util.Context ;
 
 /** 
@@ -36,7 +41,61 @@ import org.apache.jena.sparql.util.Context ;
  * @see ResultSetFormatter 
  */
 public class ResultSetMgr {
-    
+    /**
+     * Read from a {@code URL} (including filenames) and produce a {@link ResultSet}.
+     * Note that returned result set may stream and so the input stream be read
+     * while the ResultSet is used.
+     * <p>
+     * See {@link ResultSetFactory#copyResults(ResultSet)}
+     * for a ResultSet that is detached from the {@code InputStream}.
+     * 
+     * @param urlOrFilename
+     * @return ResultSet
+     */
+    public static ResultSet read(String urlOrFilename) {
+        ResultSet rs = readAny(urlOrFilename).getResultSet();
+        if ( rs == null )
+            throw new ResultSetException("Not a result set"); 
+        return rs;
+    }
+
+
+    /**
+     * Read from a {@code URL} (including filenames) and produce a {@link ResultSet};
+     * the stream is expect to use syntax {@code lang}.  Note that returned
+     * result set may stream and so the input stream be read while the ResultSet is used.
+     * See {@link ResultSetFactory#copyResults(ResultSet)}
+     * for a ResultSet that is detached from the {@code InputStream}.
+     * 
+     * @param urlOrFilename
+     * @param lang
+     * @return ResultSet
+     */
+    public static ResultSet read(String urlOrFilename, Lang lang) {
+        ResultSet rs = readAny(urlOrFilename, lang).getResultSet();
+        if ( rs == null )
+            throw new ResultSetException("Not a result set"); 
+        return rs;
+    }
+
+    /**
+     * Read from a {@code URL} (including filenames) and produce a {@link ResultSet}.
+     * Note that returned result set may stream and so the input stream be read
+     * while the ResultSet is used.
+     * <p>
+     * See {@link ResultSetFactory#copyResults(ResultSet)}
+     * for a ResultSet that is detached from the {@code InputStream}.
+     * 
+     * @param input
+     * @return ResultSet
+     */
+    public static ResultSet read(InputStream input) {
+        ResultSet rs = readAny(input).getResultSet();
+        if ( rs == null )
+            throw new ResultSetException("Not a result set"); 
+        return rs;
+    }
+
     /**
      * Read from an {@code InputStream} and produce a {@link ResultSet};
      * the stream is expect to use syntax {@code lang}.  Note that returned
@@ -44,115 +103,154 @@ public class ResultSetMgr {
      * See {@link ResultSetFactory#copyResults(ResultSet)}
      * for a ResultSet that is detached from the {@code InputStream}.
      * 
-     * @param in
+     * @param input
      * @param lang
      * @return ResultSet
      */
-    public static ResultSet read(InputStream in, Lang lang) {
-        return process(TypedInputStream.wrap(in), null, lang, null) ;
+    public static ResultSet read(InputStream input, Lang lang) {
+        ResultSet rs = readAny(input, lang).getResultSet();
+        if ( rs == null )
+            throw new ResultSetException("Not a result set"); 
+        return rs;
+    }
+
+    private static void checkLang(Lang lang) {
+        Objects.requireNonNull(lang);
+        if ( ! ResultSetReaderRegistry.isRegistered(lang) ) {
+            throw new ResultSetException("Not a result set syntax: "+lang);
+        }
     }
     
-    /** Read a result set from the URI */
-    public static ResultSet read(String uri) {
-        return read(uri, null) ;
+    /** Read a boolean result from the URI
+     * 
+     * @param urlOrFilename
+     * @return boolean
+     */
+    public static boolean readBoolean(String urlOrFilename) {
+        Boolean b = readAny(urlOrFilename).getBooleanResult();
+        return b;
     }
     
-    /** Read a result set from the URI, in the specified syntax */ 
-    public static ResultSet read(String uri, Lang lang) {
-        return parse(uri, lang, null) ;
+    /** Read a boolean result from the URI;
+     * the input is expect to use syntax {@code lang}
+     * 
+     * @param urlOrFilename
+     * @param lang
+     * @return boolean
+     */
+    public static boolean readBoolean(String urlOrFilename, Lang lang) {
+        Boolean b = readAny(urlOrFilename, lang).getBooleanResult();
+        return b;
+    }
+    
+    /** Read a boolean result from the URI
+     * 
+     * @param input
+     * @return boolean
+     */
+    public static boolean readBoolean(InputStream input) {
+        Boolean b = readAny(input).getBooleanResult();
+        return b;
+    }
+    
+    /** Read a boolean result from the URI;
+     * the input is expect to use syntax {@code lang}
+     * 
+     * @param input
+     * @param lang
+     * @return boolean
+     */
+    public static boolean readBoolean(InputStream input, Lang lang) {
+        Boolean b = readAny(input, lang).getBooleanResult();
+        return b;
     }
 
+    private static SPARQLResult readAny(String url) {
+        return ResultsReader.create().build().readAny(url);
+    }
+
+    private static SPARQLResult readAny(String url, Lang lang) {
+        checkLang(lang);
+        return ResultsReader.create()
+            .lang(lang)
+            .build()
+            .readAny(url);
+    }
+    
+    private static SPARQLResult readAny(InputStream input) {
+        return ResultsReader.create().build().readAny(input);
+    }
+
+    private static SPARQLResult readAny(InputStream input, Lang lang) {
+        checkLang(lang);
+        return ResultsReader.create()
+            .lang(lang)
+            .build()
+            .readAny(input);
+    }
+    // -------------------------------
+    
     /** Read ResultSet.
      * @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 ResultSet parse(String uri, Lang hintLang, Context context)
-    {
-        // Conneg
-        if ( uri == null )
-            throw new IllegalArgumentException("URI to read from is null") ;
-        if ( hintLang == null )
-            hintLang = RDFLanguages.filenameToLang(uri) ;
-        TypedInputStream in = RDFDataMgr.open(uri, context) ;
-        if ( in == null )
-            throw new RiotException("Not found: "+uri) ;
-        return process(in, uri, hintLang, context) ;
-    }
-        
-    private static ResultSet process(TypedInputStream in, String srcURI, Lang hintLang, Context context) {
-        ContentType ct = WebContent.determineCT(in.getContentType(), hintLang, srcURI) ;
-        if ( ct == null )
-            throw new RiotException("Failed to determine the content type: (URI="+srcURI+" : stream="+in.getContentType()+" : hint="+hintLang+")") ;
-        ResultSetReader reader = getReader(ct) ;
-        if ( reader == null )
-            throw new RiotException("No parser registered for content type: "+ct.getContentType()) ;
-        return reader.read(in, context) ;
+    public static ResultSet parse(String uri, Lang hintLang, Context context) {
+        ResultSet rs = ResultsReader.create().lang(hintLang).context(context).read(uri);
+        if ( rs == null )
+            throw new ResultSetException("Not a result set"); 
+        return rs;
     }
-    
-    private static ResultSetReader getReader(ContentType ct)
-    {
-        Lang lang = RDFLanguages.contentTypeToLang(ct) ;
-        if ( lang == null )
-            return null ;
-        ResultSetReaderFactory r = ResultSetReaderRegistry.getFactory(lang) ;
-        if ( r == null )
-            return null ;
-        return r.create(lang) ;
-    }
-    
-    // -------------------------------
 
+    // -------------------------------
+    
     /** Write a SPARQL result set to the output stream in the specified language/syntax.
-     * @param out
+     * @param output
      * @param resultSet
      * @param lang
      */
-    public static void write(OutputStream out, ResultSet resultSet, Lang lang) { 
-        ResultSetWriterFactory f = ResultSetWriterRegistry.lookup(lang) ;
-        if ( f == null )
-            throw new RiotException("No resultSet writer for "+lang) ;
-        f.create(lang).write(out, resultSet, null) ;
+    public static void write(OutputStream output, ResultSet resultSet, Lang lang) {
+        ResultsWriter.create()
+            .lang(lang)
+            .write(output, resultSet);
     }
-    
+
     /** Write a SPARQL boolean result to the output stream in the specified language/syntax.
-     * @param out
+     * @param output
      * @param result
      * @param lang
      */
-    public static void write(OutputStream out, boolean result, Lang lang) {
-        ResultSetWriterFactory f = ResultSetWriterRegistry.lookup(lang) ;
-        if ( f == null )
-            throw new RiotException("No resultSet writer for "+lang) ;
-        f.create(lang).write(out, result, null) ;
+    public static void write(OutputStream output, boolean result, Lang lang) {
+        ResultsWriter.create()
+            .lang(lang)
+            .build()
+            .write(output, result);
     }
     
-//    /** Write a SPARQL result set to the {@link java.io.Writer} in the speciifcied language/syntax.
-//     * Using {@link OutputStream}s is better because the charcater encoding will match the
-//     * requirements of the language.   
-//     * @param out
-//     * @param resultSet
-//     * @param lang
-//     */
-//    @Deprecated
-//    public static void write(Writer out, ResultSet resultSet, Lang lang) { 
-//        ResultSetWriterFactory f = ResultSetWriterRegistry.lookup(lang) ;
-//        if ( f == null )
-//            throw new RiotException("No resultSet writer for "+lang) ;
-//        f.create(lang).write(out, resultSet, null) ;
-//    }
-//
-//    /** Write a SPARQL result set to the {@link java.io.Writer} in the speciifcied language/syntax.
-//     * @param out
-//     * @param resultSet
-//     * @param lang
-//     */
-//    public static void write(StringWriter out, ResultSet resultSet, Lang lang) { 
-//        ResultSetWriterFactory f = ResultSetWriterRegistry.lookup(lang) ;
-//        if ( f == null )
-//            throw new RiotException("No resultSet writer for "+lang) ;
-//        f.create(lang).write(out, resultSet, null) ;
-//    }
+    /** Generate a string in the specified language/syntax for a SPARQL result set.
+     * @param resultSet
+     * @param lang
+     */
+    public static String asString(ResultSet resultSet, Lang lang) {
+        ByteArrayOutputStream output = new ByteArrayOutputStream(1000); 
+        ResultsWriter.create()
+            .lang(lang)
+            .write(output, resultSet);
+        return StrUtils.fromUTF8bytes(output.toByteArray());
+    }
+
+    /** Generate a string in the specified language/syntax for a SPARQL boolean result.
+     * @param result
+     * @param lang
+     */
+    public static String asString(boolean result, Lang lang) {
+        ByteArrayOutputStream output = new ByteArrayOutputStream(1000); 
+        ResultsWriter.create()
+            .lang(lang)
+            .build()
+            .write(output, result);
+        return StrUtils.fromUTF8bytes(output.toByteArray());
+    }
 
 }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/716b86cf/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetLang.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetLang.java b/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetLang.java
index 53d6a28..5ca83ae 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetLang.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetLang.java
@@ -24,7 +24,7 @@ import org.apache.jena.riot.RDFLanguages ;
 import org.apache.jena.riot.WebContent ;
 
 public class ResultSetLang {
-    // Add SSE!
+
     public static final Lang SPARQLResultSetXML
         = LangBuilder.create("SPARQL-Results-XML", WebContent.contentTypeResultsXML)
                      .addAltNames("SRX")

http://git-wip-us.apache.org/repos/asf/jena/blob/716b86cf/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetReader.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetReader.java b/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetReader.java
index c894344..242b8a1 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetReader.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetReader.java
@@ -23,31 +23,50 @@ import java.io.Reader ;
 
 import org.apache.jena.query.ResultSet ;
 import org.apache.jena.query.ResultSetFactory ;
+import org.apache.jena.sparql.resultset.SPARQLResult;
 import org.apache.jena.sparql.util.Context ;
 
 public interface ResultSetReader {
     
     /**
      * Read from an {@code InputStream} and produce a {@link ResultSet}.
-     * Note that return result may stream and so the input stream be read
-     * while the ResultSet is used.
+     * Note that return result may stream and so the input stream may be read
+     * while the {@link ResultSet} is used.
      * See {@link ResultSetFactory#copyResults(ResultSet)} for a ResultSet that is detached from the {@code InputStream}.
      * @param in InputStream to read from.
      * @param context
      * @return ResultSet
      */
-    public ResultSet read(InputStream in, Context context) ;
+    public default ResultSet read(InputStream in, Context context) {
+        return readAny(in, context).getResultSet();
+    }
+    
+    /**
+     * Read from an {@code InputStream} and produce a {@link SPARQLResult}.
+     * Note that return result may stream and so the input stream may be read
+     * while the {@link ResultSet} is used.
+     * See {@link #read(InputStream, Context)} for more details
+     * @param in InputStream to read from.
+     * @param context
+     * @return SPARQLResult
+     */
+    public SPARQLResult readAny(InputStream in, Context context) ;
     
     /**
-     * Using {@link #read(InputStream, Context)} is preferred.
+     * <em>Using {@link #read(InputStream, Context)} is preferred.</em>
+     * <p>
+     * Notall formast support reading from a {@code java.io.Reader}.
+     * <p>
      * Read from an {@code Reader} and produce a {@link ResultSet}.
-     * Note that return result may stream and so the reader be read
+     * Note that return result may stream and so the reader may be read
      * while the ResultSet is used.
      * See {@link ResultSetFactory#copyResults(ResultSet)} for a ResultSet that is detached from the {@code InputStream}.
      * @param in Reader
      * @param context
      * @return ResultSet
      */
-    public ResultSet read(Reader in, Context context) ;
+    public default ResultSet read(Reader in, Context context) {
+        throw new UnsupportedOperationException("ResultSetReader.read - input from a Java Reader not supported.  Use an InputStream.");
+    }
 }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/716b86cf/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetReaderRegistry.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetReaderRegistry.java b/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetReaderRegistry.java
index f2a34d6..57f8c31 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetReaderRegistry.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetReaderRegistry.java
@@ -18,11 +18,7 @@
 
 package org.apache.jena.riot.resultset;
 
-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.SPARQLResultSetThrift ;
-import static org.apache.jena.riot.resultset.ResultSetLang.SPARQLResultSetXML ;
+import static org.apache.jena.riot.resultset.ResultSetLang.*;
 
 import java.io.InputStream ;
 import java.io.Reader ;
@@ -34,11 +30,12 @@ import org.apache.jena.atlas.lib.NotImplemented ;
 import org.apache.jena.query.ResultSet ;
 import org.apache.jena.riot.Lang ;
 import org.apache.jena.riot.RiotException ;
+import org.apache.jena.riot.resultset.rw.ResultSetReaderJSON;
+import org.apache.jena.riot.resultset.rw.ResultSetReaderXML;
 import org.apache.jena.riot.thrift.BinRDF ;
 import org.apache.jena.sparql.resultset.CSVInput ;
-import org.apache.jena.sparql.resultset.JSONInput ;
+import org.apache.jena.sparql.resultset.SPARQLResult;
 import org.apache.jena.sparql.resultset.TSVInput ;
-import org.apache.jena.sparql.resultset.XMLInput ;
 import org.apache.jena.sparql.util.Context ;
 
 public class ResultSetReaderRegistry {
@@ -56,6 +53,12 @@ public class ResultSetReaderRegistry {
         registry.put(lang, factory) ;
     }
 
+    /** Test whether {@link Lang} is registered as a result set syntax. */
+    public static boolean isRegistered(Lang lang) {
+        Objects.requireNonNull(lang) ;
+        return registry.containsKey(lang);
+    }
+
     private static Map<Lang, ResultSetReaderFactory> registry = new HashMap<>() ;
     
     private static boolean initialized = false ;
@@ -65,8 +68,8 @@ public class ResultSetReaderRegistry {
         initialized = true ;
 
         ResultSetReaderFactory factory = new ResultSetReaderFactoryStd() ;
-        register(SPARQLResultSetXML,    factory) ;
-        register(SPARQLResultSetJSON,   factory) ;
+        register(SPARQLResultSetXML,    ResultSetReaderXML.factory) ;
+        register(SPARQLResultSetJSON,   ResultSetReaderJSON.factory) ;
         register(SPARQLResultSetCSV,    factory) ;
         register(SPARQLResultSetTSV,    factory) ;
         register(SPARQLResultSetThrift, factory) ;
@@ -76,11 +79,10 @@ public class ResultSetReaderRegistry {
         @Override
         public ResultSetReader create(Lang lang) {
             lang = Objects.requireNonNull(lang, "Language must not be null") ;
-            if ( lang.equals(SPARQLResultSetXML) )      return readerXML ;
-            if ( lang.equals(SPARQLResultSetJSON) )     return readerJSON ;
+//            if ( lang.equals(SPARQLResultSetXML) )      return readerXML ;
+//            if ( lang.equals(SPARQLResultSetJSON) )     return readerJSON ;
             if ( lang.equals(SPARQLResultSetCSV) )      return readerCSV ;
             if ( lang.equals(SPARQLResultSetTSV) )      return readerTSV ;
-            if ( lang.equals(SPARQLResultSetThrift) )   return readerThrift ;
             throw new RiotException("Lang not registered (ResultSet reader)") ;
         }
     }
@@ -96,43 +98,49 @@ public class ResultSetReaderRegistry {
                 @Override
                 public ResultSet read(Reader in, Context context) {
                     throw new NotImplemented("Reading binary data from a java.io.Reader is not possible") ;
-                }} ;
+                    
+                }
+                @Override public SPARQLResult readAny(InputStream in, Context context) { 
+                    return new SPARQLResult(read(in, context));
+                }    
+            } ;
         }
     }
     // These all call static methods, so have no state and so don't
     // need to be created for each read operation.  
     
-    private static ResultSetReader readerXML = new ResultSetReader() {
-        @Override public ResultSet read(InputStream in, Context context)    { return XMLInput.fromXML(in); }
-        @Override public ResultSet read(Reader in, Context context)         { return XMLInput.fromXML(in); }
-    } ;
-
-    private static ResultSetReader readerJSON = new ResultSetReader() {
-        @Override public ResultSet read(InputStream in, Context context)    { return JSONInput.fromJSON(in) ; }
-        @Override public ResultSet read(Reader in, Context context)         { throw new NotImplemented("Reader") ; } 
-    } ;
+//    private static ResultSetReader readerXML = new ResultSetReader() {
+//        @Override public ResultSet read(InputStream in, Context context)    { return XMLInput.fromXML(in); }
+//        @Override public ResultSet read(Reader in, Context context)         { return XMLInput.fromXML(in); }
+//        @Override public SPARQLResult readAny(InputStream in, Context context) { return XMLInput.make(in); }
+//    };
 
+//    private static ResultSetReader readerJSON = new ResultSetReader() {
+//        @Override public ResultSet read(InputStream in, Context context)    { return JSONInput.fromJSON(in) ; }
+//        @Override public ResultSet read(Reader in, Context context)         { throw new NotImplemented("Reader") ; } 
+//    } ;
+//
     private static ResultSetReader readerCSV = new ResultSetReader() {
         @Override public ResultSet read(InputStream in, Context context)    { return CSVInput.fromCSV(in) ; }
         @Override public ResultSet read(Reader in, Context context)         { throw new NotImplemented("Reader") ; } 
+        @Override public SPARQLResult readAny(InputStream in, Context context) {
+            // Not switchable.
+            return new SPARQLResult(read(in, context));
+        } 
     } ;
     
     private static ResultSetReader readerTSV = new ResultSetReader() {
         @Override public ResultSet read(InputStream in, Context context)    { return TSVInput.fromTSV(in); }
         @Override public ResultSet read(Reader in, Context context)         { throw new NotImplemented("Reader") ; } 
-    } ;
-
-    private static ResultSetReader readerThrift = new ResultSetReader() {
-        @Override public ResultSet read(InputStream in, Context context)    { return BinRDF.readResultSet(in) ;}
-        @Override public ResultSet read(Reader in, Context context)         { 
-            throw new NotImplemented("Reading binary data from a java.io.Reader is not possible") ;
-        }
+        @Override public SPARQLResult readAny(InputStream in, Context context) {
+            // Not switchable.
+            return new SPARQLResult(read(in, context));
+        } 
     } ;
 
     private static ResultSetReader readerNo = new ResultSetReader() {
         @Override public ResultSet read(InputStream in, Context context)    { return null ; }
         @Override public ResultSet read(Reader in, Context context)         { return null ; }
+        @Override public SPARQLResult readAny(InputStream in, Context context) { return null ; }
     } ;
-    
-    
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/716b86cf/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetWriterRegistry.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetWriterRegistry.java b/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetWriterRegistry.java
index b5c4738..859ab79 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetWriterRegistry.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/resultset/ResultSetWriterRegistry.java
@@ -18,12 +18,7 @@
 
 package org.apache.jena.riot.resultset;
 
-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.SPARQLResultSetText ;
-import static org.apache.jena.riot.resultset.ResultSetLang.SPARQLResultSetThrift ;
-import static org.apache.jena.riot.resultset.ResultSetLang.SPARQLResultSetXML ;
+import static org.apache.jena.riot.resultset.ResultSetLang.*;
 
 import java.io.OutputStream ;
 import java.io.Writer ;
@@ -35,9 +30,13 @@ import org.apache.jena.atlas.lib.NotImplemented ;
 import org.apache.jena.query.ResultSet ;
 import org.apache.jena.riot.Lang ;
 import org.apache.jena.riot.RiotException ;
-import org.apache.jena.riot.thrift.BinRDF ;
+import org.apache.jena.riot.resultset.rw.ResultSetWriterJSON;
+import org.apache.jena.riot.resultset.rw.ResultSetWriterThrift;
+import org.apache.jena.riot.resultset.rw.ResultSetWriterXML;
 import org.apache.jena.sparql.core.Prologue ;
-import org.apache.jena.sparql.resultset.* ;
+import org.apache.jena.sparql.resultset.CSVOutput;
+import org.apache.jena.sparql.resultset.TSVOutput;
+import org.apache.jena.sparql.resultset.TextOutput;
 import org.apache.jena.sparql.serializer.SerializationContext ;
 import org.apache.jena.sparql.util.Context ;
 
@@ -46,11 +45,16 @@ public class ResultSetWriterRegistry {
     private static Map<Lang, ResultSetWriterFactory> registry = new HashMap<>() ;
     
     /** Lookup a {@link Lang} to get the registered {@link ResultSetReaderFactory} (or null) */
-    public static ResultSetWriterFactory lookup(Lang lang) {
+    public static ResultSetWriterFactory getFactory(Lang lang) {
         Objects.requireNonNull(lang) ;
         return registry.get(lang) ;
     }
 
+    public static boolean isRegistered(Lang lang) {
+        Objects.requireNonNull(lang) ;
+        return registry.containsKey(lang) ;
+    }
+
     /** Register a {@link ResultSetReaderFactory} for a {@link Lang} */
     public static void register(Lang lang, ResultSetWriterFactory factory) {
         Objects.requireNonNull(lang) ;
@@ -65,45 +69,21 @@ public class ResultSetWriterRegistry {
         initialized = true ;
 
         ResultSetWriterFactory factory = new ResultSetWriterFactoryStd() ;
-        register(SPARQLResultSetXML,    factory) ;
-        register(SPARQLResultSetJSON,   factory) ;
+        register(SPARQLResultSetXML,    ResultSetWriterXML.factory) ;
+        register(SPARQLResultSetJSON,   ResultSetWriterJSON.factory) ;
+        register(SPARQLResultSetThrift, ResultSetWriterThrift.factory) ;
         register(SPARQLResultSetCSV,    factory) ;
         register(SPARQLResultSetTSV,    factory) ;
-        register(SPARQLResultSetThrift, new ResultSetWriterThriftFactory()) ;
         register(SPARQLResultSetText,   factory) ;
     }
  
-    private static ResultSetWriter writerXML = new ResultSetWriter() {
-        @Override public void write(OutputStream out, ResultSet resultSet, Context context) { 
-            XMLOutput xOut = new XMLOutput(null) ;
-            xOut.format(out, resultSet) ;
-        }
-        @Override public void write(Writer out, ResultSet resultSet, Context context) {throw new NotImplemented("Writer") ; }
-        @Override public void write(OutputStream out, boolean result, Context context) {
-            XMLOutput xOut = new XMLOutput(null);
-            xOut.format(out, result);
-        }
-    } ;
-
-    private static ResultSetWriter writerJSON = new ResultSetWriter() {
-        @Override public void write(OutputStream out, ResultSet resultSet, Context context) {
-            JSONOutput jOut = new JSONOutput() ;
-            jOut.format(out, resultSet) ; 
-        }
-        @Override public void write(Writer out, ResultSet resultSet, Context context) {throw new NotImplemented("Writer") ; }
-        @Override public void write(OutputStream out, boolean result, Context context) {
-            JSONOutput jOut = new JSONOutput() ;
-            jOut.format(out, result) ; 
-        }
-    } ;
-    
     private static ResultSetWriter writerCSV = new ResultSetWriter() {
         @Override public void write(OutputStream out, ResultSet resultSet, Context context) {
             CSVOutput fmt = new CSVOutput() ;
             fmt.format(out, resultSet) ;
         }
-        @Override public void write(Writer out, ResultSet resultSet, Context context) {throw new NotImplemented("Writer") ; }
-        @Override public void write(OutputStream out, boolean result, Context context) {
+        @Override public void write(Writer out, ResultSet resultSet, Context context)   { throw new NotImplemented("Writer") ; }
+        @Override public void write(OutputStream out, boolean result, Context context)  {
             CSVOutput fmt = new CSVOutput() ;
             fmt.format(out, result) ;
         }
@@ -114,8 +94,8 @@ public class ResultSetWriterRegistry {
             TSVOutput fmt = new TSVOutput() ;
             fmt.format(out, resultSet) ;
         }
-        @Override public void write(Writer out, ResultSet resultSet, Context context) {throw new NotImplemented("Writer") ; }
-        @Override public void write(OutputStream out, boolean result, Context context) {
+        @Override public void write(Writer out, ResultSet resultSet, Context context)   {throw new NotImplemented("Writer") ; }
+        @Override public void write(OutputStream out, boolean result, Context context)  {
             TSVOutput fmt = new TSVOutput() ;
             fmt.format(out, result) ;
         }
@@ -124,7 +104,7 @@ public class ResultSetWriterRegistry {
     private static ResultSetWriter writerNo = new ResultSetWriter() {
         @Override public void write(OutputStream out, ResultSet resultSet, Context context) {}
         @Override public void write(Writer out, ResultSet resultSet, Context context)       {}
-        @Override public void write(OutputStream out, boolean result, Context context) {}
+        @Override public void write(OutputStream out, boolean result, Context context)      {}
     } ;
 
     private static ResultSetWriter writerText = new ResultSetWriter() {
@@ -145,32 +125,13 @@ public class ResultSetWriterRegistry {
         @Override
         public ResultSetWriter create(Lang lang) {
             lang = Objects.requireNonNull(lang, "Language must not be null") ;
-            if ( lang.equals(SPARQLResultSetXML) )      return writerXML ;
-            if ( lang.equals(SPARQLResultSetJSON) )     return writerJSON ;
+//            if ( lang.equals(SPARQLResultSetXML) )      return writerXML ;
+//            if ( lang.equals(SPARQLResultSetJSON) )     return writerJSON ;
             if ( lang.equals(SPARQLResultSetCSV) )      return writerCSV ;
             if ( lang.equals(SPARQLResultSetTSV) )      return writerTSV ;
             if ( lang.equals(SPARQLResultSetText) )     return writerText ;
             throw new RiotException("Lang not registered (ResultSet writer)") ;
         }
     }
-    
-    private static class ResultSetWriterThriftFactory implements ResultSetWriterFactory {
-        @Override
-        public ResultSetWriter create(Lang lang) {
-            return new ResultSetWriter() {
-                @Override
-                public void write(OutputStream out, ResultSet resultSet, Context context)
-                { BinRDF.writeResultSet(out, resultSet) ; }
-                
-                @Override
-                public void write(Writer out, ResultSet resultSet, Context context) {
-                    throw new NotImplemented("Writing binary data to a java.io.Writer is not possible") ;
-                }
-                @Override
-                public void write(OutputStream out, boolean result, Context context)
-                { throw new NotImplemented("No Thrift RDF encoding defined for boolean results"); }
-            } ;
-        }
-    }
 }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/716b86cf/jena-arq/src/main/java/org/apache/jena/riot/resultset/rw/JSONInputIterator.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/resultset/rw/JSONInputIterator.java b/jena-arq/src/main/java/org/apache/jena/riot/resultset/rw/JSONInputIterator.java
new file mode 100644
index 0000000..ccf770b
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/riot/resultset/rw/JSONInputIterator.java
@@ -0,0 +1,657 @@
+/**
+ * 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.resultset.rw;
+
+import java.io.InputStream;
+import java.util.*;
+
+import org.apache.jena.atlas.AtlasException;
+import org.apache.jena.atlas.io.IO;
+import org.apache.jena.atlas.io.IndentedWriter;
+import org.apache.jena.atlas.io.PeekReader;
+import org.apache.jena.atlas.iterator.PeekIterator;
+import org.apache.jena.atlas.json.io.parser.TokenizerJSON;
+import org.apache.jena.datatypes.TypeMapper;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.query.QueryException;
+import org.apache.jena.riot.RiotParseException;
+import org.apache.jena.riot.tokens.Token;
+import org.apache.jena.riot.tokens.TokenType;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.engine.binding.Binding;
+import org.apache.jena.sparql.engine.binding.BindingFactory;
+import org.apache.jena.sparql.engine.binding.BindingMap;
+import org.apache.jena.sparql.engine.iterator.QueryIteratorBase;
+import org.apache.jena.sparql.serializer.SerializationContext;
+
+/**
+ * Streaming Iterator over SPARQL JSON results, not yet fully implemented (see
+ * JENA-267)
+ * <p>
+ * Creating the Iterator automatically causes it to parse a small chunk of the
+ * stream to determine the variables in the result set either by reading the
+ * header or reading some portion of the results if the results appear before
+ * the header since JSON does not guarantee the order of keys within an object
+ * </p>
+ */
+public class JSONInputIterator extends QueryIteratorBase {
+
+    private InputStream         input;
+
+    private boolean             isBooleanResults = false,
+                                    boolResult = false, headerSeen = false;
+    private Binding             binding          = null;
+    private TokenizerJSON       tokens;
+    private PeekIterator<Token> peekIter;
+
+    private Queue<Binding>      cache            = new LinkedList<>();
+    private Set<String>         vars             = new HashSet<>();
+
+    /**
+     * Creates a SPARQL JSON Iterator
+     * <p>
+     * Automatically parses some portion of the input to determine the variables
+     * in use
+     * </p>
+     */
+    public JSONInputIterator(InputStream input) {
+        this.input = input;
+        this.tokens = new TokenizerJSON(PeekReader.makeUTF8(input));
+        this.peekIter = new PeekIterator<>(this.tokens);
+
+        // We should always parse the first little bit to see the head stuff or
+        // to cache a chunk of results and infer the headers
+        // Primarily we are trying to find out what the variables are
+        preParse();
+    }
+
+    /**
+     * Returns the variables present in the result sets
+     */
+    public Iterator<String> getVars() {
+        return vars.iterator();
+    }
+
+    /**
+     * Gets whether the SPARQL JSON represents a boolean result set
+     */
+    public boolean isBooleanResult() {
+        return isBooleanResults;
+    }
+
+    /**
+     * Does the pre-parsing which attempts to read the header of the results
+     * file and determine variables present
+     * <p>
+     * If the header is encountered first then we read this, if the results are
+     * encountered first we parse the first 100 results and determine the
+     * variables present from those instead
+     * </p>
+     */
+    private void preParse() {
+        // First off the { to start the object
+        expect("Expected the start of the JSON Results Object", TokenType.LBRACE);
+
+        // Then expect to see a Property Name
+        // Loop here because we might see some things we can discard first
+        do {
+            if ( !isPropertyName() ) {
+                Token t = nextToken();
+                String name = t.getImage();
+                checkColon();
+
+                if ( name.equals("head") ) {
+                    if ( headerSeen )
+                        exception(t, "Invalid duplicate header property");
+                    parseHeader();
+                    // Continue afterwards because we want to be in place to
+                    // start streaming results
+                } else if ( name.equals("boolean") ) {
+                    parseBoolean();
+                    // Afterwards we continue because we want to see an empty
+                    // head
+                } else if ( name.equals("results") ) {
+                    if ( isBooleanResults )
+                        exception(t, "Encountered results property when boolean property has already been countered");
+
+                    // Scroll to first result
+                    parseToFirstResult();
+
+                    // If we already saw the header then exit at this point
+                    if ( headerSeen )
+                        return;
+
+                    // If not we're going to pre-cache some chunk of results so
+                    // we can infer the variable names
+                    boolean complete = cacheResults(100);
+
+                    // If this exhausted the result set then we can continue
+                    // looking for the header
+                    // Otherwise we should exit as we may eventually see the
+                    // header later...
+                    if ( !complete ) {
+                        // TODO Now determine variables present from this
+                        return;
+                    }
+                } else {
+                    ignoreValue();
+                }
+                checkComma(TokenType.RBRACE);
+            } else if ( lookingAt(TokenType.RBRACE) ) {
+                // We hit the end of the result object already
+                if ( !headerSeen )
+                    exception(peekToken(), "End of JSON Results Object encountered before a valid header was seen");
+                nextToken();
+
+                // Shouldn't be any further content
+                if ( !lookingAt(TokenType.EOF) )
+                    exception(peekToken(), "Unexpected content after end of JSON Results Object");
+
+                // Can stop our initial buffering at this stage
+                return;
+            } else {
+                exception(peekToken(), "Expected a JSON property name but got %s", peekToken());
+            }
+        } while (true);
+    }
+
+    private void parseHeader() {
+        do {
+            if ( isPropertyName() ) {
+                Token t = nextToken();
+                String name = t.getImage();
+                checkColon();
+
+                if ( name.equals("vars") ) {
+                    parseVars();
+                } else if ( name.equals("link") ) {
+                    // Throw away the links
+                    skipLinks();
+                } else {
+                    exception(t, "Unexpected property %s encountered in head object", name);
+                }
+                checkComma(TokenType.RBRACE);
+            } else if ( lookingAt(TokenType.RBRACE) ) {
+                nextToken();
+                return;
+            } else {
+                exception(peekToken(), "Unexpected Token encountered while parsing head object");
+            }
+        } while (true);
+    }
+
+    private void parseVars() {
+        if ( lookingAt(TokenType.LBRACKET) ) {
+            nextToken();
+            vars.clear();
+            do {
+                if ( lookingAt(TokenType.STRING) ) {
+                    Token t = nextToken();
+                    String var = t.getImage();
+                    vars.add(var);
+                    checkComma(TokenType.RBRACKET);
+                } else if ( lookingAt(TokenType.RBRACKET) ) {
+                    nextToken();
+                    return;
+                } else {
+                    exception(peekToken(), "Unexpected Token encountered while parsing the variables list in the head object");
+                }
+            } while (true);
+        } else {
+            exception(peekToken(), "Unexpected Token ecountered, expected a [ to start the array of variables in the head object");
+        }
+    }
+
+    private void skipLinks() {
+        if ( lookingAt(TokenType.LBRACKET) ) {
+            nextToken();
+            do {
+                if ( lookingAt(TokenType.RBRACKET) ) {
+                    // End of links
+                    nextToken();
+                    return;
+                } else if ( lookingAt(TokenType.STRING) ) {
+                    // Ignore link and continue
+                    nextToken();
+                } else {
+                    exception(peekToken(), "Unexpected Token when a Link URI was expected");
+                }
+                checkComma(TokenType.RBRACKET);
+            } while (true);
+        } else {
+            exception(peekToken(), "Unexpected token when a [ was expected to start the list of URIs for a link property");
+        }
+    }
+
+    private void parseToFirstResult() {
+        if ( lookingAt(TokenType.LBRACE) ) {
+            nextToken();
+            if ( isPropertyName() ) {
+                Token t = nextToken();
+                String name = t.getImage();
+                if ( name.equals("bindings") ) {
+                    checkColon();
+                    if ( lookingAt(TokenType.LBRACKET) ) {
+                        nextToken();
+                    } else {
+                        exception(peekToken(), "Unexpected Token encountered, expected a [ for the start of the bindings array");
+                    }
+                } else {
+                    exception(t, "Unexpected Token encountered, expected the bindings property");
+                }
+            } else {
+                exception(peekToken(), "Unexpected Token ecnountered, expected the bindings property");
+            }
+        } else {
+            exception(peekToken(), "Unexpected Token encountered, expected a { to start the results list object");
+        }
+    }
+
+    private void parseToEnd() {
+        // TODO Parse through to end of the JSON document consuming the header
+        // if we haven't seen it already
+        checkComma(TokenType.RBRACE);
+    }
+
+    private void ignoreValue() {
+        if ( isPropertyName() ) {
+            // Just a string value so can discard and then check for the
+            // subsequent comma
+            nextToken();
+            checkComma(TokenType.RBRACE);
+        } else if ( lookingAt(TokenType.DECIMAL) || lookingAt(TokenType.INTEGER) || lookingAt(TokenType.DOUBLE)
+                    || lookingAt(TokenType.KEYWORD) ) {
+            // Just a numeric/keyword (boolean) value do discard and check for
+            // subsequent comma
+            nextToken();
+            checkComma(TokenType.RBRACE);
+        } else if ( lookingAt(TokenType.LBRACE) ) {
+            // Start of an Object
+            nextToken();
+
+            // TODO We should really care about the syntactic validity of
+            // objects we are ignoring but that seems like a bit too much effort
+            int openBraces = 1;
+            while (openBraces >= 1) {
+                Token next = nextToken();
+                if ( next.getType().equals(TokenType.LBRACE) ) {
+                    openBraces++;
+                } else if ( next.getType().equals(TokenType.RBRACE) ) {
+                    openBraces--;
+                }
+            }
+            checkComma(TokenType.RBRACE);
+        } else if ( lookingAt(TokenType.LBRACKET) ) {
+            // Start of an Array
+            nextToken();
+
+            // TODO We should really care about the syntactic validity of
+            // objects we are ignoring but that seems like a bit too much effort
+            int openBraces = 1;
+            while (openBraces >= 1) {
+                Token next = nextToken();
+                if ( next.getType().equals(TokenType.LBRACKET) ) {
+                    openBraces++;
+                } else if ( next.getType().equals(TokenType.RBRACKET) ) {
+                    openBraces--;
+                }
+            }
+            checkComma(TokenType.RBRACE);
+        } else {
+            exception(peekToken(), "Unexpected Token");
+        }
+    }
+
+    /**
+     * Caches the first N results so we can infer variables, indicates whether
+     * the caching exhausted the result set
+     * 
+     * @param n
+     *            Number of results to cache
+     */
+    private boolean cacheResults(int n) {
+        for ( int i = 0 ; i < n ; i++ ) {
+            if ( parseNextBinding() ) {
+                this.cache.add(this.binding);
+                this.binding = null;
+            } else {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void parseBoolean() {
+        isBooleanResults = true;
+        if ( lookingAt(TokenType.KEYWORD) ) {
+            Token t = nextToken();
+            String keyword = t.getImage();
+            if ( keyword.equals("true") ) {
+                boolResult = true;
+            } else if ( keyword.equals("false") ) {
+                boolResult = false;
+            } else {
+                exception(t, "Unexpected keyword %s encountered, expected true or false", keyword);
+            }
+        } else {
+            exception(peekToken(), "Unexpected token when a true/false keyword was expected for the value of the boolean property");
+        }
+    }
+
+    @Override
+    public void output(IndentedWriter out, SerializationContext sCxt) {
+        // Not needed - only called as part of printing/debugging query plans.
+        out.println("JSONInputIterator");
+    }
+
+    @Override
+    protected boolean hasNextBinding() {
+        if ( isBooleanResults )
+            return false;
+
+        if ( this.input != null ) {
+            if ( this.cache.size() > 0 ) {
+                this.binding = this.cache.remove();
+                return true;
+            } else if ( this.binding == null ) {
+                return this.parseNextBinding();
+            } else {
+                return true;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    private boolean parseNextBinding() {
+        if ( lookingAt(TokenType.LBRACE) ) {
+            nextToken();
+            BindingMap b = BindingFactory.create();
+            do {
+                if ( isPropertyName() ) {
+                    Token t = nextToken();
+                    String var = t.getImage();
+                    checkColon();
+
+                    Node n = parseNode();
+                    b.add(Var.alloc(var), n);
+
+                    checkComma(TokenType.RBRACE);
+                } else if ( lookingAt(TokenType.RBRACE) ) {
+                    nextToken();
+                    checkComma(TokenType.RBRACKET);
+                    break;
+                } else {
+                    exception(peekToken(), "Unexpected Token encountered, expected a property name to indicate the value for a variable");
+                }
+            } while (true);
+
+            this.binding = b;
+            return true;
+        } else if ( lookingAt(TokenType.RBRACKET) ) {
+            // End of Bindings Array
+            nextToken();
+            if ( lookingAt(TokenType.RBRACE) ) {
+                nextToken();
+                parseToEnd();
+            } else {
+                exception(peekToken(), "Unexpected Token encountered, expected a } to end the results object");
+            }
+        } else {
+            exception(peekToken(),
+                      "Unexpected Token encountered, expected a { for the start of a binding of ] to end the array of bindings");
+        }
+        return false;
+    }
+
+    private Node parseNode() {
+        String type, value, lang, datatype;
+        type = value = lang = datatype = null;
+
+        if ( lookingAt(TokenType.LBRACE) ) {
+            Token pos = nextToken();
+
+            // Collect the Properties
+            do {
+                if ( isPropertyName() ) {
+                    Token t = nextToken();
+                    String name = t.getImage();
+                    checkColon();
+
+                    if ( name.equals("type") ) {
+                        if ( type != null )
+                            exception(t, "Illegal duplicate type property");
+                        type = parseNodeInfo("type");
+                    } else if ( name.equals("value") ) {
+                        if ( value != null )
+                            exception(t, "Illegal duplicate value property");
+                        value = parseNodeInfo("value");
+                    } else if ( name.equals("datatype") ) {
+                        if ( datatype != null )
+                            exception(t, "Illegal duplicate datatype property");
+                        datatype = parseNodeInfo("datatype");
+                    } else if ( name.equals("xml:lang") ) {
+                        if ( lang != null )
+                            exception(t, "Illegal duplicate xml:lang property");
+                        lang = parseNodeInfo("xml:lang");
+                    } else {
+                        exception(t, "Unexpected Property Name '%s', expected one of type, value, datatype or xml:lang", name);
+                    }
+                } else if ( lookingAt(TokenType.RBRACE) ) {
+                    nextToken();
+                    break;
+                } else {
+                    exception(peekToken(), "Unexpected Token, expected a property name as part of a Node object");
+                }
+            } while (true);
+
+            // Error if missing type or value
+            if ( type == null )
+                exception(pos, "Encountered a Node object with no type property");
+            if ( value == null )
+                exception(pos, "Encountered a Node object with no value property");
+
+            // Generate a Node based on the properties we saw
+            if ( type.equals("uri") ) {
+                return NodeFactory.createURI(value);
+            } else if ( type.equals("literal") ) {
+                if ( datatype != null ) {
+                    return NodeFactory.createLiteral(value, TypeMapper.getInstance().getSafeTypeByName(datatype));
+                } else if ( lang != null ) {
+                    return NodeFactory.createLiteral(value, lang);
+                } else {
+                    return NodeFactory.createLiteral(value);
+                }
+            } else if ( type.equals("bnode") ) {
+                return NodeFactory.createBlankNode(value);
+            } else {
+                exception(pos, "Encountered a Node object with an invalid type value '%s', expected one of uri, literal or bnode", type);
+            }
+        } else {
+            exception(peekToken(), "Unexpected Token, expected a { for the start of a Node object");
+        }
+        return null;
+    }
+
+    private String parseNodeInfo(String name) {
+        if ( lookingAt(TokenType.STRING) ) {
+            Token t = nextToken();
+            String value = t.getImage();
+            checkComma(TokenType.RBRACE);
+            return value;
+        } else {
+            exception(peekToken(), "Unexpected Token, expected a string as the value for the %s property", name);
+            return null;
+        }
+    }
+
+    @Override
+    protected Binding moveToNextBinding() {
+        if ( !hasNext() )
+            throw new NoSuchElementException();
+        Binding b = this.binding;
+        this.binding = null;
+        return b;
+    }
+
+    @Override
+    protected void closeIterator() {
+        IO.close(input);
+        input = null;
+    }
+
+    @Override
+    protected void requestCancel() {
+        // Don't need to do anything special to cancel
+        // Superclass should take care of that and call closeIterator() where we
+        // do our actual clean up
+    }
+
+    // JSON Parsing Helpers taken from LangRDFJSON
+
+    private boolean isPropertyName() {
+        return lookingAt(TokenType.STRING);
+    }
+
+    private Token checkValidForStringProperty(String property) {
+        Token t = null;
+        if ( lookingAt(TokenType.STRING) ) {
+            t = nextToken();
+        } else {
+            exception(peekToken(), "JSON Values given for property " + property + " must be Strings");
+        }
+        return t;
+    }
+
+    private void checkColon() {
+        if ( !lookingAt(TokenType.COLON) ) {
+            exception(peekToken(), "Expected a : character after a JSON Property Name but got %s", peekToken());
+        }
+        nextToken();
+    }
+
+    private void checkComma(TokenType terminator) {
+        if ( lookingAt(TokenType.COMMA) ) {
+            nextToken();
+        } else if ( lookingAt(terminator) ) {
+            return;
+        } else {
+            exception(peekToken(), "Unexpected Token encountered, expected a , or a %s", terminator);
+        }
+    }
+
+    // Streaming Parsing Helper Functions nicked from LangEngine
+
+    // ---- Managing tokens.
+
+    protected final Token peekToken() {
+        // Avoid repeating.
+        if ( eof() )
+            return tokenEOF;
+        return peekIter.peek();
+    }
+
+    // Set when we get to EOF to record line/col of the EOF.
+    private Token tokenEOF = null;
+
+    protected final boolean eof() {
+        if ( tokenEOF != null )
+            return true;
+
+        if ( !moreTokens() ) {
+            tokenEOF = new Token(tokens.getLine(), tokens.getColumn());
+            tokenEOF.setType(TokenType.EOF);
+            return true;
+        }
+        return false;
+    }
+
+    protected final boolean moreTokens() {
+        return peekIter.hasNext();
+    }
+
+    protected final boolean lookingAt(TokenType tokenType) {
+        if ( eof() )
+            return tokenType == TokenType.EOF;
+        if ( tokenType == TokenType.NODE )
+            return peekToken().isNode();
+        return peekToken().hasType(tokenType);
+    }
+
+    // Remember line/col of last token for messages
+    protected long currLine = -1;
+    protected long currCol  = -1;
+
+    protected final Token nextToken() {
+        if ( eof() )
+            return tokenEOF;
+
+        // Tokenizer errors appear here!
+        try {
+            Token t = peekIter.next();
+            currLine = t.getLine();
+            currCol = t.getColumn();
+            return t;
+        }
+        catch (RiotParseException ex) {
+            // Intercept to log it.
+            raiseException(ex);
+            throw ex;
+        }
+        catch (AtlasException ex) {
+            // Bad I/O
+            RiotParseException ex2 = new RiotParseException(ex.getMessage(), -1, -1);
+            raiseException(ex2);
+            throw ex2;
+        }
+    }
+
+    protected final void expectOrEOF(String msg, TokenType tokenType) {
+        // DOT or EOF
+        if ( eof() )
+            return;
+        expect(msg, tokenType);
+    }
+
+    protected final void expect(String msg, TokenType ttype) {
+
+        if ( !lookingAt(ttype) ) {
+            Token location = peekToken();
+            exception(location, msg);
+        }
+        nextToken();
+    }
+
+    protected final void exception(Token token, String msg, Object... args) {
+        if ( token != null )
+            exceptionDirect(String.format(msg, args), token.getLine(), token.getColumn());
+        else
+            exceptionDirect(String.format(msg, args), -1, -1);
+    }
+
+    protected final void exceptionDirect(String msg, long line, long col) {
+        raiseException(new RiotParseException(msg, line, col));
+    }
+
+    protected final void raiseException(RiotParseException ex) {
+        throw new QueryException("Error passing SPARQL JSON results", ex);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/716b86cf/jena-arq/src/main/java/org/apache/jena/riot/resultset/rw/JSONResultsKW.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/resultset/rw/JSONResultsKW.java b/jena-arq/src/main/java/org/apache/jena/riot/resultset/rw/JSONResultsKW.java
new file mode 100644
index 0000000..beac34f
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/riot/resultset/rw/JSONResultsKW.java
@@ -0,0 +1,44 @@
+/*
+ * 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.resultset.rw;
+
+//Keywords for JSON:
+//Taken from:
+//From http://www.w3.org/TR/sparql11-results-json/ (Oct 2011)
+
+public class JSONResultsKW
+{
+    public static String kHead          = "head" ;
+    public static String kVars          = "vars" ;
+    public static String kLink          = "link" ;
+    public static String kResults       = "results" ;
+    public static String kBindings      = "bindings" ;
+    public static String kType          = "type" ;
+    public static String kUri           = "uri"  ;
+    public static String kValue         = "value" ;
+    public static String kLiteral       = "literal" ;
+    public static String kUnbound       = "undef" ;
+    // Legacy.
+    public static String kTypedLiteral  = "typed-literal" ;
+    public static String kXmlLang       = "xml:lang" ;
+    public static String kDatatype      = "datatype" ;
+    public static String kBnode         = "bnode" ;
+    public static String kBoolean       = "boolean" ;
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/716b86cf/jena-arq/src/main/java/org/apache/jena/riot/resultset/rw/ReadAnything.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/resultset/rw/ReadAnything.java b/jena-arq/src/main/java/org/apache/jena/riot/resultset/rw/ReadAnything.java
new file mode 100644
index 0000000..089845b
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/riot/resultset/rw/ReadAnything.java
@@ -0,0 +1,100 @@
+/*
+ * 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.resultset.rw;
+
+import java.util.function.Supplier;
+
+import org.apache.jena.atlas.web.ContentType;
+import org.apache.jena.atlas.web.TypedInputStream;
+import org.apache.jena.query.ARQ;
+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.*;
+import org.apache.jena.riot.resultset.ResultSetReaderRegistry;
+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.sparql.resultset.SPARQLResult;
+import org.apache.jena.sparql.util.Context;
+import org.apache.jena.system.Txn;
+
+/** Read anything (RDF).
+ * <li>By MIME type.
+ * <li>By format (resultset, boolean, graph)
+ */
+public class ReadAnything {
+    
+    /** Read something RDF/SPARQL like */ 
+    public static SPARQLResult read(String url) {
+        return read(url, ARQ.getContext());
+    }
+
+    /** Read something RDF/SPARQL like */ 
+    public static SPARQLResult read(String url, Context context) {
+        TypedInputStream in = StreamManager.get(context).open(url);
+        ContentType ct = WebContent.determineCT(in.getContentType(), null, url);
+        Lang lang = RDFLanguages.contentTypeToLang(ct);
+        
+        if ( RDFLanguages.isTriples(lang) ) {
+            Model model = ModelFactory.createDefaultModel();
+            Supplier<SPARQLResult> r = ()->{
+                StreamRDF sink = StreamRDFLib.graph(model.getGraph());
+                RDFParser.source(in).lang(lang).parse(sink);
+                return new SPARQLResult(model);
+            };
+            if ( model.supportsTransactions() )
+                return model.calculateInTxn(r);
+            else
+                return r.get();
+        }
+
+        if ( RDFLanguages.isQuads(lang) ) {
+            Dataset ds = DatasetFactory.create();
+            Supplier<SPARQLResult> r = ()->{
+                StreamRDF sink = StreamRDFLib.dataset(ds.asDatasetGraph());
+                RDFParser.source(in).lang(lang).parse(sink);
+                return new SPARQLResult(ds);
+            };
+            
+            if ( ds.supportsTransactions() ) 
+                return Txn.calculateWrite(ds, r);
+            else
+                return r.get();
+        }
+        
+        if ( ResultSetReaderRegistry.isRegistered(lang) ) {
+            return 
+                ResultsReader.create()
+                    .forceLang(lang)
+                    .context(context)
+                    .build()
+                    .readAny(in.getInputStream());
+            // Which would do, if we need to invert the code ...
+//            ResultSetReaderFactory factory = ResultSetReaderRegistry.getFactory(lang);
+//            if ( factory == null )
+//                throw new RiotException("No ResultSetReaderFactory for "+lang);
+//            ResultSetReader reader = factory.create(lang);
+//            ResultSet rs = reader.read(in.getInputStream(), context);
+        }
+
+        throw new RiotException("Failed to determine: lang = "+lang);
+    }
+}


Mime
View raw message