Add construct quad support to Fuseki

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

Branch: refs/heads/master
Commit: 0eb28d805e3270c9951f13cdbd55af3e8d01d0ab
Parents: e819ac3
Author: confidencesun <[email protected]>
Authored: Tue Aug 11 12:05:55 2015 +0800
Committer: confidencesun <[email protected]>
Committed: Tue Aug 11 12:05:55 2015 +0800

----------------------------------------------------------------------
 .../sparql/engine/http/QueryEngineHTTP.java     |  30 +-
 .../main/java/org/apache/jena/fuseki/DEF.java   |   7 +
 .../jena/fuseki/servlets/ResponseDataset.java   | 134 +++
 .../jena/fuseki/servlets/SPARQL_Query.java      | 838 ++++++++++---------
 .../java/org/apache/jena/fuseki/TestQuery.java  | 188 ++---
 5 files changed, 719 insertions(+), 478 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/0eb28d80/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 a35fffc..cab831f 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
@@ -394,7 +394,7 @@ public class QueryEngineHTTP implements QueryExecution {
     
     @Override
     public Iterator<Quad> execConstructQuads(){
-       return null;
+       return execQuads();
     }
     
     @Override
@@ -469,6 +469,32 @@ public class QueryEngineHTTP implements QueryExecution {
 
         return RiotReader.createIteratorTriples(in, lang, null);
     }
+    
+    private Iterator<Quad> execQuads() {
+        checkNotClosed() ;
+        HttpQuery httpQuery = makeHttpQuery();
+        httpQuery.setAccept(WebContent.defaultDatasetAcceptHeader);
+        InputStream in = httpQuery.exec();
+        
+        // Don't assume the endpoint actually gives back the content type we
+        // asked for
+        String actualContentType = httpQuery.getContentType();
+
+        // If the server fails to return a Content-Type then we will assume
+        // the server returned the type we asked for
+        if (actualContentType == null || actualContentType.equals("")) {
+            actualContentType = WebContent.defaultDatasetAcceptHeader;
+        }
+
+        // Try to select language appropriately here based on the model content
+        // type
+        Lang lang = RDFLanguages.contentTypeToLang(actualContentType);
+        if (!RDFLanguages.isQuads(lang))
+            throw new QueryException("Endpoint returned Content Type: " + 
actualContentType
+                    + " which is not a valid RDF Dataset syntax");
+
+        return RiotReader.createIteratorQuads(in, lang, null);
+    }
 
     @Override
     public boolean execAsk() {
@@ -817,4 +843,4 @@ public class QueryEngineHTTP implements QueryExecution {
         if ( v < 1 )
             sBuff.append(";q=").append(v) ;
     } 
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/0eb28d80/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 b419cc6..953b724 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
@@ -31,6 +31,13 @@ public class DEF
     
     public static final AcceptList jsonOffer          = 
AcceptList.create(contentTypeJSON) ;
 
+    public static final AcceptList pureRdfOffer       = 
AcceptList.create(contentTypeTurtle, 
+                                                                          
contentTypeTurtleAlt1,
+                                                                          
contentTypeTurtleAlt2,
+                                                                          
contentTypeNTriples,
+                                                                          
contentTypeRDFXML
+                                                                          ) ;
+    
     public static final AcceptList rdfOffer           = 
AcceptList.create(contentTypeTurtle, 
                                                                           
contentTypeTurtleAlt1,
                                                                           
contentTypeTurtleAlt2,

http://git-wip-us.apache.org/repos/asf/jena/blob/0eb28d80/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
new file mode 100644
index 0000000..91d615d
--- /dev/null
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ResponseDataset.java
@@ -0,0 +1,134 @@
+/*
+ * 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.fuseki.servlets;
+
+import static org.apache.jena.riot.WebContent.charsetUTF8;
+import static org.apache.jena.riot.WebContent.contentTypeJSONLD;
+import static org.apache.jena.riot.WebContent.contentTypeNTriples;
+import static org.apache.jena.riot.WebContent.contentTypeRDFJSON;
+import static org.apache.jena.riot.WebContent.contentTypeRDFXML;
+import static org.apache.jena.riot.WebContent.contentTypeTurtle;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.jena.atlas.web.MediaType;
+import org.apache.jena.fuseki.DEF;
+import org.apache.jena.fuseki.Fuseki;
+import org.apache.jena.fuseki.conneg.ConNeg;
+import org.apache.jena.fuseki.conneg.WebLib;
+import org.apache.jena.query.Dataset;
+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.web.HttpSC;
+
+public class ResponseDataset
+{
+    // Short names for "output="
+    private static final String contentOutputTriG          = "trig" ;
+    private static final String contentOutputNQuads        = "n-quads" ;
+
+
+    public static Map<String,String> shortNamesModel = new HashMap<String, 
String>() ;
+    static {
+
+        // Some short names.  keys are lowercase.
+        
+        ResponseOps.put(shortNamesModel, contentOutputNQuads,  
WebContent.contentTypeNQuads) ;
+        ResponseOps.put(shortNamesModel, contentOutputTriG,     
WebContent.contentTypeTriG) ;
+    }
+
+    public static void doResponseDataset(HttpAction action, Dataset dataset) 
+    {
+        HttpServletRequest request = action.request ;
+        HttpServletResponse response = action.response ;
+        
+        String mimeType = null ;        // Header request type 
+
+        // TODO Use MediaType throughout.
+        MediaType i = ConNeg.chooseContentType(request, DEF.quadsOffer, 
DEF.acceptNQuads) ;
+        if ( i != null )
+            mimeType = i.getContentType() ;
+
+        String outputField = ResponseOps.paramOutput(request, shortNamesModel) 
;
+        if ( outputField != null )
+            mimeType = outputField ;
+
+        String writerMimeType = mimeType ;
+
+        if ( mimeType == null )
+        {
+            Fuseki.actionLog.warn("Can't find MIME type for response") ;
+            String x = WebLib.getAccept(request) ;
+            String msg ;
+            if ( x == null )
+                msg = "No Accept: header" ;
+            else
+                msg = "Accept: "+x+" : Not understood" ;
+            ServletOps.error(HttpSC.NOT_ACCEPTABLE_406, msg) ;
+        }
+
+        String contentType = mimeType ;
+        String charset =     charsetUTF8 ;
+
+        String forceAccept = ResponseOps.paramForceAccept(request) ;
+        if ( forceAccept != null )
+        {
+            contentType = forceAccept ;
+            charset = charsetUTF8 ;
+        }
+
+        Lang lang = RDFLanguages.contentTypeToLang(contentType) ;
+        if ( lang == null )
+            ServletOps.errorBadRequest("Can't determine output content type: 
"+contentType) ;
+        
+//        if ( rdfw instanceof RDFXMLWriterI )
+//            rdfw.setProperty("showXmlDeclaration", "true") ;
+
+    //        // Write locally to check it's possible.
+    //        // Time/space tradeoff.
+    //        try {
+    //            OutputStream out = new NullOutputStream() ;
+    //            RDFDataMgr.write(out, model, lang) ;
+    //            IO.flush(out) ;
+    //        } catch (JenaException ex)
+    //        {
+    //            SPARQL_ServletBase.errorOccurred(ex) ;
+    //        }
+
+        try {
+            ResponseResultSet.setHttpResponse(action, contentType, charset) ; 
+            response.setStatus(HttpSC.OK_200) ;
+            ServletOutputStream out = response.getOutputStream() ;
+            RDFDataMgr.write(out, dataset, lang) ;
+            out.flush() ;
+        }
+        catch (Exception ex) { 
+            action.log.info("Exception while writing the response model: 
"+ex.getMessage(), ex) ;
+            ServletOps.errorOccurred("Exception while writing the response 
model: "+ex.getMessage(), ex) ;
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/0eb28d80/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
----------------------------------------------------------------------
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
index ba4a61a..bed63da 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
@@ -16,385 +16,463 @@
  * limitations under the License.
  */
 
-package org.apache.jena.fuseki.servlets ;
-
-import static java.lang.String.format ;
-import static org.apache.jena.fuseki.server.CounterName.QueryTimeouts ;
-import static org.apache.jena.riot.WebContent.ctHTMLForm ;
-import static org.apache.jena.riot.WebContent.ctSPARQLQuery ;
-import static org.apache.jena.riot.WebContent.isHtmlForm ;
-import static org.apache.jena.riot.WebContent.matchContentType ;
-import static org.apache.jena.riot.web.HttpNames.paramAccept ;
-import static org.apache.jena.riot.web.HttpNames.paramCallback ;
-import static org.apache.jena.riot.web.HttpNames.paramDefaultGraphURI ;
-import static org.apache.jena.riot.web.HttpNames.paramForceAccept ;
-import static org.apache.jena.riot.web.HttpNames.paramNamedGraphURI ;
-import static org.apache.jena.riot.web.HttpNames.paramOutput1 ;
-import static org.apache.jena.riot.web.HttpNames.paramOutput2 ;
-import static org.apache.jena.riot.web.HttpNames.paramQuery ;
-import static org.apache.jena.riot.web.HttpNames.paramQueryRef ;
-import static org.apache.jena.riot.web.HttpNames.paramStyleSheet ;
-import static org.apache.jena.riot.web.HttpNames.paramTimeout ;
-
-import java.io.IOException ;
-import java.io.InputStream ;
-import java.util.* ;
-
-import javax.servlet.http.HttpServletRequest ;
-import javax.servlet.http.HttpServletResponse ;
-
-import org.apache.jena.atlas.io.IO ;
-import org.apache.jena.atlas.io.IndentedLineBuffer ;
-import org.apache.jena.atlas.web.ContentType ;
-import org.apache.jena.fuseki.Fuseki ;
-import org.apache.jena.fuseki.FusekiException ;
-import org.apache.jena.fuseki.FusekiLib ;
-import org.apache.jena.query.* ;
-import org.apache.jena.rdf.model.Model ;
-import org.apache.jena.riot.web.HttpNames ;
-import org.apache.jena.riot.web.HttpOp ;
-import org.apache.jena.sparql.core.Prologue ;
-import org.apache.jena.sparql.resultset.SPARQLResult ;
-import org.apache.jena.web.HttpSC ;
-
-/** Handle SPARQL Query requests overt eh SPARQL Protocol. 
- * Subclasses provide this algorithm with the actual dataset to query, whether
- * a dataset hosted by this server ({@link SPARQL_QueryDataset}) or 
- * speciifed in the protocol request ({@link SPARQL_QueryGeneral}).   
- */ 
-public abstract class SPARQL_Query extends SPARQL_Protocol
-{
-    private static final String QueryParseBase = Fuseki.BaseParserSPARQL ;
-    
-    public SPARQL_Query() {
-        super() ;
-    }
-
-    // Choose REST verbs to support.
-
-    @Override
-    protected void doPost(HttpServletRequest request, HttpServletResponse 
response) {
-        doCommon(request, response) ;
-    }
-
-    @Override
-    protected void doGet(HttpServletRequest request, HttpServletResponse 
response) {
-        doCommon(request, response) ;
-    }
-
-    // HEAD
-
-    @Override
-    protected void doOptions(HttpServletRequest request, HttpServletResponse 
response) {
-        setCommonHeadersForOptions(response) ;
-        response.setHeader(HttpNames.hAllow, "GET,OPTIONS,POST") ;
-        response.setHeader(HttpNames.hContentLengh, "0") ;
-    }
-
-    @Override
-    protected final void perform(HttpAction action) {
-        // GET
-        if ( action.request.getMethod().equals(HttpNames.METHOD_GET) ) {
-            executeWithParameter(action) ;
-            return ;
-        }
-
-        ContentType ct = FusekiLib.getContentType(action) ;
-
-        // POST application/x-www-form-url
-        // POST ?query= and no Content-Type
-        if ( ct == null || isHtmlForm(ct) ) {
-            // validation checked that if no Content-type, then its a POST 
with ?query=
-            executeWithParameter(action) ;
-            return ;
-        }
-
-        // POST application/sparql-query
-        if ( matchContentType(ct, ctSPARQLQuery) ) {
-            executeBody(action) ;
-            return ;
-        }
-
-        ServletOps.error(HttpSC.UNSUPPORTED_MEDIA_TYPE_415, "Bad content type: 
" + ct.getContentType()) ;
-    }
-
-    // All the params we support
-
-    protected static List<String> allParams = Arrays.asList(paramQuery, 
paramDefaultGraphURI, paramNamedGraphURI,
-                                                            paramQueryRef, 
paramStyleSheet, paramAccept, paramOutput1,
-                                                            paramOutput2, 
paramCallback, paramForceAccept, paramTimeout) ;
-
-    /**
-     * Validate the request, checking HTTP method and HTTP Parameters.
-     * @param action HTTP Action
-     */
-    @Override
-    protected void validate(HttpAction action) {
-        String method = action.request.getMethod().toUpperCase(Locale.ROOT) ;
-
-        if ( !HttpNames.METHOD_POST.equals(method) && 
!HttpNames.METHOD_GET.equals(method) )
-            ServletOps.errorMethodNotAllowed("Not a GET or POST request") ;
-
-        if ( HttpNames.METHOD_GET.equals(method) && 
action.request.getQueryString() == null ) {
-            ServletOps.warning(action, "Service Description / SPARQL Query / " 
+ action.request.getRequestURI()) ;
-            ServletOps.errorNotFound("Service Description: " + 
action.request.getRequestURI()) ;
-        }
-
-        // Use of the dataset describing parameters is check later.
-        try {
-            validateParams(action, allParams) ;
-            validateRequest(action) ;
-        } catch (ActionErrorException ex) {
-            throw ex ;
-        }
-        // Query not yet parsed.
-    }
-
-    /**
-     * Validate the request after checking HTTP method and HTTP Parameters.
-     * @param action HTTP Action
-     */
-    protected abstract void validateRequest(HttpAction action) ;
-
-    /**
-     * Helper method for validating request.
-     * @param request HTTP request
-     * @param params parameters in a collection of Strings
-     */
-    protected void validateParams(HttpAction action, Collection<String> 
params) {
-        HttpServletRequest request = action.request ;
-        ContentType ct = FusekiLib.getContentType(request) ;
-        boolean mustHaveQueryParam = true ;
-        if ( ct != null ) {
-            String incoming = ct.getContentType() ;
-
-            if ( matchContentType(ctSPARQLQuery, ct) ) {
-                mustHaveQueryParam = false ;
-                // Drop through.
-            } else if ( matchContentType(ctHTMLForm, ct)) {
-                // Nothing specific to do
-            } 
-            else
-                ServletOps.error(HttpSC.UNSUPPORTED_MEDIA_TYPE_415, 
"Unsupported: " + incoming) ;
-        }
-
-        // GET/POST of a form at this point.
-
-        if ( mustHaveQueryParam ) {
-            int N = countParamOccurences(request, paramQuery) ;
-
-            if ( N == 0 )
-                ServletOps.errorBadRequest("SPARQL Query: No 'query=' 
parameter") ;
-            if ( N > 1 )
-                ServletOps.errorBadRequest("SPARQL Query: Multiple 'query=' 
parameters") ;
-
-            // application/sparql-query does not use a query param.
-            String queryStr = request.getParameter(HttpNames.paramQuery) ;
-
-            if ( queryStr == null )
-                ServletOps.errorBadRequest("SPARQL Query: No query specified 
(no 'query=' found)") ;
-            if ( queryStr.isEmpty() )
-                ServletOps.errorBadRequest("SPARQL Query: Empty query string") 
;
-        }
-
-        if ( params != null ) {
-            Enumeration<String> en = request.getParameterNames() ;
-            for (; en.hasMoreElements();) {
-                String name = en.nextElement() ;
-                if ( !params.contains(name) )
-                    ServletOps.warning(action, "SPARQL Query: Unrecognize 
request parameter (ignored): " + name) ;
-            }
-        }
-    }
-
-    private void executeWithParameter(HttpAction action) {
-        String queryString = action.request.getParameter(paramQuery) ;
-        execute(queryString, action) ;
-    }
-
-    private void executeBody(HttpAction action) {
-        String queryString = null ;
-        try {
-            InputStream input = action.request.getInputStream() ;
-            queryString = IO.readWholeFileAsUTF8(input) ;
-        } catch (IOException ex) {
-            ServletOps.errorOccurred(ex) ;
-        }
-        execute(queryString, action) ;
-    }
-
-    private void execute(String queryString, HttpAction action) {
-        String queryStringLog = ServletOps.formatForLog(queryString) ;
-        if ( action.verbose )
-            action.log.info(format("[%d] Query = \n%s", action.id, 
queryString)) ;
-        else
-            action.log.info(format("[%d] Query = %s", action.id, 
queryStringLog)) ;
-
-        Query query = null ;
-        try {
-            // NB syntax is ARQ (a superset of SPARQL)
-            query = QueryFactory.create(queryString, QueryParseBase, 
Syntax.syntaxARQ) ;
-            queryStringLog = formatForLog(query) ;
-            validateQuery(action, query) ;
-        } catch (ActionErrorException ex) {
-            throw ex ;
-        } catch (QueryParseException ex) {
-            ServletOps.errorBadRequest("Parse error: \n" + queryString + 
"\n\r" + messageForQueryException(ex)) ;
-        }
-        // Should not happen.
-        catch (QueryException ex) {
-            ServletOps.errorBadRequest("Error: \n" + queryString + "\n\r" + 
ex.getMessage()) ;
-        }
-
-        // Assumes finished whole thing by end of sendResult.
-        try {
-            action.beginRead() ;
-            Dataset dataset = decideDataset(action, query, queryStringLog) ;
-            try ( QueryExecution qExec = createQueryExecution(query, dataset) 
; ) {
-                SPARQLResult result = executeQuery(action, qExec, query, 
queryStringLog) ;
-                // Deals with exceptions itself.
-                sendResults(action, result, query.getPrologue()) ;
-            }
-        } 
-        catch (QueryParseException ex) {
-            // Late stage static error (e.g. bad fixed Lucene query string). 
-            ServletOps.errorBadRequest("Query parse error: \n" + queryString + 
"\n\r" + messageForQueryException(ex)) ;
-        }
-        catch (QueryCancelledException ex) {
-            // Additional counter information.
-            incCounter(action.getEndpoint().getCounters(), QueryTimeouts) ;
-            throw ex ;
-        } finally { action.endRead() ; }
-    }
-
-    /**
-     * Check the query - if unacceptable, throw ActionErrorException or call
-     * super.error
-     * @param action HTTP Action
-     * @param query  SPARQL Query
-     */
-    protected abstract void validateQuery(HttpAction action, Query query) ;
-
-    /** Create the {@link QueryExecution} for this operation.
-     * @param query
-     * @param dataset
-     * @return QueryExecution
-     */
-    protected QueryExecution createQueryExecution(Query query, Dataset 
dataset) {
-        return QueryExecutionFactory.create(query, dataset) ;
-    }
-
-    /** Perform the {@link QueryExecution} once.
-     * @param action
-     * @param queryExecution
-     * @param query
-     * @param queryStringLog Informational string created from the initial 
query. 
-     * @return
-     */
-    protected SPARQLResult executeQuery(HttpAction action, QueryExecution 
queryExecution, Query query, String queryStringLog) {
-        setAnyTimeouts(queryExecution, action) ;
-
-        if ( query.isSelectType() ) {
-            ResultSet rs = queryExecution.execSelect() ;
-
-            // Force some query execution now.
-            //
-            // If the timeout-first-row goes off, the output stream has not
-            // been started so the HTTP error code is sent.
-
-            rs.hasNext() ;
-
-            // If we wanted perfect query time cancellation, we could consume
-            // the result now
-            // to see if the timeout-end-of-query goes off.
-
-            // rs = ResultSetFactory.copyResults(rs) ;
-
-            action.log.info(format("[%d] exec/select", action.id)) ;
-            return new SPARQLResult(rs) ;
-        }
-
-        if ( query.isConstructType() ) {
-            Model model = queryExecution.execConstruct() ;
-            action.log.info(format("[%d] exec/construct", action.id)) ;
-            return new SPARQLResult(model) ;
-        }
-
-        if ( query.isDescribeType() ) {
-            Model model = queryExecution.execDescribe() ;
-            action.log.info(format("[%d] exec/describe", action.id)) ;
-            return new SPARQLResult(model) ;
-        }
-
-        if ( query.isAskType() ) {
-            boolean b = queryExecution.execAsk() ;
-            action.log.info(format("[%d] exec/ask", action.id)) ;
-            return new SPARQLResult(b) ;
-        }
-
-        ServletOps.errorBadRequest("Unknown query type - " + queryStringLog) ;
-        return null ;
-    }
-
-    private void setAnyTimeouts(QueryExecution qexec, HttpAction action) {
-//        if ( !(action.getDataService().allowTimeoutOverride) )
-//            return ;
-
-        long desiredTimeout = Long.MAX_VALUE ;
-        String timeoutHeader = action.request.getHeader("Timeout") ;
-        String timeoutParameter = action.request.getParameter("timeout") ;
-        if ( timeoutHeader != null ) {
-            try {
-                desiredTimeout = (int)(Float.parseFloat(timeoutHeader) * 1000) 
;
-            } catch (NumberFormatException e) {
-                throw new FusekiException("Timeout header must be a number", 
e) ;
-            }
-        } else if ( timeoutParameter != null ) {
-            try {
-                desiredTimeout = (int)(Float.parseFloat(timeoutParameter) * 
1000) ;
-            } catch (NumberFormatException e) {
-                throw new FusekiException("timeout parameter must be a 
number", e) ;
-            }
-        }
-
-//        desiredTimeout = 
Math.min(action.getDataService().maximumTimeoutOverride, desiredTimeout) ;
-        if ( desiredTimeout != Long.MAX_VALUE )
-            qexec.setTimeout(desiredTimeout) ;
-    }
-
-    /** Choose the dataset for this SPARQL Query request. 
-     * @param action
-     * @param query  Query - this may be modified to remove a 
DatasetDescription.
-     * @param queryStringLog 
-     * @return {@link Dataset}
-     */
-    protected abstract Dataset decideDataset(HttpAction action, Query query, 
String queryStringLog) ;
-
-    /** Ship the results to the remote caller.
-     * @param action
-     * @param result
-     * @param qPrologue
-     */
-    protected void sendResults(HttpAction action, SPARQLResult result, 
Prologue qPrologue) {
-        if ( result.isResultSet() )
-            ResponseResultSet.doResponseResultSet(action, 
result.getResultSet(), qPrologue) ;
-        else if ( result.isGraph() )
-            ResponseModel.doResponseModel(action, result.getModel()) ;
-        else if ( result.isBoolean() )
-            ResponseResultSet.doResponseResultSet(action, 
result.getBooleanResult()) ;
-        else
-            ServletOps.errorOccurred("Unknown or invalid result type") ;
-    }
-
-    private String formatForLog(Query query) {
-        IndentedLineBuffer out = new IndentedLineBuffer() ;
-        out.setFlatMode(true) ;
-        query.serialize(out) ;
-        return out.asString() ;
-    }
-
-    private String getRemoteString(String queryURI) {
-        return HttpOp.execHttpGetString(queryURI) ;
-    }
+package org.apache.jena.fuseki.servlets;
+
+import static java.lang.String.format;
+import static org.apache.jena.fuseki.server.CounterName.QueryTimeouts;
+import static org.apache.jena.riot.WebContent.ctHTMLForm;
+import static org.apache.jena.riot.WebContent.ctSPARQLQuery;
+import static org.apache.jena.riot.WebContent.isHtmlForm;
+import static org.apache.jena.riot.WebContent.matchContentType;
+import static org.apache.jena.riot.web.HttpNames.paramAccept;
+import static org.apache.jena.riot.web.HttpNames.paramCallback;
+import static org.apache.jena.riot.web.HttpNames.paramDefaultGraphURI;
+import static org.apache.jena.riot.web.HttpNames.paramForceAccept;
+import static org.apache.jena.riot.web.HttpNames.paramNamedGraphURI;
+import static org.apache.jena.riot.web.HttpNames.paramOutput1;
+import static org.apache.jena.riot.web.HttpNames.paramOutput2;
+import static org.apache.jena.riot.web.HttpNames.paramQuery;
+import static org.apache.jena.riot.web.HttpNames.paramQueryRef;
+import static org.apache.jena.riot.web.HttpNames.paramStyleSheet;
+import static org.apache.jena.riot.web.HttpNames.paramTimeout;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.jena.atlas.io.IO;
+import org.apache.jena.atlas.io.IndentedLineBuffer;
+import org.apache.jena.atlas.web.AcceptList;
+import org.apache.jena.atlas.web.ContentType;
+import org.apache.jena.atlas.web.MediaType;
+import org.apache.jena.fuseki.DEF;
+import org.apache.jena.fuseki.Fuseki;
+import org.apache.jena.fuseki.FusekiException;
+import org.apache.jena.fuseki.FusekiLib;
+import org.apache.jena.fuseki.conneg.WebLib;
+import org.apache.jena.query.Dataset;
+import org.apache.jena.query.Query;
+import org.apache.jena.query.QueryCancelledException;
+import org.apache.jena.query.QueryException;
+import org.apache.jena.query.QueryExecution;
+import org.apache.jena.query.QueryExecutionFactory;
+import org.apache.jena.query.QueryFactory;
+import org.apache.jena.query.QueryParseException;
+import org.apache.jena.query.ResultSet;
+import org.apache.jena.query.Syntax;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.riot.web.HttpNames;
+import org.apache.jena.riot.web.HttpOp;
+import org.apache.jena.sparql.core.Prologue;
+import org.apache.jena.sparql.resultset.SPARQLResult;
+import org.apache.jena.web.HttpSC;
+
+/**
+ * Handle SPARQL Query requests overt eh SPARQL Protocol. Subclasses provide
+ * this algorithm with the actual dataset to query, whether a dataset hosted by
+ * this server ({@link SPARQL_QueryDataset}) or speciifed in the protocol
+ * request ({@link SPARQL_QueryGeneral}).
+ */
+public abstract class SPARQL_Query extends SPARQL_Protocol {
+       private static final String QueryParseBase = Fuseki.BaseParserSPARQL;
+
+       public SPARQL_Query() {
+               super();
+       }
+
+       // Choose REST verbs to support.
+
+       @Override
+       protected void doPost(HttpServletRequest request,
+                       HttpServletResponse response) {
+               doCommon(request, response);
+       }
+
+       @Override
+       protected void doGet(HttpServletRequest request,
+                       HttpServletResponse response) {
+               doCommon(request, response);
+       }
+
+       // HEAD
+
+       @Override
+       protected void doOptions(HttpServletRequest request,
+                       HttpServletResponse response) {
+               setCommonHeadersForOptions(response);
+               response.setHeader(HttpNames.hAllow, "GET,OPTIONS,POST");
+               response.setHeader(HttpNames.hContentLengh, "0");
+       }
+
+       @Override
+       protected final void perform(HttpAction action) {
+               // GET
+               if (action.request.getMethod().equals(HttpNames.METHOD_GET)) {
+                       executeWithParameter(action);
+                       return;
+               }
+
+               ContentType ct = FusekiLib.getContentType(action);
+
+               // POST application/x-www-form-url
+               // POST ?query= and no Content-Type
+               if (ct == null || isHtmlForm(ct)) {
+                       // validation checked that if no Content-type, then its 
a POST with
+                       // ?query=
+                       executeWithParameter(action);
+                       return;
+               }
+
+               // POST application/sparql-query
+               if (matchContentType(ct, ctSPARQLQuery)) {
+                       executeBody(action);
+                       return;
+               }
+
+               ServletOps.error(HttpSC.UNSUPPORTED_MEDIA_TYPE_415,
+                               "Bad content type: " + ct.getContentType());
+       }
+
+       // All the params we support
+
+       protected static List<String> allParams = Arrays.asList(paramQuery,
+                       paramDefaultGraphURI, paramNamedGraphURI, paramQueryRef,
+                       paramStyleSheet, paramAccept, paramOutput1, 
paramOutput2,
+                       paramCallback, paramForceAccept, paramTimeout);
+
+       /**
+        * Validate the request, checking HTTP method and HTTP Parameters.
+        * 
+        * @param action
+        *            HTTP Action
+        */
+       @Override
+       protected void validate(HttpAction action) {
+               String method = 
action.request.getMethod().toUpperCase(Locale.ROOT);
+
+               if (!HttpNames.METHOD_POST.equals(method)
+                               && !HttpNames.METHOD_GET.equals(method))
+                       ServletOps.errorMethodNotAllowed("Not a GET or POST 
request");
+
+               if (HttpNames.METHOD_GET.equals(method)
+                               && action.request.getQueryString() == null) {
+                       ServletOps.warning(action, "Service Description / 
SPARQL Query / "
+                                       + action.request.getRequestURI());
+                       ServletOps.errorNotFound("Service Description: "
+                                       + action.request.getRequestURI());
+               }
+
+               // Use of the dataset describing parameters is check later.
+               try {
+                       validateParams(action, allParams);
+                       validateRequest(action);
+               } catch (ActionErrorException ex) {
+                       throw ex;
+               }
+               // Query not yet parsed.
+       }
+
+       /**
+        * Validate the request after checking HTTP method and HTTP Parameters.
+        * 
+        * @param action
+        *            HTTP Action
+        */
+       protected abstract void validateRequest(HttpAction action);
+
+       /**
+        * Helper method for validating request.
+        * 
+        * @param request
+        *            HTTP request
+        * @param params
+        *            parameters in a collection of Strings
+        */
+       protected void validateParams(HttpAction action, Collection<String> 
params) {
+               HttpServletRequest request = action.request;
+               ContentType ct = FusekiLib.getContentType(request);
+               boolean mustHaveQueryParam = true;
+               if (ct != null) {
+                       String incoming = ct.getContentType();
+
+                       if (matchContentType(ctSPARQLQuery, ct)) {
+                               mustHaveQueryParam = false;
+                               // Drop through.
+                       } else if (matchContentType(ctHTMLForm, ct)) {
+                               // Nothing specific to do
+                       } else
+                               
ServletOps.error(HttpSC.UNSUPPORTED_MEDIA_TYPE_415,
+                                               "Unsupported: " + incoming);
+               }
+
+               // GET/POST of a form at this point.
+
+               if (mustHaveQueryParam) {
+                       int N = countParamOccurences(request, paramQuery);
+
+                       if (N == 0)
+                               ServletOps
+                                               .errorBadRequest("SPARQL Query: 
No 'query=' parameter");
+                       if (N > 1)
+                               ServletOps
+                                               .errorBadRequest("SPARQL Query: 
Multiple 'query=' parameters");
+
+                       // application/sparql-query does not use a query param.
+                       String queryStr = 
request.getParameter(HttpNames.paramQuery);
+
+                       if (queryStr == null)
+                               ServletOps
+                                               .errorBadRequest("SPARQL Query: 
No query specified (no 'query=' found)");
+                       if (queryStr.isEmpty())
+                               ServletOps.errorBadRequest("SPARQL Query: Empty 
query string");
+               }
+
+               if (params != null) {
+                       Enumeration<String> en = request.getParameterNames();
+                       for (; en.hasMoreElements();) {
+                               String name = en.nextElement();
+                               if (!params.contains(name))
+                                       ServletOps.warning(action,
+                                                       "SPARQL Query: 
Unrecognize request parameter (ignored): "
+                                                                       + name);
+                       }
+               }
+       }
+
+       private void executeWithParameter(HttpAction action) {
+               String queryString = action.request.getParameter(paramQuery);
+               execute(queryString, action);
+       }
+
+       private void executeBody(HttpAction action) {
+               String queryString = null;
+               try {
+                       InputStream input = action.request.getInputStream();
+                       queryString = IO.readWholeFileAsUTF8(input);
+               } catch (IOException ex) {
+                       ServletOps.errorOccurred(ex);
+               }
+               execute(queryString, action);
+       }
+
+       private void execute(String queryString, HttpAction action) {
+               String queryStringLog = ServletOps.formatForLog(queryString);
+               if (action.verbose)
+                       action.log
+                                       .info(format("[%d] Query = \n%s", 
action.id, queryString));
+               else
+                       action.log
+                                       .info(format("[%d] Query = %s", 
action.id, queryStringLog));
+
+               Query query = null;
+               try {
+                       // NB syntax is ARQ (a superset of SPARQL)
+                       query = QueryFactory.create(queryString, QueryParseBase,
+                                       Syntax.syntaxARQ);
+                       queryStringLog = formatForLog(query);
+                       validateQuery(action, query);
+               } catch (ActionErrorException ex) {
+                       throw ex;
+               } catch (QueryParseException ex) {
+                       ServletOps.errorBadRequest("Parse error: \n" + 
queryString + "\n\r"
+                                       + messageForQueryException(ex));
+               }
+               // Should not happen.
+               catch (QueryException ex) {
+                       ServletOps.errorBadRequest("Error: \n" + queryString + 
"\n\r"
+                                       + ex.getMessage());
+               }
+
+               // Assumes finished whole thing by end of sendResult.
+               try {
+                       action.beginRead();
+                       Dataset dataset = decideDataset(action, query, 
queryStringLog);
+                       try (QueryExecution qExec = createQueryExecution(query, 
dataset);) {
+                               SPARQLResult result = executeQuery(action, 
qExec, query,
+                                               queryStringLog);
+                               // Deals with exceptions itself.
+                               sendResults(action, result, 
query.getPrologue());
+                       }
+               } catch (QueryParseException ex) {
+                       // Late stage static error (e.g. bad fixed Lucene query 
string).
+                       ServletOps.errorBadRequest("Query parse error: \n" + 
queryString
+                                       + "\n\r" + 
messageForQueryException(ex));
+               } catch (QueryCancelledException ex) {
+                       // Additional counter information.
+                       incCounter(action.getEndpoint().getCounters(), 
QueryTimeouts);
+                       throw ex;
+               } finally {
+                       action.endRead();
+               }
+       }
+
+       /**
+        * Check the query - if unacceptable, throw ActionErrorException or call
+        * super.error
+        * 
+        * @param action
+        *            HTTP Action
+        * @param query
+        *            SPARQL Query
+        */
+       protected abstract void validateQuery(HttpAction action, Query query);
+
+       /**
+        * Create the {@link QueryExecution} for this operation.
+        * 
+        * @param query
+        * @param dataset
+        * @return QueryExecution
+        */
+       protected QueryExecution createQueryExecution(Query query, Dataset 
dataset) {
+               return QueryExecutionFactory.create(query, dataset);
+       }
+
+       /**
+        * Perform the {@link QueryExecution} once.
+        * 
+        * @param action
+        * @param queryExecution
+        * @param query
+        * @param queryStringLog
+        *            Informational string created from the initial query.
+        * @return
+        */
+       protected SPARQLResult executeQuery(HttpAction action,
+                       QueryExecution queryExecution, Query query, String 
queryStringLog) {
+               setAnyTimeouts(queryExecution, action);
+
+               if (query.isSelectType()) {
+                       ResultSet rs = queryExecution.execSelect();
+
+                       // Force some query execution now.
+                       //
+                       // If the timeout-first-row goes off, the output stream 
has not
+                       // been started so the HTTP error code is sent.
+
+                       rs.hasNext();
+
+                       // If we wanted perfect query time cancellation, we 
could consume
+                       // the result now
+                       // to see if the timeout-end-of-query goes off.
+
+                       // rs = ResultSetFactory.copyResults(rs) ;
+
+                       action.log.info(format("[%d] exec/select", action.id));
+                       return new SPARQLResult(rs);
+               }
+
+               if (query.isConstructType()) {
+
+                       MediaType rdfMediaType = AcceptList.match( 
DEF.pureRdfOffer, new AcceptList( WebLib.getAccept(action.getRequest())));
+                       
+                       if ( ! rdfMediaType.getType().equals("*") ) {
+                               Model model = queryExecution.execConstruct();
+                               action.log.info(format("[%d] 
exec/construct/model", action.id));
+                               return new SPARQLResult(model);
+                       } else  {
+                               Dataset dataset = 
queryExecution.execConstructDataset();
+                               action.log
+                                               .info(format("[%d] 
exec/construct/dataset", action.id));
+                               return new SPARQLResult(dataset);
+                       }
+               }
+
+               if (query.isDescribeType()) {
+                       Model model = queryExecution.execDescribe();
+                       action.log.info(format("[%d] exec/describe", 
action.id));
+                       return new SPARQLResult(model);
+               }
+
+               if (query.isAskType()) {
+                       boolean b = queryExecution.execAsk();
+                       action.log.info(format("[%d] exec/ask", action.id));
+                       return new SPARQLResult(b);
+               }
+
+               ServletOps.errorBadRequest("Unknown query type - " + 
queryStringLog);
+               return null;
+       }
+
+       private void setAnyTimeouts(QueryExecution qexec, HttpAction action) {
+               // if ( !(action.getDataService().allowTimeoutOverride) )
+               // return ;
+
+               long desiredTimeout = Long.MAX_VALUE;
+               String timeoutHeader = action.request.getHeader("Timeout");
+               String timeoutParameter = 
action.request.getParameter("timeout");
+               if (timeoutHeader != null) {
+                       try {
+                               desiredTimeout = (int) 
(Float.parseFloat(timeoutHeader) * 1000);
+                       } catch (NumberFormatException e) {
+                               throw new FusekiException("Timeout header must 
be a number", e);
+                       }
+               } else if (timeoutParameter != null) {
+                       try {
+                               desiredTimeout = (int) 
(Float.parseFloat(timeoutParameter) * 1000);
+                       } catch (NumberFormatException e) {
+                               throw new FusekiException("timeout parameter 
must be a number",
+                                               e);
+                       }
+               }
+
+               // desiredTimeout =
+               // Math.min(action.getDataService().maximumTimeoutOverride,
+               // desiredTimeout) ;
+               if (desiredTimeout != Long.MAX_VALUE)
+                       qexec.setTimeout(desiredTimeout);
+       }
+
+       /**
+        * Choose the dataset for this SPARQL Query request.
+        * 
+        * @param action
+        * @param query
+        * @param queryStringLog
+        * @return {@link Dataset}
+        */
+       protected abstract Dataset decideDataset(HttpAction action, Query query,
+                       String queryStringLog);
+
+       /**
+        * Ship the results to the remote caller.
+        * 
+        * @param action
+        * @param result
+        * @param qPrologue
+        */
+       protected void sendResults(HttpAction action, SPARQLResult result,
+                       Prologue qPrologue) {
+               if (result.isResultSet())
+                       ResponseResultSet.doResponseResultSet(action,
+                                       result.getResultSet(), qPrologue);
+               else if (result.isGraph()) {
+                       ResponseModel.doResponseModel(action, 
result.getModel());
+               } else if (result.isBoolean())
+                       ResponseResultSet.doResponseResultSet(action,
+                                       result.getBooleanResult());
+               else if (result.isDataset()) {
+                       ResponseDataset.doResponseDataset(action, 
result.getDataset());
+               } else
+                       ServletOps.errorOccurred("Unknown or invalid result 
type");
+       }
+
+       private String formatForLog(Query query) {
+               IndentedLineBuffer out = new IndentedLineBuffer();
+               out.setFlatMode(true);
+               query.serialize(out);
+               return out.asString();
+       }
+
+       private String getRemoteString(String queryURI) {
+               return HttpOp.execHttpGetString(queryURI);
+       }
 
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/0eb28d80/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TestQuery.java
----------------------------------------------------------------------
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TestQuery.java
 
b/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TestQuery.java
index 2f4d73a..911d105 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TestQuery.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TestQuery.java
@@ -16,140 +16,136 @@
  * limitations under the License.
  */
 
-package org.apache.jena.fuseki ;
+package org.apache.jena.fuseki;
 
-import static org.apache.jena.fuseki.ServerTest.gn1 ;
-import static org.apache.jena.fuseki.ServerTest.gn2 ;
-import static org.apache.jena.fuseki.ServerTest.model1 ;
-import static org.apache.jena.fuseki.ServerTest.model2 ;
-import static org.apache.jena.fuseki.ServerTest.serviceQuery ;
-import static org.apache.jena.fuseki.ServerTest.serviceREST ;
+import static org.apache.jena.fuseki.ServerTest.gn1;
+import static org.apache.jena.fuseki.ServerTest.model1;
+import static org.apache.jena.fuseki.ServerTest.model2;
+import static org.apache.jena.fuseki.ServerTest.serviceQuery;
+import static org.apache.jena.fuseki.ServerTest.serviceREST;
 
-import java.io.IOException ;
-import java.net.HttpURLConnection ;
-import java.net.URL ;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Iterator;
 
-import org.apache.jena.atlas.junit.BaseTest ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.query.* ;
-import org.apache.jena.sparql.core.Var ;
-import org.apache.jena.sparql.engine.binding.Binding ;
-import org.apache.jena.sparql.resultset.ResultSetCompare ;
-import org.apache.jena.sparql.sse.Item ;
-import org.apache.jena.sparql.sse.SSE ;
-import org.apache.jena.sparql.sse.builders.BuilderResultSet ;
-import org.apache.jena.sparql.util.Convert ;
-import org.junit.AfterClass ;
-import org.junit.Assert ;
-import org.junit.BeforeClass ;
-import org.junit.Test ;
+import org.apache.jena.atlas.junit.BaseTest;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.query.DatasetAccessor;
+import org.apache.jena.query.DatasetAccessorFactory;
+import org.apache.jena.query.Query;
+import org.apache.jena.query.QueryExecution;
+import org.apache.jena.query.QueryExecutionFactory;
+import org.apache.jena.query.QueryFactory;
+import org.apache.jena.query.ResultSet;
+import org.apache.jena.query.ResultSetFormatter;
+import org.apache.jena.query.Syntax;
+import org.apache.jena.sparql.core.Quad;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.engine.binding.Binding;
+import org.apache.jena.sparql.resultset.ResultSetCompare;
+import org.apache.jena.sparql.sse.Item;
+import org.apache.jena.sparql.sse.SSE;
+import org.apache.jena.sparql.sse.builders.BuilderResultSet;
+import org.apache.jena.sparql.util.Convert;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
 
-public class TestQuery extends BaseTest {
-    protected static ResultSet rs1 = null ;
+public class TestQuery extends BaseTest 
+{
+    protected static ResultSet rs1 = null ; 
     static {
         Item item = SSE.parseItem("(resultset (?s ?p ?o) (row (?s <x>)(?p 
<p>)(?o 1)))") ;
         rs1 = BuilderResultSet.build(item) ;
     }
-
-    @BeforeClass
-    public static void beforeClass() {
+    
+    @BeforeClass public static void beforeClass()
+    {
         ServerTest.allocServer() ;
         ServerTest.resetServer() ;
         DatasetAccessor du = DatasetAccessorFactory.createHTTP(serviceREST) ;
         du.putModel(model1) ;
         du.putModel(gn1, model2) ;
     }
-
-    @AfterClass
-    public static void afterClass() {
+    
+    @AfterClass public static void afterClass()
+    {
         DatasetAccessor du = DatasetAccessorFactory.createHTTP(serviceREST) ;
         du.deleteDefault() ;
         ServerTest.freeServer() ;
     }
-
-    @Test
-    public void query_01() {
+    
+    @Test public void query_01()
+    {
         execQuery("SELECT * {?s ?p ?o}", 1) ;
     }
-
-    @Test
-    public void query_recursive_01() {
-        String query = "SELECT * WHERE { SERVICE <" + serviceQuery + "> { ?s 
?p ?o . BIND(?o AS ?x) } }" ;
-        try (QueryExecution qExec = 
QueryExecutionFactory.sparqlService(serviceQuery, query)) {
-            ResultSet rs = qExec.execSelect() ;
-            Var x = Var.alloc("x") ;
+    
+    @Test public void query_recursive_01()
+    {
+        String query = "SELECT * WHERE { SERVICE <" + serviceQuery + "> { ?s 
?p ?o . BIND(?o AS ?x) } }";
+        try ( QueryExecution qExec = 
QueryExecutionFactory.sparqlService(serviceQuery, query) ) {
+            ResultSet rs = qExec.execSelect();
+            Var x = Var.alloc("x");
             while (rs.hasNext()) {
-                Binding b = rs.nextBinding() ;
-                Assert.assertNotNull(b.get(x)) ;
+                Binding b = rs.nextBinding();
+                Assert.assertNotNull(b.get(x));
             }
         }
     }
-
-    @Test
-    public void query_with_params_01() {
-        String query = "ASK { }" ;
-        try (QueryExecution qExec = 
QueryExecutionFactory.sparqlService(serviceQuery + "?output=json", query)) {
-            boolean result = qExec.execAsk() ;
-            Assert.assertTrue(result) ;
+    
+    @Test public void query_with_params_01()
+    {
+        String query = "ASK { }";
+        try ( QueryExecution qExec = 
QueryExecutionFactory.sparqlService(serviceQuery + "?output=json", query) ) {
+            boolean result = qExec.execAsk();
+            Assert.assertTrue(result);
         }
     }
+    
+    @Test public void query_construct_quad_01()
+    {
+        String queryString = " CONSTRUCT { GRAPH <http://eg/g> {?s ?p ?oq} } 
WHERE {?s ?p ?oq}" ;
+        Query query = QueryFactory.create(queryString, Syntax.syntaxARQ);
+               
+        try ( QueryExecution qExec = 
QueryExecutionFactory.sparqlService(serviceQuery, query) ) {
+            Iterator<Quad> result = qExec.execConstructQuads();
+            Assert.assertTrue(result.hasNext());
+            Assert.assertEquals( "http://eg/g";, 
result.next().getGraph().getURI());
 
-    @Test
-    public void request_id_header_01() throws IOException {
-        String qs = Convert.encWWWForm("ASK{}") ;
-        URL u = new URL(serviceQuery + "?query=" + qs) ;
-        HttpURLConnection conn = (HttpURLConnection)u.openConnection() ;
-        Assert.assertTrue(conn.getHeaderField("Fuseki-Request-ID") != null) ;
-    }
-
-    @Test
-    public void query_dynamic_dataset_01() {
-        DatasetAccessor du = DatasetAccessorFactory.createHTTP(serviceREST) ;
-        du.putModel(model1);
-        du.putModel(gn1, model2);
-        {
-            String query = "SELECT * { ?s ?p ?o }" ;
-            try (QueryExecution qExec = 
QueryExecutionFactory.sparqlService(serviceQuery + "?output=json", query)) {
-                ResultSet rs = qExec.execSelect() ;
-                Node o = rs.next().getLiteral("o").asNode() ;
-                Node n = SSE.parseNode("1") ;
-                assertEquals(n, o) ;
-            }
-        }
-        {
-
-            String query = "SELECT * FROM <" + gn1 + "> { ?s ?p ?o }" ;
-            try (QueryExecution qExec = 
QueryExecutionFactory.sparqlService(serviceQuery + "?output=json", query)) {
-                ResultSet rs = qExec.execSelect() ;
-                Node o = rs.next().getLiteral("o").asNode() ;
-                Node n = SSE.parseNode("2") ;
-                assertEquals(n, o) ;
-            }
         }
     }
     
-    @Test
-    public void query_dynamic_dataset_02() {
-        DatasetAccessor du = DatasetAccessorFactory.createHTTP(serviceREST) ;
-        du.putModel(model1);
-        du.putModel(gn1, model1);
-        du.putModel(gn2, model2);
-        String query = "SELECT * FROM <"+gn1+"> FROM <"+gn2+"> { ?s ?p ?o }" ;
-        try (QueryExecution qExec = 
QueryExecutionFactory.sparqlService(serviceQuery + "?output=json", query)) {
-            ResultSet rs = qExec.execSelect() ;
-            int n = ResultSetFormatter.consume(rs) ;
-            assertEquals(2, n) ;
+    @Test public void query_construct_01()
+    {
+        String query = " CONSTRUCT {?s ?p ?o} WHERE {?s ?p ?o}" ;
+        try ( QueryExecution qExec = 
QueryExecutionFactory.sparqlService(serviceQuery, query) ) {
+            Iterator<Triple> result = qExec.execConstructTriples();
+            Assert.assertTrue(result.hasNext());
         }
     }
+    
 
-    private void execQuery(String queryString, int exceptedRowCount) {
+    
+    @Test public void request_id_header_01() throws IOException
+    {
+        String qs = Convert.encWWWForm("ASK{}") ;
+        URL u = new URL(serviceQuery+"?query="+qs);
+        HttpURLConnection conn = (HttpURLConnection) u.openConnection();
+        Assert.assertTrue(conn.getHeaderField("Fuseki-Request-ID") != null);
+    }
+
+    private void execQuery(String queryString, int exceptedRowCount)
+    {
         QueryExecution qExec = 
QueryExecutionFactory.sparqlService(serviceQuery, queryString) ;
         ResultSet rs = qExec.execSelect() ;
         int x = ResultSetFormatter.consume(rs) ;
         assertEquals(exceptedRowCount, x) ;
     }
-
-    private void execQuery(String queryString, ResultSet expectedResultSet) {
+    
+    private void execQuery(String queryString, ResultSet expectedResultSet)
+    {
         QueryExecution qExec = 
QueryExecutionFactory.sparqlService(serviceQuery, queryString) ;
         ResultSet rs = qExec.execSelect() ;
         boolean b = ResultSetCompare.equalsByTerm(rs, expectedResultSet) ;

Reply via email to