jena-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a...@apache.org
Subject [07/11] jena git commit: JENA-1454: Use of new result set machinery for HTTP responses
Date Sun, 31 Dec 2017 10:52:45 GMT
JENA-1454: Use of new result set machinery for HTTP responses


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

Branch: refs/heads/master
Commit: 1e1da9570e2d07a1500d85c2b2b1e495624ece00
Parents: b022dc1
Author: Andy Seaborne <andy@apache.org>
Authored: Sat Dec 23 15:51:55 2017 +0000
Committer: Andy Seaborne <andy@apache.org>
Committed: Sat Dec 23 21:13:28 2017 +0000

----------------------------------------------------------------------
 .../org/apache/jena/query/ResultSetFactory.java |   3 +-
 .../java/org/apache/jena/riot/WebContent.java   |  15 ++
 .../riot/lang/BlankNodeAllocatorGlobal.java     |  58 ++++++
 .../lang/BlankNodeAllocatorTraditional.java     |  59 ------
 .../org/apache/jena/riot/lang/LabelToNode.java  |   8 +-
 .../jena/sparql/engine/QueryEngineBase.java     |   2 +-
 .../jena/sparql/engine/QueryExecutionBase.java  |   2 +-
 .../sparql/engine/http/QueryEngineHTTP.java     |  61 +++---
 .../org/apache/jena/sparql/expr/E_BNode.java    |   4 +-
 .../org/apache/jena/sparql/lang/ParserBase.java |   1 +
 .../sparql/modify/UpdateProcessRemoteBase.java  |   2 +-
 .../jena/sparql/modify/UpdateProcessorBase.java |   2 +-
 .../modify/UpdateProcessorStreamingBase.java    |   2 +-
 .../apache/jena/sparql/resultset/JSONInput.java |   2 +-
 .../jena/sparql/resultset/JSONOutput.java       |   2 +-
 .../apache/jena/sparql/resultset/XMLInput.java  |   2 +
 .../jena/sparql/resultset/XMLInputSAX.java      |   2 +-
 .../apache/jena/sparql/resultset/XMLOutput.java |  40 ++--
 .../jena/sparql/sse/lang/ParseHandlerPlain.java |   6 +-
 .../org/apache/jena/sparql/util/Context.java    |  43 +++--
 .../apache/jena/sparql/util/LabelToNodeMap.java |   1 -
 .../jena/riot/lang/TestBlankNodeAllocator.java  |   2 +-
 .../apache/jena/riot/lang/TestLabelToNode.java  |   2 +-
 jena-fuseki2/examples/service-tdb1-B.ttl        |   1 +
 .../main/java/org/apache/jena/fuseki/DEF.java   |   6 +
 .../apache/jena/fuseki/servlets/ActionBase.java |   6 -
 .../apache/jena/fuseki/servlets/HttpAction.java |   8 +
 .../jena/fuseki/servlets/ResponseDataset.java   |   2 +-
 .../jena/fuseki/servlets/ResponseOps.java       |  21 +++
 .../jena/fuseki/servlets/ResponseResultSet.java | 187 ++++++++-----------
 30 files changed, 299 insertions(+), 253 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/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 5682b3d..20320a5 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
