JENA-1435: New request dispatcher
Project: http://git-wip-us.apache.org/repos/asf/jena/repo Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/6d89af35 Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/6d89af35 Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/6d89af35 Branch: refs/heads/master Commit: 6d89af352e1a92dd1338f5d9c6f9641581423cdc Parents: 057fc73 Author: Andy Seaborne <[email protected]> Authored: Fri Nov 24 13:35:29 2017 +0000 Committer: Andy Seaborne <[email protected]> Committed: Tue Dec 12 10:07:37 2017 +0000 ---------------------------------------------------------------------- .../java/org/apache/jena/fuseki/Fuseki.java | 8 +- .../apache/jena/fuseki/build/FusekiBuilder.java | 27 +- .../org/apache/jena/fuseki/mgt/ActionCtl.java | 3 +- .../apache/jena/fuseki/mgt/ActionDatasets.java | 12 +- .../jena/fuseki/server/DataAccessPoint.java | 1 - .../apache/jena/fuseki/server/DataService.java | 25 +- .../apache/jena/fuseki/server/FusekiSystem.java | 2 +- .../jena/fuseki/server/OperationName.java | 24 +- .../apache/jena/fuseki/servlets/ActionBase.java | 12 +- .../apache/jena/fuseki/servlets/ActionLib.java | 45 +- .../jena/fuseki/servlets/ActionSPARQL.java | 94 ++- .../apache/jena/fuseki/servlets/Dispatch.java | 62 ++ .../jena/fuseki/servlets/FusekiFilter.java | 6 +- .../apache/jena/fuseki/servlets/HttpAction.java | 24 +- .../servlets/HttpServletResponseTracker.java | 4 +- .../jena/fuseki/servlets/SPARQL_Query.java | 4 +- .../fuseki/servlets/SPARQL_UberServlet.java | 412 ------------- .../servlets/SPARQL_UberServlet_Original.java | 416 ++++++++++++++ .../jena/fuseki/servlets/SPARQL_Update.java | 2 - .../jena/fuseki/servlets/SPARQL_Upload.java | 10 +- .../fuseki/servlets/ServiceRouterServlet.java | 573 +++++++++++++++++++ .../org/apache/jena/fuseki/servlets/Upload.java | 4 +- .../jena/fuseki/servlets/package-info.java | 61 ++ .../org/apache/jena/fuseki/TestDatasetOps.java | 11 +- .../apache/jena/fuseki/TestHttpOperations.java | 5 +- .../jena/fuseki/embedded/FusekiServer.java | 2 +- 26 files changed, 1318 insertions(+), 531 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/Fuseki.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/Fuseki.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/Fuseki.java index 01f6a71..4a4d4bd 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/Fuseki.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/Fuseki.java @@ -102,10 +102,14 @@ public class Fuseki { * quite sensitive to request route. * <p> * The following places use this switch: + * <ul> * <li>{@code FusekiFilter} for the "clearly not a service" case - * <li>{@code SPARQL_UberServlet}, end of dispatch (after checking for http://server/dataset/service) + * <li>{@code ServiceRouterServlet}, end of dispatch (after checking for http://server/dataset/service) * <li>{@code SPARQL_GSP.determineTarget} This is all-purpose code - should not get there because of other checks. - * + * </ul> + * <p> + * <b>Note</b><br/> + * GSP Direct Naming was implemented to provide two implementations for the SPARQL 1.1 implementation report. */ static public final boolean GSP_DIRECT_NAMING = false ; http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiBuilder.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiBuilder.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiBuilder.java index c2c4f5f..9eb3b4a 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiBuilder.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiBuilder.java @@ -46,7 +46,7 @@ public class FusekiBuilder { private static Logger log = Fuseki.builderLog ; - /** Build a DataAccessPoint, including DataService at Resource svc */ + /** Build a DataAccessPoint, including DataService, from the description at Resource svc */ public static DataAccessPoint buildDataAccessPoint(Resource svc, DatasetDescriptionRegistry dsDescMap) { RDFNode n = FusekiLib.getOne(svc, "fu:name") ; if ( ! n.isLiteral() ) @@ -58,13 +58,13 @@ public class FusekiBuilder String name = object.getLexicalForm() ; name = DataAccessPoint.canonical(name) ; - DataService dataService = FusekiBuilder.buildDataService(svc, dsDescMap) ; + DataService dataService = buildDataServiceCustom(svc, dsDescMap) ; DataAccessPoint dataAccess = new DataAccessPoint(name, dataService) ; return dataAccess ; } - /** Build a DatasetRef starting at Resource svc */ - private static DataService buildDataService(Resource svc, DatasetDescriptionRegistry dsDescMap) { + /** Build a DatasetRef starting at Resource svc, having the services as described by the descriptions. */ + private static DataService buildDataServiceCustom(Resource svc, DatasetDescriptionRegistry dsDescMap) { if ( log.isDebugEnabled() ) log.debug("Service: " + nodeLabel(svc)) ; Resource datasetDesc = ((Resource)getOne(svc, "fu:dataset")) ; Dataset ds = getDataset(datasetDesc, dsDescMap); @@ -83,13 +83,19 @@ public class FusekiBuilder // Quads - actions directly on the dataset URL are different. // In the config file they are also implicit when using GSP. + if ( ! dataService.getOperation(OperationName.GSP_RW).isEmpty() || ! dataService.getOperation(OperationName.Quads_RW).isEmpty() ) { - dataService.addEndpoint(OperationName.Quads_RW, "") ; + // ReadWrite available. + // Dispatch needs introspecting on the HTTP request. + dataService.addEndpoint(OperationName.DatasetRequest_RW, "") ; } else if ( ! dataService.getOperation(OperationName.GSP_R).isEmpty() || ! dataService.getOperation(OperationName.Quads_R).isEmpty() ) { - dataService.addEndpoint(OperationName.Quads_R, "") ; + // Read-only available. + // Dispatch needs introspecting on the HTTP request. + dataService.addEndpoint(OperationName.DatasetRequest_R, "") ; } // XXX + // This needs sorting out -- here, it is only on the whole server, not per dataset or even per service. // // Extract timeout overriding configuration if present. // if ( svc.hasProperty(FusekiVocab.pAllowTimeoutOverride) ) { // sDesc.allowTimeoutOverride = svc.getProperty(FusekiVocab.pAllowTimeoutOverride).getObject().asLiteral().getBoolean() ; @@ -116,21 +122,22 @@ public class FusekiBuilder return ds; } - /** Build a DataService starting at Resource svc */ - public static DataService buildDataService(DatasetGraph dsg, boolean allowUpdate) { + /** Build a DataService starting at Resource svc, with the standard (default) set of services */ + public static DataService buildDataServiceStd(DatasetGraph dsg, boolean allowUpdate) { DataService dataService = new DataService(dsg) ; addServiceEP(dataService, OperationName.Query, "query") ; addServiceEP(dataService, OperationName.Query, "sparql") ; if ( ! allowUpdate ) { addServiceEP(dataService, OperationName.GSP_R, "data") ; - addServiceEP(dataService, OperationName.Quads_R, "") ; + addServiceEP(dataService, OperationName.DatasetRequest_R, "") ; return dataService ; } addServiceEP(dataService, OperationName.GSP_RW, "data") ; addServiceEP(dataService, OperationName.GSP_R, "get") ; addServiceEP(dataService, OperationName.Update, "update") ; addServiceEP(dataService, OperationName.Upload, "upload") ; - addServiceEP(dataService, OperationName.Quads_RW, "") ; + // Dispatch needs introspecting on the HTTP request. + addServiceEP(dataService, OperationName.DatasetRequest_RW, "") ; return dataService ; } http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/mgt/ActionCtl.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/mgt/ActionCtl.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/mgt/ActionCtl.java index 456f97b..4909612 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/mgt/ActionCtl.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/mgt/ActionCtl.java @@ -59,8 +59,7 @@ public abstract class ActionCtl extends ActionBase return extractItemName(action) ; } - // Execute - no stats. - // Intercept point for the UberServlet + // Possible intercept point protected void executeAction(HttpAction action) { executeLifecycle(action) ; } http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java index b21d29b..b772372 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java @@ -46,7 +46,10 @@ import org.apache.jena.fuseki.build.FusekiBuilder ; import org.apache.jena.fuseki.build.Template ; import org.apache.jena.fuseki.build.TemplateFunctions ; import org.apache.jena.fuseki.server.* ; -import org.apache.jena.fuseki.servlets.* ; +import org.apache.jena.fuseki.servlets.ActionLib; +import org.apache.jena.fuseki.servlets.HttpAction; +import org.apache.jena.fuseki.servlets.ServletOps; +import org.apache.jena.fuseki.servlets.Upload; import org.apache.jena.graph.Node ; import org.apache.jena.graph.NodeFactory ; import org.apache.jena.query.Dataset ; @@ -431,8 +434,11 @@ public class ActionDatasets extends ActionContainerItem { try { input = request.getInputStream() ; } catch (IOException ex) { IO.exception(ex) ; } + // Don't log - assemblers are typically small. + // Adding this to the log confuses things. + // Reserve logging for data uploads. // int len = request.getContentLength() ; -// if ( verbose ) { +// if ( action.verbose ) { // if ( len >= 0 ) // alog.info(format("[%d] Body: Content-Length=%d, Content-Type=%s, Charset=%s => %s", action.id, len, // ct.getContentType(), ct.getCharset(), lang.getName())) ; @@ -441,6 +447,6 @@ public class ActionDatasets extends ActionContainerItem { // ct.getCharset(), lang.getName())) ; // } dest.prefix("root", base+"#"); - ActionSPARQL.parse(action, dest, input, lang, base) ; + ActionLib.parse(action, dest, input, lang, base) ; } } http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPoint.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPoint.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPoint.java index 5fac02f..53fb4d4 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPoint.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPoint.java @@ -22,7 +22,6 @@ import java.util.concurrent.atomic.AtomicLong ; import org.apache.jena.fuseki.servlets.HttpAction ; - /** A name in the URL space of the server */ public class DataAccessPoint { private final String name ; http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataService.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataService.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataService.java index ac87b4b..d191272 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataService.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataService.java @@ -92,7 +92,7 @@ public class DataService { //implements DatasetMXBean { operations.put(operationName, endpoint); } - public Endpoint getOperation(String endpointName) { + public Endpoint getEndpoint(String endpointName) { return endpoints.get(endpointName) ; } @@ -113,18 +113,23 @@ public class DataService { //implements DatasetMXBean { //@Override public boolean allowUpdate() { return true ; } - public void goOffline() { - offlineInProgress.set(true) ; - acceptingRequests.set(false) ; - state = DatasetStatus.OFFLINE ; + public void goOffline() { + offlineInProgress.set(true); + acceptingRequests.set(false); + state = DatasetStatus.OFFLINE; } - - public void goActive() { - offlineInProgress.set(false) ; - acceptingRequests.set(true) ; - state = DatasetStatus.ACTIVE ; + + public void goActive() { + offlineInProgress.set(false); + acceptingRequests.set(true); + state = DatasetStatus.ACTIVE; } + // Due to concurrency, call isAcceptingRequests(). +// public boolean isActive() { +// return state != DatasetStatus.ACTIVE; +// } + public boolean isAcceptingRequests() { return acceptingRequests.get() ; } http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiSystem.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiSystem.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiSystem.java index 6a95765..78f6490 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiSystem.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiSystem.java @@ -350,7 +350,7 @@ public class FusekiSystem private static DataAccessPoint datasetDefaultConfiguration( String name, DatasetGraph dsg, boolean allowUpdate) { name = DataAccessPoint.canonical(name) ; - DataService ds = FusekiBuilder.buildDataService(dsg, allowUpdate) ; + DataService ds = FusekiBuilder.buildDataServiceStd(dsg, allowUpdate) ; DataAccessPoint dap = new DataAccessPoint(name, ds) ; return dap ; } http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/OperationName.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/OperationName.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/OperationName.java index e152645..c18b0a8 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/OperationName.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/OperationName.java @@ -29,13 +29,17 @@ public class OperationName { static private NameMgr<OperationName> mgr = new NameMgr<>(); static public OperationName register(String name, String description) { return mgr.register(name, (x)->new OperationName(x, description)); } - public static final OperationName Query = register("Query", "SPARQL Query"); - public static final OperationName Update = register("Update", "SPARQL Update"); - public static final OperationName Upload = register("Upload", "File Upload"); - public static final OperationName GSP_RW = register("GSP_RW", "Graph Store Protocol"); - public static final OperationName GSP_R = register("GSP_R", "Graph Store Protocol (Read)"); - public static final OperationName Quads_RW = register("Quads_RW", "HTTP Quads"); - public static final OperationName Quads_R = register("Quads_R", "HTTP Quads (Read)"); + public static final OperationName Query = register("Query", "SPARQL Query"); + public static final OperationName Update = register("Update", "SPARQL Update"); + public static final OperationName Upload = register("Upload", "File Upload"); + public static final OperationName GSP_RW = register("GSP_RW", "Graph Store Protocol"); + public static final OperationName GSP_R = register("GSP_R", "Graph Store Protocol (Read)"); + public static final OperationName Quads_RW = register("Quads_RW", "HTTP Quads"); + public static final OperationName Quads_R = register("Quads_R", "HTTP Quads (Read)"); + + // Dummy "operation" used to mark that datasets accept request made directly on them. + public static final OperationName DatasetRequest_RW = Quads_RW; //register("Dataset", "HTTP Request"); + public static final OperationName DatasetRequest_R = Quads_R; //register("Dataset", "HTTP Request"); private final String description ; private final String name ; @@ -80,6 +84,10 @@ public class OperationName { return false; return true; } - + + @Override + public String toString() { + return name; + } } http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java index a64f2ee..3a2cecd 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionBase.java @@ -234,15 +234,15 @@ public abstract class ActionBase extends ServletBase HttpServletResponseTracker response = action.response ; if ( action.verbose ) { - if ( action.contentType != null ) - log.info(format("[%d] <= %-20s %s", action.id, HttpNames.hContentType+":", action.contentType)) ; - if ( action.contentLength != -1 ) - log.info(format("[%d] <= %-20s %d", action.id, HttpNames.hContentLengh+":", action.contentLength)) ; + if ( action.responseContentType != null ) + log.info(format("[%d] <= %-20s %s", action.id, HttpNames.hContentType+":", action.responseContentType)) ; + if ( action.responseContentLength != -1 ) + log.info(format("[%d] <= %-20s %d", action.id, HttpNames.hContentLengh+":", action.responseContentLength)) ; for (Map.Entry<String, String> e : action.headers.entrySet()) { // Skip already printed. - if ( e.getKey().equalsIgnoreCase(HttpNames.hContentType) && action.contentType != null) + if ( e.getKey().equalsIgnoreCase(HttpNames.hContentType) && action.responseContentType != null) continue; - if ( e.getKey().equalsIgnoreCase(HttpNames.hContentLengh) && action.contentLength != -1) + if ( e.getKey().equalsIgnoreCase(HttpNames.hContentLengh) && action.responseContentLength != -1) continue; log.info(format("[%d] <= %-20s %s", action.id, e.getKey()+":", e.getValue())) ; } http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLib.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLib.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLib.java index ae911d0..49e25eb 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLib.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionLib.java @@ -18,14 +18,25 @@ package org.apache.jena.fuseki.servlets; +import java.io.InputStream; +import java.nio.charset.CharacterCodingException; + import javax.servlet.http.HttpServletRequest ; +import org.apache.jena.atlas.RuntimeIOException; import org.apache.jena.atlas.web.AcceptList ; import org.apache.jena.atlas.web.MediaType ; import org.apache.jena.fuseki.DEF ; import org.apache.jena.fuseki.conneg.ConNeg ; import org.apache.jena.fuseki.server.DataAccessPoint ; import org.apache.jena.fuseki.server.DataAccessPointRegistry ; +import org.apache.jena.riot.Lang; +import org.apache.jena.riot.RDFParser; +import org.apache.jena.riot.RDFParserRegistry; +import org.apache.jena.riot.RiotException; +import org.apache.jena.riot.system.ErrorHandler; +import org.apache.jena.riot.system.ErrorHandlerFactory; +import org.apache.jena.riot.system.StreamRDF; /** Operations related to servlets */ @@ -35,7 +46,8 @@ public class ActionLib { * that assumes the form /dataset/service. * @param action the request * @return the dataset - */ public static String mapRequestToDataset(HttpAction action) { + */ + public static String mapRequestToDataset(HttpAction action) { String uri = action.getActionURI() ; return mapActionRequestToDataset(uri) ; } @@ -62,7 +74,7 @@ public class ActionLib { return uri.substring(0, i) ; } - /** Calculate the operation , given action and data access point */ + /** Calculate the operation, given action and data access point */ public static String mapRequestToOperation(HttpAction action, DataAccessPoint dsRef) { if ( dsRef == null ) return "" ; @@ -134,9 +146,12 @@ public class ActionLib { return actionURI(action.request) ; } + /** + * @return the URI without context path of the webapp. + */ public static String actionURI(HttpServletRequest request) { // Log.info(this, "URI = '"+request.getRequestURI()) ; -// Log.info(this, "Context path = '"+request.getContextPath()+"'") ; +// Log.info(this, "Context Path = '"+request.getContextPath()+"'") ; // Log.info(this, "Servlet path = '"+request.getServletPath()+"'") ; // ServletContext cxt = this.getServletContext() ; // Log.info(this, "ServletContext path = '"+cxt.getContextPath()+"'") ; @@ -150,7 +165,6 @@ public class ActionLib { String x = uri ; if ( uri.startsWith(contextPath) ) x = uri.substring(contextPath.length()) ; - //log.info("uriWithoutContextPath: uri = "+uri+" contextPath="+contextPath+ "--> x="+x) ; return x ; } @@ -176,5 +190,28 @@ public class ActionLib { public static MediaType contentNegotationQuads(HttpAction action) { return contentNegotation(action, DEF.quadsOffer, DEF.acceptNQuads) ; } + + + /** + * Parse RDF content + */ + public static void parse(HttpAction action, StreamRDF dest, InputStream input, Lang lang, String base) { + try { + if ( ! RDFParserRegistry.isRegistered(lang) ) + ServletOps.errorBadRequest("No parser for language '"+lang.getName()+"'") ; + ErrorHandler errorHandler = ErrorHandlerFactory.errorHandlerStd(action.log); + RDFParser.create() + .errorHandler(errorHandler) + .source(input) + .lang(lang) + .base(base) + .parse(dest); + } catch (RuntimeIOException ex) { + if ( ex.getCause() instanceof CharacterCodingException ) + throw new RiotException("Character Coding Error: "+ex.getMessage()); + throw ex; + } + catch (RiotException ex) { ServletOps.errorBadRequest("Parse error: "+ex.getMessage()) ; } + } } http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionSPARQL.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionSPARQL.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionSPARQL.java index 93cdbfa..1a0097d 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionSPARQL.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionSPARQL.java @@ -18,21 +18,20 @@ package org.apache.jena.fuseki.servlets; +import static java.lang.String.format; import static org.apache.jena.fuseki.server.CounterName.Requests ; import static org.apache.jena.fuseki.server.CounterName.RequestsBad ; import static org.apache.jena.fuseki.server.CounterName.RequestsGood ; -import java.io.InputStream ; -import java.nio.charset.CharacterCodingException; +import java.io.IOException; + +import javax.servlet.ServletException; import org.apache.jena.atlas.RuntimeIOException ; import org.apache.jena.fuseki.Fuseki ; import org.apache.jena.fuseki.server.* ; import org.apache.jena.query.QueryCancelledException ; -import org.apache.jena.riot.*; -import org.apache.jena.riot.system.ErrorHandler ; -import org.apache.jena.riot.system.ErrorHandlerFactory ; -import org.apache.jena.riot.system.StreamRDF ; +import org.apache.jena.web.HttpSC; /** SPARQL request lifecycle */ public abstract class ActionSPARQL extends ActionBase @@ -62,10 +61,9 @@ public abstract class ActionSPARQL extends ActionBase ServletOps.errorNotFound("No dataset for URI: "+datasetUri) ; return ; } - //dataAccessPoint. dSrv = dataAccessPoint.getDataService() ; if ( ! dSrv.isAcceptingRequests() ) { - ServletOps.errorNotFound("Dataset not active: "+datasetUri) ; + ServletOps.error(HttpSC.SERVICE_UNAVAILABLE_503, "Dataset not currently active"); return ; } } else { @@ -73,16 +71,69 @@ public abstract class ActionSPARQL extends ActionBase dSrv = DataService.serviceOnlyDataService() ; } - String operationName = mapRequestToOperation(action, dataAccessPoint) ; action.setRequest(dataAccessPoint, dSrv) ; + String endpointName = mapRequestToOperation(action, dataAccessPoint) ; - //operationName = "" + if ( true ) { + // New dispatch + OperationName opName = null; + if ( ! endpointName.isEmpty() ) { + opName = chooseEndpoint(action, dSrv, endpointName); + if ( opName == null ) + ServletOps.errorNotFound(format("dataset=%s, service=%s", dataAccessPoint.getName(), endpointName)); + + } else { + opName = chooseEndpoint(action, dSrv); + if ( opName == null ) + ServletOps.errorBadRequest(format("dataset=%s", dataAccessPoint.getName())); + } + + ActionSPARQL handler = Dispatch.OpNameToHandler.get(opName); + // XXX -- replace action.setEndpoint + Endpoint ep = dSrv.getEndpoint(endpointName) ; + //List<Endpoint> endpoints = dSrv.getOperation(opName); + action.setEndpoint(ep, endpointName); + handler.executeLifecycle(action); + return ; + } - Endpoint op = dSrv.getOperation(operationName) ; - action.setEndpoint(op, operationName); + // Old dispatch via SPARQL_UberServlet.executeAction override. + Endpoint op = dSrv.getEndpoint(endpointName) ; + action.setEndpoint(op, endpointName); executeAction(action) ; } + // These are overridden by the ServiceRouterServlet. + protected OperationName chooseEndpoint(HttpAction action, DataService dataService, String serviceName) { + Endpoint ep = dataService.getEndpoint(serviceName) ; + OperationName opName = ep.getOperationName(); + return opName; + } + + protected OperationName chooseEndpoint(HttpAction action, DataService dataService) { + // No default implementation for directly bound services operation servlets. + return null; + } + + private void executeRequest(HttpAction action, ActionSPARQL servlet) { + if ( true ) { + // Execute an ActionSPARQL. + // Bypasses HttpServlet.service to doMethod dispatch. + servlet.executeLifecycle(action) ; + return ; + } + if ( false ) { + // Execute by calling the whole servlet mechanism. + // This causes HttpServlet.service to call the appropriate doMethod. + // but the action, and the id, are not passed on and a ne one is created. + try { servlet.service(action.request, action.response) ; } + catch (ServletException | IOException e) { + ServletOps.errorOccurred(e); + } + } + } + + /** Execute a SPARQL request. Statistics have not been adjusted at this point. * * @param action @@ -194,23 +245,4 @@ public abstract class ActionSPARQL extends ActionBase Fuseki.serverLog.warn("Exception on counter dec", ex) ; } } - - public static void parse(HttpAction action, StreamRDF dest, InputStream input, Lang lang, String base) { - try { - if ( ! RDFParserRegistry.isRegistered(lang) ) - ServletOps.errorBadRequest("No parser for language '"+lang.getName()+"'") ; - ErrorHandler errorHandler = ErrorHandlerFactory.errorHandlerStd(action.log); - RDFParser.create() - .errorHandler(errorHandler) - .source(input) - .lang(lang) - .base(base) - .parse(dest); - } catch (RuntimeIOException ex) { - if ( ex.getCause() instanceof CharacterCodingException ) - throw new RiotException("Character Coding Error: "+ex.getMessage()); - throw ex; - } - catch (RiotException ex) { ServletOps.errorBadRequest("Parse error: "+ex.getMessage()) ; } - } } http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Dispatch.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Dispatch.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Dispatch.java new file mode 100644 index 0000000..d0a4cf4 --- /dev/null +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Dispatch.java @@ -0,0 +1,62 @@ +/* + * 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 java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.jena.fuseki.server.DataService; +import org.apache.jena.fuseki.server.OperationName; +import org.apache.jena.riot.WebContent; + +/** The global mapping of content-type to OperationName. */ + +public class Dispatch { + /** Map ContentType (lowercase, no charset) to the {@code OperationName} for handling it. */ + public static Map<String, OperationName> contentTypeToOpName = new ConcurrentHashMap<>(); + static { + contentTypeToOpName.put(WebContent.contentTypeSPARQLQuery, OperationName.Query); + contentTypeToOpName.put(WebContent.contentTypeSPARQLUpdate, OperationName.Update); + } + + /** Map {@link OperationName} to servlet handler. + * {@code OperartionNames} are the internal symbol identifying an operation, + * not the name used in the configuration file, which is mapped by {@link DataService#getOperation}. + * + * */ + public static Map<OperationName, ActionSPARQL> OpNameToHandler = new ConcurrentHashMap<>(); + + public static final ActionSPARQL queryServlet = new SPARQL_QueryDataset() ; + public static final ActionSPARQL updateServlet = new SPARQL_Update() ; + public static final ActionSPARQL uploadServlet = new SPARQL_Upload() ; + public static final ActionSPARQL gspServlet_R = new SPARQL_GSP_R() ; + public static final ActionSPARQL gspServlet_RW = new SPARQL_GSP_RW() ; + public static final ActionSPARQL restQuads_R = new REST_Quads_R() ; + public static final ActionSPARQL restQuads_RW = new REST_Quads_RW() ; + + static { + OpNameToHandler.put(OperationName.Query, queryServlet); + OpNameToHandler.put(OperationName.Update, updateServlet); + OpNameToHandler.put(OperationName.Upload, uploadServlet); + OpNameToHandler.put(OperationName.GSP_R, gspServlet_R); + OpNameToHandler.put(OperationName.GSP_RW, gspServlet_RW); + OpNameToHandler.put(OperationName.Quads_R, restQuads_R); + OpNameToHandler.put(OperationName.Quads_RW, restQuads_RW); + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/FusekiFilter.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/FusekiFilter.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/FusekiFilter.java index 23eec72..44ab013 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/FusekiFilter.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/FusekiFilter.java @@ -35,7 +35,7 @@ import org.slf4j.Logger ; */ public class FusekiFilter implements Filter { private static Logger log = Fuseki.serverLog ; - private static SPARQL_UberServlet überServlet = new SPARQL_UberServlet.AccessByConfig() ; + private static ServiceRouterServlet routerServlet = new ServiceRouterServlet.AccessByConfig() ; @Override public void init(FilterConfig filterConfig) { @@ -70,7 +70,7 @@ public class FusekiFilter implements Filter { if ( registry.isRegistered(datasetUri) ) { if ( LogFilter ) log.info("Filter: dispatch") ; - überServlet.doCommon(req, resp) ; + routerServlet.doCommon(req, resp) ; return ; } @@ -85,7 +85,7 @@ public class FusekiFilter implements Filter { if ( datasetUri.startsWith(dsName) ) { if ( LogFilter ) log.info("Filter: dispatch (GSP direct name)") ; - überServlet.doCommon(req, resp) ; + routerServlet.doCommon(req, resp) ; return ; } } http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java index 3df0908..6dfb1ee 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java @@ -82,8 +82,8 @@ public class HttpAction // Outcome. public int statusCode = -1 ; public String message = null ; - public int contentLength = -1 ; - public String contentType = null ; + public int responseContentLength = -1 ; + public String responseContentType = null ; // Cleared to archive: public Map <String, String> headers = new HashMap<>() ; @@ -143,6 +143,16 @@ public class HttpAction setDataset(dService.getDataset()) ; } + public void setControlRequest(DataAccessPoint dataAccessPoint, String datasetUri) { + this.dataAccessPoint = dataAccessPoint ; + this.dataService = null ; + if ( dataAccessPoint != null ) + this.dataService = dataAccessPoint.getDataService() ; + this.datasetName = datasetUri ; + if ( dataService != null ) + setDataset(dataAccessPoint.getDataService().getDataset()) ; + } + /** Minimum initialization using just a dataset. * <p> * the HTTP Action will change its transactional state and @@ -180,16 +190,6 @@ public class HttpAction return dsg ; } - public void setControlRequest(DataAccessPoint dataAccessPoint, String datasetUri) { - this.dataAccessPoint = dataAccessPoint ; - this.dataService = null ; - if ( dataAccessPoint != null ) - this.dataService = dataAccessPoint.getDataService() ; - this.datasetName = datasetUri ; - if ( dataService != null ) - setDataset(dataAccessPoint.getDataService().getDataset()) ; - } - /** * Return the "Transactional" for this HttpAction. */ http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpServletResponseTracker.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpServletResponseTracker.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpServletResponseTracker.java index ac7ce09..47f2b36 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpServletResponseTracker.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/HttpServletResponseTracker.java @@ -83,13 +83,13 @@ public class HttpServletResponseTracker extends HttpServletResponseWrapper @Override public void setContentLength(int len) { - action.contentLength = len; + action.responseContentLength = len; super.setContentLength(len); } @Override public void setContentType(String type) { - action.contentType = type; + action.responseContentType = type; super.setContentType(type); } http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/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 959d114..b0283c2 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 @@ -73,9 +73,7 @@ public abstract class SPARQL_Query extends SPARQL_Protocol } // Choose REST verbs to support. - - // doMethod : Not used with UberServlet dispatch. - + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { doCommon(request, response) ; http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java deleted file mode 100644 index e9e0587..0000000 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java +++ /dev/null @@ -1,412 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.jena.fuseki.servlets; - -import static java.lang.String.format ; -import static org.apache.jena.riot.WebContent.contentTypeSPARQLQuery ; -import static org.apache.jena.riot.WebContent.contentTypeSPARQLUpdate ; - -import java.io.IOException ; -import java.util.List ; - -import javax.servlet.ServletException ; -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.FusekiException ; -import org.apache.jena.fuseki.conneg.ConNeg ; -import org.apache.jena.fuseki.server.* ; -import org.apache.jena.riot.web.HttpNames ; - -/** This servlet can be attached to a dataset location - * and acts as a router for all SPARQL operations - * (query, update, graph store, both direct and - * indirect naming, quads operations on a dataset and - * ?query and ?update directly on a dataset.) - */ -public abstract class SPARQL_UberServlet extends ActionSPARQL -{ - private static final long serialVersionUID = -491895535163680509L; - - protected abstract boolean allowQuery(HttpAction action) ; - protected abstract boolean allowUpdate(HttpAction action) ; - protected abstract boolean allowREST_R(HttpAction action) ; - protected abstract boolean allowREST_W(HttpAction action) ; - protected abstract boolean allowQuadsR(HttpAction action) ; - protected abstract boolean allowQuadsW(HttpAction action) ; - - public static class ReadOnly extends SPARQL_UberServlet - { - private static final long serialVersionUID = -3486969173228213955L; - - public ReadOnly() { super() ; } - @Override protected boolean allowQuery(HttpAction action) { return true ; } - @Override protected boolean allowUpdate(HttpAction action) { return false ; } - @Override protected boolean allowREST_R(HttpAction action) { return true ; } - @Override protected boolean allowREST_W(HttpAction action) { return false ; } - @Override protected boolean allowQuadsR(HttpAction action) { return true ; } - @Override protected boolean allowQuadsW(HttpAction action) { return false ; } - } - - public static class ReadWrite extends SPARQL_UberServlet - { - private static final long serialVersionUID = 1383389566691599382L; - - public ReadWrite() { super() ; } - @Override protected boolean allowQuery(HttpAction action) { return true ; } - @Override protected boolean allowUpdate(HttpAction action) { return true ; } - @Override protected boolean allowREST_R(HttpAction action) { return true ; } - @Override protected boolean allowREST_W(HttpAction action) { return true ; } - @Override protected boolean allowQuadsR(HttpAction action) { return true ; } - @Override protected boolean allowQuadsW(HttpAction action) { return true ; } - } - - public static class AccessByConfig extends SPARQL_UberServlet - { - private static final long serialVersionUID = 5078964040391977778L; - - public AccessByConfig() { super() ; } - @Override protected boolean allowQuery(HttpAction action) { return isEnabled(action, OperationName.Query) ; } - @Override protected boolean allowUpdate(HttpAction action) { return isEnabled(action, OperationName.Update) ; } - @Override protected boolean allowREST_R(HttpAction action) { return isEnabled(action, OperationName.GSP_R) || isEnabled(action, OperationName.GSP_RW) ; } - @Override protected boolean allowREST_W(HttpAction action) { return isEnabled(action, OperationName.GSP_RW) ; } - @Override protected boolean allowQuadsR(HttpAction action) { return isEnabled(action, OperationName.Quads_R) || isEnabled(action, OperationName.Quads_RW) ; } - @Override protected boolean allowQuadsW(HttpAction action) { return isEnabled(action, OperationName.Quads_RW) ; } - - // Test whether there is a configuration that allows this action as the operation given. - // Ignores the operation in the action (set due to parsing - it might be "quads" - // which is the generic operation when just the dataset is specificed. - private boolean isEnabled(HttpAction action, OperationName opName) { - // Disregard the operation name of the action - DataService dSrv = action.getDataService() ; - if ( dSrv == null ) - return false; - return ! dSrv.getOperation(opName).isEmpty() ; - } - } - - /* This can be used for a single servlet for everything (über-servlet) - * - * It can check for a request that looks like a service request and passes it on. - * This takes precedence over direct naming. - */ - - private final ActionSPARQL queryServlet = new SPARQL_QueryDataset() ; - private final ActionSPARQL updateServlet = new SPARQL_Update() ; - private final ActionSPARQL uploadServlet = new SPARQL_Upload() ; - private final ActionSPARQL gspServlet_R = new SPARQL_GSP_R() ; - private final ActionSPARQL gspServlet_RW = new SPARQL_GSP_RW() ; - private final ActionSPARQL restQuads_R = new REST_Quads_R() ; - private final ActionSPARQL restQuads_RW = new REST_Quads_RW() ; - - public SPARQL_UberServlet() { super(); } - - private String getEPName(String dsname, List<String> endpoints) { - if (endpoints == null || endpoints.size() == 0) - return null ; - String x = endpoints.get(0) ; - if ( ! dsname.endsWith("/") ) - x = dsname+"/"+x ; - else - x = dsname+x ; - return x ; - } - - // These calls should not happen because we hook in at executeAction - @Override protected void validate(HttpAction action) { throw new FusekiException("Call to SPARQL_UberServlet.validate") ; } - @Override protected void perform(HttpAction action) { throw new FusekiException("Call to SPARQL_UberServlet.perform") ; } - - /** Map request to uri in the registry. - * null means no mapping done - */ - @Override - protected String mapRequestToDataset(HttpAction action) { - String uri = ActionLib.removeContextPath(action) ; - return ActionLib.mapRequestToDatasetLongest$(uri, action.getDataAccessPointRegistry()) ; - } - - /** Intercept the processing cycle at the point where the action has been set up, - * the dataset target decided but no validation or execution has been done, - * nor any stats have been done. - */ - @Override - protected void executeAction(HttpAction action) { - - // DEBUG: DataAccessPointRegistry.print("UberServlet "); - - long id = action.id ; - HttpServletRequest request = action.request ; - HttpServletResponse response = action.response ; - String actionURI = action.getActionURI() ; // No context path - String method = request.getMethod() ; - - DataAccessPoint desc = action.getDataAccessPoint() ; - DataService dSrv = action.getDataService() ; - -// if ( ! dSrv.isActive() ) -// ServletOps.error(HttpSC.SERVICE_UNAVAILABLE_503, "Dataset not currently active"); - - // Part after the DataAccessPoint (dataset) name. - String trailing = findTrailing(actionURI, desc.getName()) ; - String qs = request.getQueryString() ; - - boolean hasParams = request.getParameterMap().size() > 0 ; - - // Is it a query or update because of a ?query= , ?request= parameter? - // Test for parameters - includes HTML forms. - boolean isQuery = request.getParameter(HttpNames.paramQuery) != null ; - // Include old name "request=" - boolean isUpdate = request.getParameter(HttpNames.paramUpdate) != null || request.getParameter(HttpNames.paramRequest) != null ; - - boolean hasParamGraph = request.getParameter(HttpNames.paramGraph) != null ; - boolean hasParamGraphDefault = request.getParameter(HttpNames.paramGraphDefault) != null ; - - boolean hasTrailing = ( trailing.length() != 0 ) ; - - String ct = request.getContentType() ; - String charset = request.getCharacterEncoding() ; - - MediaType mt = null ; - if ( ct != null ) { - // Parse it. - mt = MediaType.create(ct, charset) ; - // Another way to send queries and updates is with the content-type. - if ( contentTypeSPARQLQuery.equalsIgnoreCase(ct) ) - isQuery = true ; - else if ( contentTypeSPARQLUpdate.equalsIgnoreCase(ct) ) - isUpdate = true ; - } - - if (action.log.isInfoEnabled() ) { - //String cxt = action.getContextPath() ; - action.log.info(format("[%d] %s %s :: '%s' :: %s ? %s", id, method, desc.getName(), trailing, (mt==null?"<none>":mt), (qs==null?"":qs))) ; - } - - if ( !hasTrailing ) { - // Nothing after the DataAccessPoint i.e. Dataset by name. - // Action on the dataset itself. This can be: - // - // http://localhost:3030/ds?query= - // http://localhost:3030/ds and a content type of "applicatiopn/sparql-query" - // - // http://localhost:3030/ds?update= - // http://localhost:3030/ds and a content type of "applicatiopn/sparql-update" - // - // http://localhost:3030/ds?default ?graph= GSP - // - // http://localhost:3030/ds REST quads action on the dataset itself. - if ( isQuery ) { - if ( !allowQuery(action) ) - ServletOps.errorMethodNotAllowed("SPARQL query : "+method) ; - executeRequest(action, queryServlet) ; - return ; - } - - if ( isUpdate ) { - // SPARQL Update - if ( !allowUpdate(action) ) - ServletOps.errorMethodNotAllowed("SPARQL update : "+method) ; - // This will deal with using GET. - executeRequest(action, updateServlet) ; - return ; - } - - // ?graph=, ?default - if ( hasParamGraph || hasParamGraphDefault ) { - doGraphStoreProtocol(action) ; - return ; - } - - if ( hasParams ) { - // Unrecognized ?key=value - ServletOps.errorBadRequest("Malformed request") ; - } - - // REST dataset. - boolean isGET = method.equals(HttpNames.METHOD_GET) ; - boolean isHEAD = method.equals(HttpNames.METHOD_HEAD) ; - - // Check enabled. - if ( isGET || isHEAD ) { - if ( allowQuadsR(action) ) - restQuads_R.executeLifecycle(action) ; - else - ServletOps.errorMethodNotAllowed(method) ; - return ; - } - - if ( allowQuadsW(action) ) - restQuads_RW.executeLifecycle(action) ; - else - ServletOps.errorMethodNotAllowed("Read-only dataset : "+method) ; - return ; - } - - // Has trailing path name => service or direct naming GSP. - - final boolean checkForPossibleService = true ; - if ( checkForPossibleService && action.getEndpoint() != null ) { - // There is a trailing part. - // Check it's not the same name as a registered service. - // If so, dispatch to that service. - if ( serviceDispatch(action, OperationName.Query, queryServlet) ) return ; - if ( serviceDispatch(action, OperationName.Update, updateServlet) ) return ; - if ( serviceDispatch(action, OperationName.Upload, uploadServlet) ) return ; - if ( hasParams ) { - if ( serviceDispatch(action, OperationName.GSP_R, gspServlet_R) ) return ; - if ( serviceDispatch(action, OperationName.GSP_RW, gspServlet_RW) ) return ; - } else { - // No parameters - do as a quads operation on the dataset. - if ( serviceDispatch(action, OperationName.GSP_R, restQuads_R) ) return ; - if ( serviceDispatch(action, OperationName.GSP_RW, restQuads_RW) ) return ; - } - if ( serviceDispatch(action, OperationName.Quads_RW, restQuads_RW) ) return ; - if ( serviceDispatch(action, OperationName.Quads_R, restQuads_R) ) return ; - } - // There is a trailing part - params are illegal by this point. - if ( hasParams ) - // ?? Revisit to include query-on-one-graph - //errorBadRequest("Can't invoke a query-string service on a direct named graph") ; - ServletOps.errorNotFound("Not found: dataset='"+printName(desc.getName())+ - "' service='"+printName(trailing)+ - "' query string=?"+qs); - - // There is a trailing part - not a service, no params ==> GSP direct naming. - if ( ! Fuseki.GSP_DIRECT_NAMING ) - ServletOps.errorNotFound("Not found: dataset='"+printName(desc.getName())+"' service='"+printName(trailing)+"'"); - - doGraphStoreProtocol(action); - } - - /** See if the operation is enabled for this setup. - * Return true if dispatched - */ - private boolean serviceDispatch(HttpAction action, OperationName opName, ActionSPARQL servlet) { - Endpoint operation = action.getEndpoint() ; - if ( operation == null ) - return false ; - if ( ! operation.isType(opName) ) - return false ; - // Handle OPTIONS specially. -// if ( action.getRequest().getMethod().equals(HttpNames.METHOD_OPTIONS) ) { -// // See also ServletBase.CORS_ENABLED -// //action.log.info(format("[%d] %s", action.id, action.getMethod())) ; -// setCommonHeadersForOptions(action.getResponse()) ; -// ServletOps.success(action); -// return true ; -// } - executeRequest(action, servlet) ; - return true ; - } - private String printName(String x) { - if ( x.startsWith("/") ) - return x.substring(1) ; - return x ; - } - - private void doGraphStoreProtocol(HttpAction action) { - // The GSP servlets handle direct and indirect naming. - Endpoint operation = action.getEndpoint() ; - String method = action.request.getMethod() ; - - // Try to route to read service. - - if ( HttpNames.METHOD_GET.equalsIgnoreCase(method) || - HttpNames.METHOD_HEAD.equalsIgnoreCase(method) ) - { - // Graphs Store Protocol, indirect naming, read operations - // Try to send to the R service, else drop through to RW service dispatch. - if ( ! allowREST_R(action)) - ServletOps.errorForbidden("Forbidden: SPARQL Graph Store Protocol : Read operation : "+method) ; - executeRequest(action, gspServlet_R) ; - return ; - } - - // Graphs Store Protocol, indirect naming, write (or read, though actually handled above) - // operations on the RW service. - if ( ! allowREST_W(action)) - ServletOps.errorForbidden("Forbidden: SPARQL Graph Store Protocol : "+method) ; - executeRequest(action, gspServlet_RW) ; - return ; - } - - private void executeRequest(HttpAction action, ActionSPARQL servlet) { - if ( true ) { - // Execute an ActionSPARQL. - // Bypasses HttpServlet.service to doMethod dispatch. - servlet.executeLifecycle(action) ; - return ; - } - if ( false ) { - // Execute by calling the whole servlet mechanism. - // This causes HttpServlet.service to call the appropriate doMethod. - // but the action, and the id, are not passed on and a ne one is created. - try { servlet.service(action.request, action.response) ; } - catch (ServletException | IOException e) { - ServletOps.errorOccurred(e); - } - } - } - - protected static MediaType contentNegotationQuads(HttpAction action) { - MediaType mt = ConNeg.chooseContentType(action.request, DEF.quadsOffer, DEF.acceptNQuads) ; - if ( mt == null ) - return null ; - if ( mt.getContentType() != null ) - action.response.setContentType(mt.getContentType()); - if ( mt.getCharset() != null ) - action.response.setCharacterEncoding(mt.getCharset()) ; - return mt ; - } - - /** Find part after the dataset name: service name or the graph (direct naming) */ - protected String findTrailing(String uri, String dsname) { - if ( dsname.length() >= uri.length() ) - return "" ; - return uri.substring(dsname.length()+1) ; // Skip the separating "/" - } - - // Route everything to "doCommon" - @Override - protected void doHead(HttpServletRequest request, HttpServletResponse response) - { doCommon(request, response) ; } - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - { doCommon(request, response) ; } - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - { doCommon(request, response) ; } - - @Override - protected void doOptions(HttpServletRequest request, HttpServletResponse response) - { doCommon(request, response) ; } - - @Override - protected void doPut(HttpServletRequest request, HttpServletResponse response) - { doCommon(request, response) ; } - - @Override - protected void doDelete(HttpServletRequest request, HttpServletResponse response) - { doCommon(request, response) ; } -} http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet_Original.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet_Original.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet_Original.java new file mode 100644 index 0000000..a12928f --- /dev/null +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet_Original.java @@ -0,0 +1,416 @@ +/** + * 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 java.lang.String.format ; +import static org.apache.jena.riot.WebContent.contentTypeSPARQLQuery ; +import static org.apache.jena.riot.WebContent.contentTypeSPARQLUpdate ; + +import java.io.IOException ; +import java.util.List ; + +import javax.servlet.ServletException ; +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.FusekiException ; +import org.apache.jena.fuseki.conneg.ConNeg ; +import org.apache.jena.fuseki.server.* ; +import org.apache.jena.riot.web.HttpNames ; + +// NOT USED +// Retained during migration to the new router servlet. +// Delete when that is stable. + +/** This servlet can be attached to a dataset location + * and acts as a router for all SPARQL operations + * (query, update, graph store, both direct and + * indirect naming, quads operations on a dataset and + * ?query and ?update directly on a dataset.) + */ +public abstract class SPARQL_UberServlet_Original extends ActionSPARQL +{ + private static final long serialVersionUID = -491895535163680509L; + + protected abstract boolean allowQuery(HttpAction action) ; + protected abstract boolean allowUpdate(HttpAction action) ; + protected abstract boolean allowREST_R(HttpAction action) ; + protected abstract boolean allowREST_W(HttpAction action) ; + protected abstract boolean allowQuadsR(HttpAction action) ; + protected abstract boolean allowQuadsW(HttpAction action) ; + + public static class ReadOnly extends SPARQL_UberServlet_Original + { + private static final long serialVersionUID = -3486969173228213955L; + + public ReadOnly() { super() ; } + @Override protected boolean allowQuery(HttpAction action) { return true ; } + @Override protected boolean allowUpdate(HttpAction action) { return false ; } + @Override protected boolean allowREST_R(HttpAction action) { return true ; } + @Override protected boolean allowREST_W(HttpAction action) { return false ; } + @Override protected boolean allowQuadsR(HttpAction action) { return true ; } + @Override protected boolean allowQuadsW(HttpAction action) { return false ; } + } + + public static class ReadWrite extends SPARQL_UberServlet_Original + { + private static final long serialVersionUID = 1383389566691599382L; + + public ReadWrite() { super() ; } + @Override protected boolean allowQuery(HttpAction action) { return true ; } + @Override protected boolean allowUpdate(HttpAction action) { return true ; } + @Override protected boolean allowREST_R(HttpAction action) { return true ; } + @Override protected boolean allowREST_W(HttpAction action) { return true ; } + @Override protected boolean allowQuadsR(HttpAction action) { return true ; } + @Override protected boolean allowQuadsW(HttpAction action) { return true ; } + } + + public static class AccessByConfig extends SPARQL_UberServlet_Original + { + private static final long serialVersionUID = 5078964040391977778L; + + public AccessByConfig() { super() ; } + @Override protected boolean allowQuery(HttpAction action) { return isEnabled(action, OperationName.Query) ; } + @Override protected boolean allowUpdate(HttpAction action) { return isEnabled(action, OperationName.Update) ; } + @Override protected boolean allowREST_R(HttpAction action) { return isEnabled(action, OperationName.GSP_R) || isEnabled(action, OperationName.GSP_RW) ; } + @Override protected boolean allowREST_W(HttpAction action) { return isEnabled(action, OperationName.GSP_RW) ; } + @Override protected boolean allowQuadsR(HttpAction action) { return isEnabled(action, OperationName.Quads_R) || isEnabled(action, OperationName.Quads_RW) ; } + @Override protected boolean allowQuadsW(HttpAction action) { return isEnabled(action, OperationName.Quads_RW) ; } + + // Test whether there is a configuration that allows this action as the operation given. + // Ignores the operation in the action (set due to parsing - it might be "quads" + // which is the generic operation when just the dataset is specificed. + private boolean isEnabled(HttpAction action, OperationName opName) { + // Disregard the operation name of the action + DataService dSrv = action.getDataService() ; + if ( dSrv == null ) + return false; + return ! dSrv.getOperation(opName).isEmpty() ; + } + } + + /* This can be used for a single servlet for everything (über-servlet) + * + * It can check for a request that looks like a service request and passes it on. + * This takes precedence over direct naming. + */ + + private final ActionSPARQL queryServlet = new SPARQL_QueryDataset() ; + private final ActionSPARQL updateServlet = new SPARQL_Update() ; + private final ActionSPARQL uploadServlet = new SPARQL_Upload() ; + private final ActionSPARQL gspServlet_R = new SPARQL_GSP_R() ; + private final ActionSPARQL gspServlet_RW = new SPARQL_GSP_RW() ; + private final ActionSPARQL restQuads_R = new REST_Quads_R() ; + private final ActionSPARQL restQuads_RW = new REST_Quads_RW() ; + + public SPARQL_UberServlet_Original() { super(); } + + private String getEPName(String dsname, List<String> endpoints) { + if (endpoints == null || endpoints.size() == 0) + return null ; + String x = endpoints.get(0) ; + if ( ! dsname.endsWith("/") ) + x = dsname+"/"+x ; + else + x = dsname+x ; + return x ; + } + + // These calls should not happen because we hook in at executeAction + @Override protected void validate(HttpAction action) { throw new FusekiException("Call to SPARQL_UberServlet.validate") ; } + @Override protected void perform(HttpAction action) { throw new FusekiException("Call to SPARQL_UberServlet.perform") ; } + + /** Map request to uri in the registry. + * null means no mapping done + */ + @Override + protected String mapRequestToDataset(HttpAction action) { + String uri = ActionLib.removeContextPath(action) ; + return ActionLib.mapRequestToDatasetLongest$(uri, action.getDataAccessPointRegistry()) ; + } + + /** Intercept the processing cycle at the point where the action has been set up, + * the dataset target decided but no validation or execution has been done, + * nor any stats have been done. + */ + @Override + protected void executeAction(HttpAction action) { + + // DEBUG: DataAccessPointRegistry.print("UberServlet "); + + long id = action.id ; + HttpServletRequest request = action.request ; + HttpServletResponse response = action.response ; + String actionURI = action.getActionURI() ; // No context path + String method = request.getMethod() ; + + DataAccessPoint desc = action.getDataAccessPoint() ; + DataService dSrv = action.getDataService() ; + +// if ( ! dSrv.isActive() ) +// ServletOps.error(HttpSC.SERVICE_UNAVAILABLE_503, "Dataset not currently active"); + + // Part after the DataAccessPoint (dataset) name. + String trailing = findTrailing(actionURI, desc.getName()) ; + String qs = request.getQueryString() ; + + boolean hasParams = request.getParameterMap().size() > 0 ; + + // Is it a query or update because of a ?query= , ?request= parameter? + // Test for parameters - includes HTML forms. + boolean isQuery = request.getParameter(HttpNames.paramQuery) != null ; + // Include old name "request=" + boolean isUpdate = request.getParameter(HttpNames.paramUpdate) != null || request.getParameter(HttpNames.paramRequest) != null ; + + boolean hasParamGraph = request.getParameter(HttpNames.paramGraph) != null ; + boolean hasParamGraphDefault = request.getParameter(HttpNames.paramGraphDefault) != null ; + + boolean hasTrailing = ( trailing.length() != 0 ) ; + + String ct = request.getContentType() ; + String charset = request.getCharacterEncoding() ; + + MediaType mt = null ; + if ( ct != null ) { + // Parse it. + mt = MediaType.create(ct, charset) ; + // Another way to send queries and updates is with the content-type. + if ( contentTypeSPARQLQuery.equalsIgnoreCase(ct) ) + isQuery = true ; + else if ( contentTypeSPARQLUpdate.equalsIgnoreCase(ct) ) + isUpdate = true ; + } + + if (action.log.isInfoEnabled() ) { + //String cxt = action.getContextPath() ; + action.log.info(format("[%d] %s %s :: '%s' :: %s ? %s", id, method, desc.getName(), trailing, (mt==null?"<none>":mt), (qs==null?"":qs))) ; + } + + if ( !hasTrailing ) { + // Nothing after the DataAccessPoint i.e. Dataset by name. + // Action on the dataset itself. This can be: + // + // http://localhost:3030/ds?query= + // http://localhost:3030/ds and a content type of "applicatiopn/sparql-query" + // + // http://localhost:3030/ds?update= + // http://localhost:3030/ds and a content type of "applicatiopn/sparql-update" + // + // http://localhost:3030/ds?default ?graph= GSP + // + // http://localhost:3030/ds REST quads action on the dataset itself. + if ( isQuery ) { + if ( !allowQuery(action) ) + ServletOps.errorMethodNotAllowed("SPARQL query : "+method) ; + executeRequest(action, queryServlet) ; + return ; + } + + if ( isUpdate ) { + // SPARQL Update + if ( !allowUpdate(action) ) + ServletOps.errorMethodNotAllowed("SPARQL update : "+method) ; + // This will deal with using GET. + executeRequest(action, updateServlet) ; + return ; + } + + // ?graph=, ?default + if ( hasParamGraph || hasParamGraphDefault ) { + doGraphStoreProtocol(action) ; + return ; + } + + if ( hasParams ) { + // Unrecognized ?key=value + ServletOps.errorBadRequest("Malformed request") ; + } + + // REST dataset. + boolean isGET = method.equals(HttpNames.METHOD_GET) ; + boolean isHEAD = method.equals(HttpNames.METHOD_HEAD) ; + + // Check enabled. + if ( isGET || isHEAD ) { + if ( allowQuadsR(action) ) + restQuads_R.executeLifecycle(action) ; + else + ServletOps.errorMethodNotAllowed(method) ; + return ; + } + + if ( allowQuadsW(action) ) + restQuads_RW.executeLifecycle(action) ; + else + ServletOps.errorMethodNotAllowed("Read-only dataset : "+method) ; + return ; + } + + // Has trailing path name => service or direct naming GSP. + + final boolean checkForPossibleService = true ; + if ( checkForPossibleService && action.getEndpoint() != null ) { + // There is a trailing part. + // Check it's not the same name as a registered service. + // If so, dispatch to that service. + if ( serviceDispatch(action, OperationName.Query, queryServlet) ) return ; + if ( serviceDispatch(action, OperationName.Update, updateServlet) ) return ; + if ( serviceDispatch(action, OperationName.Upload, uploadServlet) ) return ; + if ( hasParams ) { + if ( serviceDispatch(action, OperationName.GSP_R, gspServlet_R) ) return ; + if ( serviceDispatch(action, OperationName.GSP_RW, gspServlet_RW) ) return ; + } else { + // No parameters - do as a quads operation on the dataset. + if ( serviceDispatch(action, OperationName.GSP_R, restQuads_R) ) return ; + if ( serviceDispatch(action, OperationName.GSP_RW, restQuads_RW) ) return ; + } + if ( serviceDispatch(action, OperationName.Quads_RW, restQuads_RW) ) return ; + if ( serviceDispatch(action, OperationName.Quads_R, restQuads_R) ) return ; + } + // There is a trailing part - params are illegal by this point. + if ( hasParams ) + // ?? Revisit to include query-on-one-graph + //errorBadRequest("Can't invoke a query-string service on a direct named graph") ; + ServletOps.errorNotFound("Not found: dataset='"+printName(desc.getName())+ + "' service='"+printName(trailing)+ + "' query string=?"+qs); + + // There is a trailing part - not a service, no params ==> GSP direct naming. + if ( ! Fuseki.GSP_DIRECT_NAMING ) + ServletOps.errorNotFound("Not found: dataset='"+printName(desc.getName())+"' service='"+printName(trailing)+"'"); + + doGraphStoreProtocol(action); + } + + /** See if the operation is enabled for this setup. + * Return true if dispatched + */ + private boolean serviceDispatch(HttpAction action, OperationName opName, ActionSPARQL servlet) { + Endpoint operation = action.getEndpoint() ; + if ( operation == null ) + return false ; + if ( ! operation.isType(opName) ) + return false ; + // Handle OPTIONS specially. +// if ( action.getRequest().getMethod().equals(HttpNames.METHOD_OPTIONS) ) { +// // See also ServletBase.CORS_ENABLED +// //action.log.info(format("[%d] %s", action.id, action.getMethod())) ; +// setCommonHeadersForOptions(action.getResponse()) ; +// ServletOps.success(action); +// return true ; +// } + executeRequest(action, servlet) ; + return true ; + } + private String printName(String x) { + if ( x.startsWith("/") ) + return x.substring(1) ; + return x ; + } + + private void doGraphStoreProtocol(HttpAction action) { + // The GSP servlets handle direct and indirect naming. + Endpoint operation = action.getEndpoint() ; + String method = action.request.getMethod() ; + + // Try to route to read service. + + if ( HttpNames.METHOD_GET.equalsIgnoreCase(method) || + HttpNames.METHOD_HEAD.equalsIgnoreCase(method) ) + { + // Graphs Store Protocol, indirect naming, read operations + // Try to send to the R service, else drop through to RW service dispatch. + if ( ! allowREST_R(action)) + ServletOps.errorForbidden("Forbidden: SPARQL Graph Store Protocol : Read operation : "+method) ; + executeRequest(action, gspServlet_R) ; + return ; + } + + // Graphs Store Protocol, indirect naming, write (or read, though actually handled above) + // operations on the RW service. + if ( ! allowREST_W(action)) + ServletOps.errorForbidden("Forbidden: SPARQL Graph Store Protocol : "+method) ; + executeRequest(action, gspServlet_RW) ; + return ; + } + + private void executeRequest(HttpAction action, ActionSPARQL servlet) { + if ( true ) { + // Execute an ActionSPARQL. + // Bypasses HttpServlet.service to doMethod dispatch. + servlet.executeLifecycle(action) ; + return ; + } + if ( false ) { + // Execute by calling the whole servlet mechanism. + // This causes HttpServlet.service to call the appropriate doMethod. + // but the action, and the id, are not passed on and a ne one is created. + try { servlet.service(action.request, action.response) ; } + catch (ServletException | IOException e) { + ServletOps.errorOccurred(e); + } + } + } + + protected static MediaType contentNegotationQuads(HttpAction action) { + MediaType mt = ConNeg.chooseContentType(action.request, DEF.quadsOffer, DEF.acceptNQuads) ; + if ( mt == null ) + return null ; + if ( mt.getContentType() != null ) + action.response.setContentType(mt.getContentType()); + if ( mt.getCharset() != null ) + action.response.setCharacterEncoding(mt.getCharset()) ; + return mt ; + } + + /** Find part after the dataset name: service name or the graph (direct naming) */ + protected String findTrailing(String uri, String dsname) { + if ( dsname.length() >= uri.length() ) + return "" ; + return uri.substring(dsname.length()+1) ; // Skip the separating "/" + } + + // Route everything to "doCommon" + @Override + protected void doHead(HttpServletRequest request, HttpServletResponse response) + { doCommon(request, response) ; } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + { doCommon(request, response) ; } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + { doCommon(request, response) ; } + + @Override + protected void doOptions(HttpServletRequest request, HttpServletResponse response) + { doCommon(request, response) ; } + + @Override + protected void doPut(HttpServletRequest request, HttpServletResponse response) + { doCommon(request, response) ; } + + @Override + protected void doDelete(HttpServletRequest request, HttpServletResponse response) + { doCommon(request, response) ; } +} http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java index 0807bf6..cc9147f 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java @@ -74,8 +74,6 @@ public class SPARQL_Update extends SPARQL_Protocol public SPARQL_Update() { super() ; } - // doMethod : Not used with UberServlet dispatch. - @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { http://git-wip-us.apache.org/repos/asf/jena/blob/6d89af35/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java index 1dc53df..31bd0c6 100644 --- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java +++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java @@ -71,6 +71,10 @@ public class SPARQL_Upload extends ActionSPARQL } @Override + protected void validate(HttpAction action) + {} + + @Override protected void perform(HttpAction action) { // Only allows one file in the upload. boolean isMultipart = ServletFileUpload.isMultipartContent(action.request); @@ -258,7 +262,7 @@ public class SPARQL_Upload extends ActionSPARQL StreamRDF x = StreamRDFLib.dataset(dsgTmp) ; StreamRDFCounting dest = StreamRDFLib.count(x) ; - ActionSPARQL.parse(action, dest, stream, lang, base) ; + ActionLib.parse(action, dest, stream, lang, base) ; count = dest.count() ; } } @@ -272,8 +276,4 @@ public class SPARQL_Upload extends ActionSPARQL catch (ActionErrorException ex) { throw ex ; } catch (Exception ex) { ServletOps.errorOccurred(ex) ; return null ; } } - - @Override - protected void validate(HttpAction action) - {} }
