You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2015/08/24 10:13:38 UTC

[29/50] jena git commit: JENA-491 Fuseki Support: repair formatting of SPARQL_Query.java and TestQuery.java

JENA-491 Fuseki Support: repair formatting of SPARQL_Query.java and
TestQuery.java

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

Branch: refs/heads/master
Commit: c7dedb2b5b3455b2a4d62c58c138fc690d8ea383
Parents: 69f1ee2
Author: confidencesun <co...@gmail.com>
Authored: Mon Aug 17 21:12:01 2015 +0800
Committer: confidencesun <co...@gmail.com>
Committed: Mon Aug 17 21:12:01 2015 +0800

----------------------------------------------------------------------
 .../jena/fuseki/servlets/SPARQL_Query.java      | 748 +++++++++----------
 .../java/org/apache/jena/fuseki/TestQuery.java  | 193 +++--
 2 files changed, 461 insertions(+), 480 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/c7dedb2b/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 bed63da..8a2195e 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,7 +16,7 @@
  * limitations under the License.
  */
 
-package org.apache.jena.fuseki.servlets;
+package org.apache.jena.fuseki.servlets ;
 
 import static java.lang.String.format;
 import static org.apache.jena.fuseki.server.CounterName.QueryTimeouts;
@@ -74,405 +74,355 @@ 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())));
-			
+/** 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);
+			    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);
-	}
+			    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  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 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/c7dedb2b/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 911d105..21f89fc 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,95 +16,137 @@
  * limitations under the License.
  */
 
-package org.apache.jena.fuseki;
-
-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.util.Iterator;
-
-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 ; 
+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 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.graph.Triple ;
+import org.apache.jena.query.* ;
+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 ;
     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 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_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_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_quad_01()
+    @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);
@@ -117,7 +159,8 @@ public class TestQuery extends BaseTest
         }
     }
     
-    @Test public void query_construct_01()
+    @Test
+    public void query_construct_01()
     {
         String query = " CONSTRUCT {?s ?p ?o} WHERE {?s ?p ?o}" ;
         try ( QueryExecution qExec = QueryExecutionFactory.sparqlService(serviceQuery, query) ) {
@@ -125,27 +168,15 @@ public class TestQuery extends BaseTest
             Assert.assertTrue(result.hasNext());
         }
     }
-    
-
-    
-    @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)
-    {
+    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) ;