@@ -41,8 +41,9 @@ import org.apache.jena.util.FileManager ;
 /** ResultSetFactory - make result sets from places other than a query. */
 
 public class ResultSetFactory {
-    // See also ResultSetMgr -- this post-dates this code.
+    // See also ResultSetMgr - which post-dates this code.
     // Ideally, read operations here should call ResultSetMgr.
+    // The exception is XML from a string and the arcachic RDF to ResultSet forms.
     
     /**
      * Load a result set from file or URL into a result set (memory backed).

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/riot/WebContent.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/WebContent.java b/jena-arq/src/main/java/org/apache/jena/riot/WebContent.java
index 3aa0ce8..f265acc 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/WebContent.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/WebContent.java
@@ -20,6 +20,7 @@ package org.apache.jena.riot;
 
 import org.apache.jena.atlas.lib.Lib ;
 import org.apache.jena.atlas.web.ContentType ;
+import org.apache.jena.riot.resultset.ResultSetLang;
 
 
 public class WebContent
@@ -270,4 +271,18 @@ public class WebContent
         
         return ct ;
     }
+    
+    /** Map content-type to lang for SPARQL results, with pragmatic adapters. */   
+    public static Lang contentTypeToLangResultSet(String contentType) {
+        if ( contentType == null )
+            return null;
+        // Special cases : use of application/xml and application/json
+        if ( contentType.equals(WebContent.contentTypeXML) )
+            return ResultSetLang.SPARQLResultSetXML;
+        else if ( contentType.equals(WebContent.contentTypeJSON) )
+            return ResultSetLang.SPARQLResultSetJSON;
+        Lang lang = RDFLanguages.contentTypeToLang(contentType);
+        // May not be a reader/write result set language. 
+        return lang;
+    }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorGlobal.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorGlobal.java b/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorGlobal.java
new file mode 100644
index 0000000..6ad621b
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorGlobal.java
@@ -0,0 +1,58 @@
+/**
+ * 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.lang;
+
+import java.util.HashMap ;
+import java.util.Map ;
+
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.NodeFactory ;
+
+/** Allocate blank nodes by creating a randomly generated blank node.
+ *  This allocator has arbitrary sized state. 
+ */
+
+public class BlankNodeAllocatorGlobal implements BlankNodeAllocator
+{
+    Map<String, Node> map = new HashMap<>() ;
+    
+    public BlankNodeAllocatorGlobal()  {}
+
+    @Override
+    public void reset()         { map.clear() ; }
+
+    @Override
+    public Node alloc(String label)
+    {
+        Node b = map.get(label) ;
+        if ( b == null )
+        {
+            b = create() ;
+            map.put(label, b) ;
+        }
+        return b ;
+    }
+    
+    
+    @Override
+    public Node create()
+    {
+        return NodeFactory.createBlankNode() ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorTraditional.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorTraditional.java b/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorTraditional.java
deleted file mode 100644
index b44fd43..0000000
--- a/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorTraditional.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * 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.lang;
-
-import java.util.HashMap ;
-import java.util.Map ;
-
-import org.apache.jena.graph.Node ;
-import org.apache.jena.graph.NodeFactory ;
-
-/** Allocate blank nodes according to the traditional policy (up to jena 2.10.0)
- *  This allocator has arbitrary sized state. 
- *  Create a fresh one for each parser run.
- */
-
-public class BlankNodeAllocatorTraditional implements BlankNodeAllocator
-{
-    Map<String, Node> map = new HashMap<>() ;
-    
-    public BlankNodeAllocatorTraditional()  {}
-
-    @Override
-    public void reset()         { map.clear() ; }
-
-    @Override
-    public Node alloc(String label)
-    {
-        Node b = map.get(label) ;
-        if ( b == null )
-        {
-            b = create() ;
-            map.put(label, b) ;
-        }
-        return b ;
-    }
-    
-    
-    @Override
-    public Node create()
-    {
-        return NodeFactory.createBlankNode() ;
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/riot/lang/LabelToNode.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/lang/LabelToNode.java b/jena-arq/src/main/java/org/apache/jena/riot/lang/LabelToNode.java
index 0222b05..4c69fa9 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/lang/LabelToNode.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/lang/LabelToNode.java
@@ -50,8 +50,8 @@ public class LabelToNode extends MapWithScope<String, Node, Node>
     { return new LabelToNode(new AllocScopePolicy(), nodeAllocatorHash(seed)) ; }
 
     /** The policy up to jena 2.10.0 - problems at very large scale */
-    public static LabelToNode createScopeByDocumentOld()
-    { return new LabelToNode(new SingleScopePolicy(), nodeAllocatorTraditional()) ; }
+    public static LabelToNode createScopeGlobal()
+    { return new LabelToNode(new SingleScopePolicy(), nodeAllocatorGlobal()) ; }
 
     /** Allocation scoped by graph and label. */
     public static LabelToNode createScopeByGraph() {
@@ -101,8 +101,8 @@ public class LabelToNode extends MapWithScope<String, Node, Node>
         return new Alloc(new BlankNodeAllocatorLabel()) ; 
     } 
     
-    private static Allocator<String, Node, Node> nodeAllocatorTraditional() { 
-        return new Alloc(new BlankNodeAllocatorTraditional()) ; 
+    private static Allocator<String, Node, Node> nodeAllocatorGlobal() { 
+        return new Alloc(new BlankNodeAllocatorGlobal()) ; 
     } 
     
     private static Allocator<String, Node, Node> nodeAllocatorEncoded() { 

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryEngineBase.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryEngineBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryEngineBase.java
index 0204c5e..5fd8aed 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryEngineBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryEngineBase.java
@@ -63,7 +63,7 @@ public abstract class QueryEngineBase implements OpEval, Closeable
         // Ensure context setup - usually done in QueryExecutionBase
         // so it can be changed after initialization.
         if ( context == null )
-            context = Context.setupContext(context, dataset) ;
+            context = Context.setupContextExec(context, dataset) ;
         this.query = null ;
         setOp(op) ;
     }

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryExecutionBase.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryExecutionBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryExecutionBase.java
index dbc930e..1dc292e 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryExecutionBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryExecutionBase.java
@@ -88,7 +88,7 @@ public class QueryExecutionBase implements QueryExecution
     
     private void init() {
         DatasetGraph dsg = (dataset == null) ? null : dataset.asDatasetGraph() ;
-        context = Context.setupContext(context, dsg) ;
+        context = Context.setupContextExec(context, dsg) ;
         if ( query != null )
             context.put(ARQConstants.sysCurrentQuery, query) ;
         // NB: Setting timeouts via the context after creating a QueryExecutionBase 

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/QueryEngineHTTP.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/QueryEngineHTTP.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/QueryEngineHTTP.java
index 713cbc0..d424b76 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/QueryEngineHTTP.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/http/QueryEngineHTTP.java
@@ -35,18 +35,14 @@ import org.apache.jena.atlas.lib.Pair ;
 import org.apache.jena.graph.Triple ;
 import org.apache.jena.query.* ;
 import org.apache.jena.rdf.model.Model ;
-import org.apache.jena.riot.Lang ;
-import org.apache.jena.riot.RDFDataMgr ;
-import org.apache.jena.riot.RDFLanguages ;
-import org.apache.jena.riot.WebContent ;
+import org.apache.jena.riot.*;
+import org.apache.jena.riot.resultset.ResultSetLang;
+import org.apache.jena.riot.resultset.ResultSetReaderRegistry;
 import org.apache.jena.sparql.ARQException ;
 import org.apache.jena.sparql.core.Quad;
 import org.apache.jena.sparql.engine.ResultSetCheckCondition ;
 import org.apache.jena.sparql.graph.GraphFactory ;
-import org.apache.jena.sparql.resultset.CSVInput ;
-import org.apache.jena.sparql.resultset.JSONInput ;
-import org.apache.jena.sparql.resultset.TSVInput ;
-import org.apache.jena.sparql.resultset.XMLInput ;
+import org.apache.jena.sparql.resultset.ResultSetException;
 import org.apache.jena.sparql.util.Context ;
 import org.slf4j.Logger ;
 import org.slf4j.LoggerFactory ;
@@ -367,16 +363,16 @@ public class QueryEngineHTTP implements QueryExecution {
             actualContentType = selectContentType;
         }
 
-        if (actualContentType.equals(WebContent.contentTypeResultsXML) || actualContentType.equals(WebContent.contentTypeXML))
-            return ResultSetFactory.fromXML(in);
-        if (actualContentType.equals(WebContent.contentTypeResultsJSON) || actualContentType.equals(WebContent.contentTypeJSON))
-            return ResultSetFactory.fromJSON(in);
-        if (actualContentType.equals(WebContent.contentTypeTextTSV))
-            return ResultSetFactory.fromTSV(in);
-        if (actualContentType.equals(WebContent.contentTypeTextCSV))
-            return CSVInput.fromCSV(in);
-        throw new QueryException("Endpoint returned Content-Type: " + actualContentType
-                + " which is not currently supported for SELECT queries");
+        // Map to lang, with pragmatic alternatives. 
+        Lang lang = WebContent.contentTypeToLangResultSet(actualContentType);
+        if ( lang == null )
+            throw new QueryException("Endpoint returned Content-Type: " + actualContentType + " which is not rcognized for SELECT queries");
+        if ( !ResultSetReaderRegistry.isRegistered(lang) )
+            throw new QueryException("Endpoint returned Content-Type: " + actualContentType + " which is not supported for SELECT queries");
+        // This returns a streaming result set for some formats.
+        // Do not close the InputStream at this point. 
+        ResultSet result = ResultSetMgr.read(in, lang);
+        return result;
     }
 
     @Override
@@ -499,18 +495,23 @@ public class QueryEngineHTTP implements QueryExecution {
                 actualContentType = askContentType;
             }
 
-            // Parse the result appropriately depending on the
-            // selected content type.
-            if (actualContentType.equals(WebContent.contentTypeResultsXML) || actualContentType.equals(WebContent.contentTypeXML))
-                return XMLInput.booleanFromXML(in);
-            if (actualContentType.equals(WebContent.contentTypeResultsJSON) || actualContentType.equals(WebContent.contentTypeJSON))
-                return JSONInput.booleanFromJSON(in);
-            if (actualContentType.equals(WebContent.contentTypeTextTSV))
-                return TSVInput.booleanFromTSV(in);
-            if (actualContentType.equals(WebContent.contentTypeTextCSV))
-                return CSVInput.booleanFromCSV(in);
-            throw new QueryException("Endpoint returned Content-Type: " + actualContentType
-                    + " which is not currently supported for ASK queries");
+            Lang lang = RDFLanguages.contentTypeToLang(actualContentType);
+            if ( lang == null ) {
+                // Any specials :
+                // application/xml for application/sparql-results+xml
+                // application/json for application/sparql-results+json
+                if (actualContentType.equals(WebContent.contentTypeXML))
+                    lang = ResultSetLang.SPARQLResultSetXML;
+                else if ( actualContentType.equals(WebContent.contentTypeJSON))
+                    lang = ResultSetLang.SPARQLResultSetJSON;
+            }
+            if ( lang == null )
+                throw new QueryException("Endpoint returned Content-Type: " + actualContentType + " which is not supported for ASK queries");
+            Boolean result = ResultSetMgr.readBoolean(in, lang);
+            return result;
+        } catch (ResultSetException e) {
+            log.warn("Returned content is not a boolean result", e);
+            throw e;
         } catch (QueryExceptionHTTP e) { 
             throw e ;
         }

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_BNode.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_BNode.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_BNode.java
index 162a812..2430308 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_BNode.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_BNode.java
@@ -76,7 +76,9 @@ public class E_BNode extends ExprFunctionN // 0 or one
         LabelToNodeMap mapper = mapping.get(binding) ;
         if ( mapper == null )
         {
-            mapper = LabelToNodeMap.createBNodeMap() ;
+            @SuppressWarnings("deprecation")
+            LabelToNodeMap mapper_ = LabelToNodeMap.createBNodeMap() ; 
+            mapper = mapper_;
             mapping.put(binding, mapper) ;
         }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/lang/ParserBase.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/lang/ParserBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/lang/ParserBase.java
index 3a4eedd..61f206b 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/lang/ParserBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/lang/ParserBase.java
@@ -80,6 +80,7 @@ public class ParserBase
     private boolean bNodesAreAllowed = true ;
     
     // label => bNode for construct templates patterns
+    @SuppressWarnings("deprecation")
     final LabelToNodeMap bNodeLabels = LabelToNodeMap.createBNodeMap() ;
     
     // label => bNode (as variable) for graph patterns

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessRemoteBase.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessRemoteBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessRemoteBase.java
index 8e18cd1..e03b087 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessRemoteBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessRemoteBase.java
@@ -75,7 +75,7 @@ public abstract class UpdateProcessRemoteBase implements UpdateProcessor {
 
         this.request = request;
         this.endpoint = endpoint;
-        this.context = Context.setupContext(context, null);
+        this.context = Context.setupContextExec(context, null);
 
         // Apply service configuration if applicable
         UpdateProcessRemoteBase.applyServiceConfig(endpoint, this);

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorBase.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorBase.java
index fd00fca..4a83c9d 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorBase.java
@@ -45,7 +45,7 @@ public class UpdateProcessorBase implements UpdateProcessor
         this.request = request ;
         this.datasetGraph = datasetGraph ;
         this.inputBinding = inputBinding;
-        this.context = Context.setupContext(context, datasetGraph) ;
+        this.context = Context.setupContextExec(context, datasetGraph) ;
         this.factory = factory ;
     }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorStreamingBase.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorStreamingBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorStreamingBase.java
index 48569e0..505c4a0 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorStreamingBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateProcessorStreamingBase.java
@@ -36,7 +36,7 @@ public class UpdateProcessorStreamingBase implements UpdateProcessorStreaming
     public UpdateProcessorStreamingBase(DatasetGraph datasetGraph, Binding inputBinding, Context context, UpdateEngineFactory factory)
     {
         this.datasetGraph = datasetGraph ;
-        this.context = Context.setupContext(context, datasetGraph) ;
+        this.context = Context.setupContextExec(context, datasetGraph) ;
         proc = factory.create(datasetGraph, inputBinding, context) ;
     }
     

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/resultset/JSONInput.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/JSONInput.java b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/JSONInput.java
index d2a3ee5..264ac6c 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/JSONInput.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/JSONInput.java
@@ -26,7 +26,7 @@ import org.apache.jena.riot.resultset.ResultSetLang;
 import org.apache.jena.riot.resultset.rw.ResultsReader;
 
 /**
- * @deprecated Use ResultSetMgr.read 
+ * @deprecated Use {@code ResultSetMgr.read} 
  */
 @Deprecated
 public class JSONInput extends SPARQLResult {

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/resultset/JSONOutput.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/JSONOutput.java b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/JSONOutput.java
index 9898d54..c33d70e 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/JSONOutput.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/JSONOutput.java
@@ -25,7 +25,7 @@ import org.apache.jena.riot.resultset.ResultSetLang;
 import org.apache.jena.riot.resultset.rw.ResultsWriter;
 
 /**
- * @deprecated Use ResultSetMgr.write(,,ResultSetLang.SPARQLResultSetJSON) 
+ * @deprecated Use {@code ResultSetMgr.write(??,??,ResultSetLang.SPARQLResultSetJSON)} 
  */
 @Deprecated
 public class JSONOutput extends OutputBase {

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLInput.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLInput.java b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLInput.java
index 469a466..43d50a3 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLInput.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLInput.java
@@ -29,6 +29,8 @@ import org.apache.jena.sparql.SystemARQ;
 
 /**
  * Code that reads an XML Result Set and builds the ARQ structure for the same.
+ * 
+ * @deprecated Use {@code ResultSetMgr.read}
  */
 @Deprecated
 public class XMLInput {

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLInputSAX.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLInputSAX.java b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLInputSAX.java
index e9952bf..01026ff 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLInputSAX.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLInputSAX.java
@@ -46,7 +46,7 @@ import org.xml.sax.* ;
 import org.xml.sax.helpers.XMLReaderFactory ;
 
 /** Code that reads an XML Result Set and builds the ARQ structure for the same. */
-
+// UNUSED
 class XMLInputSAX extends SPARQLResult {
     // See also XMLInputStAX, which is preferred.
     // SAX is not a streaming API - the SAX handler is called as fast as the

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLOutput.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLOutput.java b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLOutput.java
index 48e85f1..5370cd3 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLOutput.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/resultset/XMLOutput.java
@@ -29,8 +29,25 @@ import org.apache.jena.sparql.util.Context;
 
 public class XMLOutput extends OutputBase
 {
-    String stylesheetURL = null ;
-    boolean includeXMLinst = true ;
+    /** Set the XML style sheet processing instruction {@code <?xml-stylesheet...>}.
+     *  Set to null to not use a stylesheet. */ 
+    public static void setStylesheetURL(Context cxt, String stylesheetURL) {
+        cxt.set(ResultSetWriterXML.xmlStylesheet, stylesheetURL);
+    }
+
+    /** Set whether to include {@code <?xml ...>}.
+     *  Set to null for "default" behaviour. */
+    public static void setXMLinstruction(Context cxt, Boolean value) {
+        if ( value != null )
+            cxt.set(ResultSetWriterXML.xmlInstruction, value.booleanValue());
+        else
+            cxt.unset(ResultSetWriterXML.xmlInstruction);
+    }
+
+    // -- Older
+    
+    protected String stylesheetURL = null ;
+    protected boolean includeXMLinst = true ;
     
     public XMLOutput() {}
 
@@ -46,13 +63,10 @@ public class XMLOutput extends OutputBase
         setStylesheetURL(stylesheetURL);
         setIncludeXMLinst(includeXMLinst);
     }
-
+    
     @Override
     public void format(OutputStream out, ResultSet resultSet) {
-        Context cxt = ARQ.getContext().copy();
-        if ( stylesheetURL != null )
-            cxt.set(ResultSetWriterXML.xmlStylesheet, stylesheetURL);
-        cxt.set(ResultSetWriterXML.xmlInstruction, includeXMLinst);
+        Context cxt = setup();
         ResultsWriter.create()
             .context(cxt)
             .lang(ResultSetLang.SPARQLResultSetXML)
@@ -77,14 +91,18 @@ public class XMLOutput extends OutputBase
     
     @Override
     public void format(OutputStream out, boolean booleanResult) {
-        Context cxt = ARQ.getContext().copy();
-        if ( stylesheetURL != null )
-            cxt.set(ResultSetWriterXML.xmlStylesheet, stylesheetURL);
-        cxt.set(ResultSetWriterXML.xmlInstruction, includeXMLinst);
+        Context cxt = setup();
         ResultsWriter.create()
             .context(cxt)
             .lang(ResultSetLang.SPARQLResultSetXML)
             .build()
             .write(out, booleanResult);
     }
+    
+    private Context setup() {
+        Context cxt = ARQ.getContext().copy();
+        setStylesheetURL(cxt, stylesheetURL);
+        setXMLinstruction(cxt, includeXMLinst);
+        return cxt;
+    }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/sse/lang/ParseHandlerPlain.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/sse/lang/ParseHandlerPlain.java b/jena-arq/src/main/java/org/apache/jena/sparql/sse/lang/ParseHandlerPlain.java
index 4badbfa..6a9be97 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/sse/lang/ParseHandlerPlain.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/sse/lang/ParseHandlerPlain.java
@@ -26,6 +26,7 @@ import org.apache.jena.datatypes.RDFDatatype ;
 import org.apache.jena.datatypes.TypeMapper ;
 import org.apache.jena.graph.Node ;
 import org.apache.jena.graph.NodeFactory ;
+import org.apache.jena.riot.lang.LabelToNode;
 import org.apache.jena.sparql.ARQConstants ;
 import org.apache.jena.sparql.core.Var ;
 import org.apache.jena.sparql.core.VarAlloc ;
@@ -33,14 +34,13 @@ import org.apache.jena.sparql.sse.Item ;
 import org.apache.jena.sparql.sse.ItemList ;
 import org.apache.jena.sparql.sse.ItemLocation ;
 import org.apache.jena.sparql.sse.SSEParseException ;
-import org.apache.jena.sparql.util.LabelToNodeMap ;
 
 public class ParseHandlerPlain implements ParseHandler 
 {
     private ListStack      listStack   = new ListStack() ;
     private Item           currentItem = null ;
     private int            depth       = 0 ;
-    private LabelToNodeMap bNodeLabels = LabelToNodeMap.createBNodeMap() ;
+    private LabelToNode    bNodeLabels = LabelToNode.createScopeGlobal();
     
     // Allocation of fresh variables.
     private VarAlloc       varAlloc        = new VarAlloc(ARQConstants.allocSSEUnamedVars) ;
@@ -163,7 +163,7 @@ public class ParseHandlerPlain implements ParseHandler
             // Fresh anonymous bNode
             n = NodeFactory.createBlankNode() ; 
         else
-            n = bNodeLabels.asNode(label) ;
+            n = bNodeLabels.get(null, label) ;
         Item item = Item.createNode(n, line, column) ;
         listAdd(item) ;
     }

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/util/Context.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/Context.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/Context.java
index 97f47b1..783a6db 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/Context.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/Context.java
@@ -344,27 +344,40 @@ public class Context {
         return x ;
     }
 
-    // Put any per-dataset execution global configuration state here.
-    public static Context setupContext(Context context, DatasetGraph dataset) {
-        if ( context == null )
-            context = ARQ.getContext() ; // Already copied?
-        context = context.copy() ;
-
-        if ( dataset != null && dataset.getContext() != null )
-            // Copy per-dataset settings.
-            context.putAll(dataset.getContext()) ;
+    /** Setup a context using anouter context and a dataset.
+     *  This adds the current time.
+     */
+    public static Context setupContextExec(Context globalContext, DatasetGraph dataset) {
+        if ( globalContext == null )
+            globalContext = ARQ.getContext();
+        // Copy per-dataset settings.
+        Context dsgCxt = ( dataset != null && dataset.getContext() != null ) 
+            ? dataset.getContext()
+            : null;
+        
+        Context context = mergeCopy(globalContext, dsgCxt); 
 
         context.set(ARQConstants.sysCurrentTime, NodeFactoryExtra.nowAsDateTime()) ;
 
         // Allocators.
-        // context.set(ARQConstants.sysVarAllocNamed, new
-        // VarAlloc(ARQConstants.allocVarMarkerExec)) ;
-        // context.set(ARQConstants.sysVarAllocAnon, new
-        // VarAlloc(ARQConstants.allocVarAnonMarkerExec)) ;
+        // context.set(ARQConstants.sysVarAllocNamed, new VarAlloc(ARQConstants.allocVarMarkerExec)) ;
+        // context.set(ARQConstants.sysVarAllocAnon, new VarAlloc(ARQConstants.allocVarAnonMarkerExec)) ;
         // Add VarAlloc for variables and bNodes (this is not the parse name).
-        // More added later e.g. query (if there is a query), algebra form (in
-        // setOp)
+        // More added later e.g. query (if there is a query), algebra form (in setOp)
 
+        return context;
+    }
+
+    /** Merge an outer (fglobal) and local context to produce a new context
+     * The new context is always a separate copy.  
+     */
+    public static Context mergeCopy(Context contextGlobal, Context contextLocal) {
+        if ( contextGlobal == null )
+            contextGlobal = ARQ.getContext();
+        Context context = contextGlobal.copy();
+        if ( contextLocal != null )
+            // Copy per-dataset settings.
+            context.putAll(contextLocal);
         return context ;
     }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/main/java/org/apache/jena/sparql/util/LabelToNodeMap.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/LabelToNodeMap.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/LabelToNodeMap.java
index 9a3ddde..9fc0714 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/LabelToNodeMap.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/LabelToNodeMap.java
@@ -31,7 +31,6 @@ import org.apache.jena.sparql.core.VarAlloc ;
 /** Map from _:* form to bNodes or variables. */
 public class LabelToNodeMap
 {
-    // Wil be replaced by LabelToNode in RIOT
     Map<String, Node> bNodeLabels = new HashMap<>() ;
     
     // Variables or bNodes?

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/test/java/org/apache/jena/riot/lang/TestBlankNodeAllocator.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/lang/TestBlankNodeAllocator.java b/jena-arq/src/test/java/org/apache/jena/riot/lang/TestBlankNodeAllocator.java
index 5b409af..7ba6ad4 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/lang/TestBlankNodeAllocator.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/lang/TestBlankNodeAllocator.java
@@ -42,7 +42,7 @@ public class TestBlankNodeAllocator extends BaseTest
         } ;
 
         Factory fUIDAlloc = new Factory() {
-            @Override public BlankNodeAllocator create() { return new BlankNodeAllocatorTraditional() ; }
+            @Override public BlankNodeAllocator create() { return new BlankNodeAllocatorGlobal() ; }
             @Override public String toString() { return "UID" ; }
         } ;
 

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLabelToNode.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLabelToNode.java b/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLabelToNode.java
index 9b64d55..5299268 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLabelToNode.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLabelToNode.java
@@ -51,7 +51,7 @@ public class TestLabelToNode extends BaseTest
         } ;
 
         LabelToNodeFactory fScopeByDocumentOld = new LabelToNodeFactory() {
-                @Override public LabelToNode create() { return LabelToNode.createScopeByDocumentOld() ; }
+                @Override public LabelToNode create() { return LabelToNode.createScopeGlobal() ; }
                 @Override public String toString() { return "ScopeByDocumentOld" ; }
         } ;
         LabelToNodeFactory fScopeByGraph = new LabelToNodeFactory() {

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-fuseki2/examples/service-tdb1-B.ttl
----------------------------------------------------------------------
diff --git a/jena-fuseki2/examples/service-tdb1-B.ttl b/jena-fuseki2/examples/service-tdb1-B.ttl
index 09a2151..c85963f 100644
--- a/jena-fuseki2/examples/service-tdb1-B.ttl
+++ b/jena-fuseki2/examples/service-tdb1-B.ttl
@@ -29,4 +29,5 @@
 ##     # Query timeout on this dataset (milliseconds)
 ##     ja:context [ ja:cxtName "arq:queryTimeout" ;  ja:cxtValue "1000" ] ;
 ##     # Default graph for query is the (read-only) union of all named graphs.
+       tdb:unionDefaultGraph true ;
      .

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/DEF.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/DEF.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/DEF.java
index cd7962a..71eaf08 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/DEF.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/DEF.java
@@ -77,19 +77,25 @@ public class DEF
                                                                           ) ;
     
     // Offer for SELECT
+    // This include application/xml and application/json.
     public static final AcceptList rsOfferTable       = AcceptList.create(contentTypeResultsJSON,
+                                                                          contentTypeJSON,
                                                                           contentTypeTextCSV,
                                                                           contentTypeTextTSV,
                                                                           contentTypeResultsXML,
+                                                                          contentTypeXML,
                                                                           contentTypeResultsThrift,
                                                                           contentTypeTextPlain
                                                                           ) ;
          
     // Offer for ASK
+    // This include application/xml and application/json.
     public static final AcceptList rsOfferBoolean      = AcceptList.create(contentTypeResultsJSON,
+                                                                           contentTypeJSON,
                                                                            contentTypeTextCSV,
                                                                            contentTypeTextTSV,
                                                                            contentTypeResultsXML,
+                                                                           contentTypeXML,
                                                                            contentTypeTextPlain
                                                                            ) ;
 

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java
index 3a61e90..367c12b 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java
@@ -29,10 +29,8 @@ import javax.servlet.http.HttpServletResponse ;
 
 import org.apache.jena.atlas.RuntimeIOException ;
 import org.apache.jena.atlas.web.HttpException;
-import org.apache.jena.query.ARQ ;
 import org.apache.jena.query.QueryCancelledException ;
 import org.apache.jena.riot.web.HttpNames ;
-import org.apache.jena.sparql.util.Context ;
 import org.apache.jena.web.HttpSC ;
 import org.slf4j.Logger ;
 
@@ -50,8 +48,6 @@ public abstract class ActionBase extends ServletBase
     public void init() {
 //        log.info("["+Utils.className(this)+"] ServletContextName = "+getServletContext().getServletContextName()) ;
 //        log.info("["+Utils.className(this)+"] ContextPath        = "+getServletContext().getContextPath()) ;
-
-        //super.init() ;
     }
     
     /**
@@ -73,8 +69,6 @@ public abstract class ActionBase extends ServletBase
             // The response may be changed to a HttpServletResponseTracker
             response = action.response ;
             initResponse(request, response) ;
-            Context cxt = ARQ.getContext() ;
-            
             try {
                 execCommonWorker(action) ;
             } catch (QueryCancelledException ex) {

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java
index f3f658b..4052f2d 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java
@@ -37,6 +37,7 @@ import org.apache.jena.sparql.core.DatasetGraph ;
 import org.apache.jena.sparql.core.DatasetGraphWrapper ;
 import org.apache.jena.sparql.core.Transactional ;
 import org.apache.jena.sparql.core.TransactionalLock ;
+import org.apache.jena.sparql.util.Context;
 import org.slf4j.Logger ;
 
 /**
@@ -70,6 +71,7 @@ public class HttpAction
     private DataService dataService         = null ;
     private String datasetName              = null ;        // Dataset URI used (e.g. registry)
     private DatasetGraph dsg                = null ;
+    private Context context                 = null ;
 
     // ----
     
@@ -165,6 +167,7 @@ public class HttpAction
      */
     private void setDataset(DatasetGraph dsg) {
         this.dsg = dsg ;
+        this.context = Context.mergeCopy(Fuseki.getContext(), dsg.getContext());
         if ( dsg == null )
             return ;
         setTransactionalPolicy(dsg) ;
@@ -191,6 +194,11 @@ public class HttpAction
         return dsg ;
     }
 
+    /** Return the Context for this {@code HttpAction}. */
+    public Context getContext() {
+        return context ;
+    }
+
     /**
      * Return the "Transactional" for this HttpAction.
      */

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseDataset.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseDataset.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseDataset.java
index 0e6543b..99ed62c 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseDataset.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseDataset.java
@@ -117,7 +117,7 @@ public class ResponseDataset
             ServletOps.errorBadRequest("Can't determine output content type: "+contentType) ;
 
         try {
-            ResponseResultSet.setHttpResponse(action, contentType, charset) ;
+            ResponseOps.setHttpResponse(action, contentType, charset) ;
             response.setStatus(HttpSC.OK_200) ;
             ServletOutputStream out = response.getOutputStream() ;
             try {

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java
index 8a3a1c9..a7e825d 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java
@@ -24,6 +24,7 @@ import java.util.Map ;
 
 import javax.servlet.http.HttpServletRequest ;
 
+import org.apache.jena.riot.WebContent;
 import org.apache.jena.riot.web.HttpNames ;
 
 public class ResponseOps
@@ -90,5 +91,25 @@ public class ResponseOps
         return value ;
     }
 
+    /** Basic settings, including Content-Type, for a response. */
+    public static void setHttpResponse(HttpAction action, String contentType, String charset) {
+        // ---- Set up HTTP Response
+        // Stop caching (not that ?queryString URLs are cached anyway)
+        if ( true )
+            ServletOps.setNoCache(action);
+        // See: http://www.w3.org/International/O-HTTP-charset.html
+        if ( contentType != null ) {
+            if ( charset != null && !isXML(contentType) )
+                contentType = contentType + "; charset=" + charset;
+            action.log.trace("Content-Type for response: " + contentType);
+            action.response.setContentType(contentType);
+        }
+    }
+    
+    public static boolean isXML(String contentType) {
+        return contentType.equals(WebContent.contentTypeRDFXML)
+            || contentType.equals(WebContent.contentTypeResultsXML)
+            || contentType.equals(WebContent.contentTypeXML) ;
+    }
 }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/1e1da957/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java
index f672019..cb9298f 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java
@@ -19,15 +19,7 @@
 package org.apache.jena.fuseki.servlets;
 
 import static java.lang.String.format ;
-import static org.apache.jena.riot.WebContent.charsetUTF8 ;
-import static org.apache.jena.riot.WebContent.contentTypeRDFXML ;
-import static org.apache.jena.riot.WebContent.contentTypeResultsJSON ;
-import static org.apache.jena.riot.WebContent.contentTypeResultsThrift ;
-import static org.apache.jena.riot.WebContent.contentTypeResultsXML ;
-import static org.apache.jena.riot.WebContent.contentTypeTextCSV ;
-import static org.apache.jena.riot.WebContent.contentTypeTextPlain ;
-import static org.apache.jena.riot.WebContent.contentTypeTextTSV ;
-import static org.apache.jena.riot.WebContent.contentTypeXML ;
+import static org.apache.jena.riot.WebContent.*;
 
 import java.io.IOException ;
 import java.util.HashMap ;
@@ -38,7 +30,6 @@ import javax.servlet.ServletOutputStream ;
 import javax.servlet.http.HttpServletRequest ;
 import javax.servlet.http.HttpServletResponse ;
 
-import org.apache.jena.atlas.io.IO ;
 import org.apache.jena.atlas.web.AcceptList ;
 import org.apache.jena.atlas.web.MediaType ;
 import org.apache.jena.fuseki.DEF ;
@@ -47,10 +38,14 @@ import org.apache.jena.fuseki.conneg.ConNeg ;
 import org.apache.jena.query.QueryCancelledException ;
 import org.apache.jena.query.ResultSet ;
 import org.apache.jena.query.ResultSetFormatter ;
-import org.apache.jena.riot.ResultSetMgr ;
+import org.apache.jena.riot.Lang;
 import org.apache.jena.riot.WebContent ;
 import org.apache.jena.riot.resultset.ResultSetLang ;
+import org.apache.jena.riot.resultset.ResultSetWriterRegistry;
+import org.apache.jena.riot.resultset.rw.ResultsWriter;
 import org.apache.jena.sparql.core.Prologue ;
+import org.apache.jena.sparql.resultset.XMLOutput;
+import org.apache.jena.sparql.util.Context;
 import org.apache.jena.web.HttpSC ;
 import org.slf4j.Logger ;
 import org.slf4j.LoggerFactory ;
@@ -81,7 +76,7 @@ public class ResponseResultSet
         ResponseOps.put(shortNamesResultSet, contentOutputThrift, contentTypeResultsThrift) ;
     }
 
-    interface OutputContent { void output(ServletOutputStream out) ; }
+    interface OutputContent { void output(ServletOutputStream out) throws IOException; }
 
     public static void doResponseResultSet(HttpAction action, Boolean booleanResult) {
         doResponseResultSet$(action, null, booleanResult, null, DEF.rsOfferBoolean) ;
@@ -91,8 +86,6 @@ public class ResponseResultSet
         doResponseResultSet$(action, resultSet, null, qPrologue, DEF.rsOfferTable) ;
     }
 
-    // If we refactor the conneg into a single function, we can split boolean and result set handling.
-
     // One or the other argument must be null
     private static void doResponseResultSet$(HttpAction action, 
                                              ResultSet resultSet, Boolean booleanResult,
@@ -112,11 +105,12 @@ public class ResponseResultSet
         }
 
         String mimeType = null ;
+        // -- Conneg
         MediaType i = ConNeg.chooseContentType(request, contentTypeOffer, DEF.acceptRSXML) ;
         if ( i != null )
             mimeType = i.getContentType() ;
 
-        // Override content type
+        // -- Override content type from conneg.
         // Does &output= override?
         // Requested output type by the web form or &output= in the request.
         String outputField = ResponseOps.paramOutput(request, shortNamesResultSet) ;    // Expands short names
@@ -126,7 +120,7 @@ public class ResponseResultSet
         String serializationType = mimeType ;           // Choose the serializer based on this.
         String contentType = mimeType ;                 // Set the HTTP respose header to this.
 
-        // Stylesheet - change to application/xml.
+        // -- Stylesheet - change to application/xml.
         final String stylesheetURL = ResponseOps.paramStylesheet(request) ;
         if ( stylesheetURL != null && Objects.equals(serializationType,contentTypeResultsXML) )
             contentType = contentTypeXML ;
@@ -136,78 +130,51 @@ public class ResponseResultSet
         if ( forceAccept != null )
             contentType = contentTypeTextPlain ;
 
-        // Better : dispatch on MediaType
-        if ( Objects.equals(serializationType, contentTypeResultsXML) )
-            sparqlXMLOutput(action, contentType, resultSet, stylesheetURL, booleanResult) ;
-        else if ( Objects.equals(serializationType, contentTypeResultsJSON) )
-            jsonOutput(action, contentType, resultSet, booleanResult) ;
-        else if ( Objects.equals(serializationType, contentTypeTextPlain) )
+        // Some kind of general dispatch is neater but there are quite a few special cases.
+        //
+        // JSON is special because of ?callback
+        // 
+        // XML is special because of
+        // (1) charset is a feature of XML, not the response 
+        // (2) ?stylesheet=
+        //
+        // Thrift is special because
+        // (1) charset is meaningless
+        // (2) there is no boolean result form.
+        //
+        // Text plain is special because of the formatting by prologue.
+        
+        Lang lang = WebContent.contentTypeToLangResultSet(serializationType);
+        if (lang == null )
+            ServletOps.errorBadRequest("Not recognized for SPARQL results: "+serializationType) ;
+        if ( ! ResultSetWriterRegistry.isRegistered(lang) )
+            ServletOps.errorBadRequest("No results writer for "+serializationType);
+        if ( ResultSetLang.SPARQLResultSetThrift.equals(lang) && booleanResult != null )
+            ServletOps.errorBadRequest("Can't write a boolean result in thrift") ;
+
+        Context cxt = action.getContext().copy();
+        String charset = charsetUTF8;
+        String jsonCallback = null;
+        
+        if ( Objects.equals(serializationType, contentTypeResultsXML) ) {
+            charset = null;
+            XMLOutput.setStylesheetURL(cxt, stylesheetURL);
+        }
+        if ( Objects.equals(serializationType, contentTypeResultsJSON) ) {
+            jsonCallback = ResponseOps.paramCallback(action.request) ;
+        }
+        if (Objects.equals(serializationType, WebContent.contentTypeResultsThrift) ) {
+            charset = null;
+        }
+        
+        if ( Objects.equals(serializationType, contentTypeTextPlain) ) {
+            // While text form does not use context for a Prologue.
             textOutput(action, contentType, resultSet, qPrologue, booleanResult) ;
-        else if ( Objects.equals(serializationType, contentTypeTextCSV) )
-            csvOutput(action, contentType, resultSet, booleanResult) ;
-        else if (Objects.equals(serializationType, contentTypeTextTSV) )
-            tsvOutput(action, contentType, resultSet, booleanResult) ;
-        else if (Objects.equals(serializationType, WebContent.contentTypeResultsThrift) )
-            thriftOutput(action, contentType, resultSet, booleanResult) ;
-        else
-            ServletOps.errorBadRequest("Can't determine output serialization: "+serializationType) ;
-    }
-
-
-    public static void setHttpResponse(HttpAction action, String contentType, String charset) {
-        // ---- Set up HTTP Response
-        // Stop caching (not that ?queryString URLs are cached anyway)
-        if ( true )
-            ServletOps.setNoCache(action) ;
-        // See: http://www.w3.org/International/O-HTTP-charset.html
-        if ( contentType != null )        {
-            if ( charset != null && ! isXML(contentType) )
-                contentType = contentType+"; charset="+charset ;
-            action.log.trace("Content-Type for response: "+contentType) ;
-            action.response.setContentType(contentType) ;
+            return;
         }
-    }
-
-    private static boolean isXML(String contentType) {
-        return contentType.equals(contentTypeRDFXML)
-            || contentType.equals(contentTypeResultsXML)
-            || contentType.equals(contentTypeXML) ;
-    }
-
-    private static void sparqlXMLOutput(HttpAction action, String contentType, ResultSet resultSet, String stylesheetURL, Boolean booleanResult) {
-        OutputContent proc = (ServletOutputStream out) -> {
-            if ( resultSet != null )
-                ResultSetFormatter.outputAsXML(out, resultSet, stylesheetURL) ;
-            if ( booleanResult != null )
-                ResultSetFormatter.outputAsXML(out, booleanResult.booleanValue(), stylesheetURL) ;
-        } ;
-        output(action, contentType, null, proc) ;
-    }
-
-    private static void jsonOutput(HttpAction action, String contentType, ResultSet resultSet, Boolean booleanResult) {
-        OutputContent proc = (ServletOutputStream out) -> {
-            if ( resultSet != null )
-                ResultSetFormatter.outputAsJSON(out, resultSet) ;
-            if ( booleanResult != null )
-                ResultSetFormatter.outputAsJSON(out, booleanResult.booleanValue()) ;
-        } ;
-
-        try {
-            String callback = ResponseOps.paramCallback(action.request) ;
-            ServletOutputStream out = action.response.getOutputStream() ;
-
-            if ( callback != null ) {
-                callback = callback.replace("\r", "") ;
-                callback = callback.replace("\n", "") ;
-                out.print(callback) ;
-                out.println("(") ;
-            }
-
-            output(action, contentType, charsetUTF8, proc) ;
-
-            if ( callback != null )
-                out.println(")") ;
-        } catch (IOException ex) { IO.exception(ex) ; }
+        
+        //Finally, the general case
+        generalOutput(action, lang, contentType, charset, cxt, jsonCallback, resultSet, booleanResult) ;
     }
 
     private static void textOutput(HttpAction action, String contentType, ResultSet resultSet, Prologue qPrologue, Boolean booleanResult) {
@@ -222,39 +189,37 @@ public class ResponseResultSet
         output(action, contentType, charsetUTF8, proc) ;
     }
 
-    private static void csvOutput(HttpAction action, String contentType, ResultSet resultSet, Boolean booleanResult) {
-        OutputContent proc = (ServletOutputStream out) -> {
-            if ( resultSet != null )
-                ResultSetFormatter.outputAsCSV(out, resultSet) ;
-            if (  booleanResult != null )
-                ResultSetFormatter.outputAsCSV(out, booleanResult.booleanValue()) ;
-        } ;
-        output(action, contentType, charsetUTF8, proc) ;
-    }
-
-    private static void tsvOutput(HttpAction action, String contentType, ResultSet resultSet, Boolean booleanResult) {
+    /** Any format */
+    private static void generalOutput(HttpAction action, Lang rsLang, 
+                                      String contentType, String charset,
+                                      Context context, String callback,
+                                      ResultSet resultSet, Boolean booleanResult) {
+        ResultsWriter rw = ResultsWriter.create()
+            .lang(rsLang)
+            .context(context)
+            .build();
         OutputContent proc = (ServletOutputStream out) -> {
+            if ( callback != null ) {
+                String callbackFunction = callback;
+                callbackFunction = callbackFunction.replace("\r", "") ;
+                callbackFunction = callbackFunction.replace("\n", "") ;
+                out.print(callbackFunction) ;
+                out.println("(") ;
+            }
             if ( resultSet != null )
-                ResultSetFormatter.outputAsTSV(out, resultSet) ;
+                rw.write(out, resultSet) ;
             if (  booleanResult != null )
-                ResultSetFormatter.outputAsTSV(out, booleanResult.booleanValue()) ;
-        } ;
-        output(action, contentType, charsetUTF8, proc) ;
-    }
-
-    private static void thriftOutput(HttpAction action, String contentType, ResultSet resultSet, Boolean booleanResult) {
-        OutputContent proc = (ServletOutputStream out) -> {
-            if ( resultSet != null )
-                ResultSetMgr.write(out, resultSet, ResultSetLang.SPARQLResultSetThrift) ;
-            if ( booleanResult != null )
-                xlog.error("Can't write boolen result in thrift") ;
+                rw.write(out, booleanResult.booleanValue()) ;
+            if ( callback != null )
+                out.println(")") ;
         } ;
-        output(action, contentType, WebContent.charsetUTF8, proc) ;
+        output(action, contentType, charset, proc) ;
     }
 
+    // Sett HTTP response Execute OutputContent inside 
     private static void output(HttpAction action, String contentType, String charset, OutputContent proc) {
         try {
-            setHttpResponse(action, contentType, charset) ;
+            ResponseOps.setHttpResponse(action, contentType, charset) ;
             action.response.setStatus(HttpSC.OK_200) ;
             ServletOutputStream out = action.response.getOutputStream() ;
             try {


Mime
View raw message