JENA-1435: Place ServiceDispatchRegistry in ServletContext

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

Branch: refs/heads/master
Commit: be57485f614b0964e0d45beda53f3d4c8d81aeee
Parents: c2b0973
Author: Andy Seaborne <[email protected]>
Authored: Fri Nov 24 17:51:11 2017 +0000
Committer: Andy Seaborne <[email protected]>
Committed: Mon Dec 11 14:56:08 2017 +0000

----------------------------------------------------------------------
 .../fuseki/server/DataAccessPointRegistry.java  |   3 +-
 .../fuseki/server/FusekiServerListener.java     |  12 ++-
 .../apache/jena/fuseki/server/Operation.java    |   4 +-
 .../jena/fuseki/servlets/ActionService.java     |   2 +-
 .../apache/jena/fuseki/servlets/Dispatch.java   |  62 -----------
 .../apache/jena/fuseki/servlets/HttpAction.java |  11 +-
 .../servlets/ServiceDispatchRegistry.java       | 108 +++++++++++++++++++
 .../jena/fuseki/servlets/ServiceRouter.java     |   2 +-
 .../jena/fuseki/embedded/FusekiServer.java      |  13 +++
 9 files changed, 144 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java
----------------------------------------------------------------------
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java
index 5e63132..965ed0f 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/DataAccessPointRegistry.java
@@ -54,11 +54,10 @@ public class DataAccessPointRegistry extends 
Registry<String, DataAccessPoint>
     // The server DataAccessPointRegistry is held in the ServletContext for 
the server.
     
     private static final String attrNameRegistry = 
"jena-fuseki:dataAccessPointRegistry" ;
-    // Policy for the location of the server-wide DataAccessPointRegistry 
     public static DataAccessPointRegistry get(ServletContext cxt) {
         DataAccessPointRegistry registry = 
(DataAccessPointRegistry)cxt.getAttribute(attrNameRegistry) ;
         if ( registry == null )
-            Log.warn(DataAccessPointRegistry.class, "No registry for 
ServletContext") ;
+            Log.warn(DataAccessPointRegistry.class, "No data access point 
registry for ServletContext") ;
         return registry ;
     }
     

http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java
----------------------------------------------------------------------
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java
index 231a0fa..ce8bb10 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/FusekiServerListener.java
@@ -24,6 +24,7 @@ import javax.servlet.ServletContextListener ;
 
 import org.apache.jena.fuseki.Fuseki ;
 import org.apache.jena.fuseki.FusekiException;
+import org.apache.jena.fuseki.servlets.ServiceDispatchRegistry;
 import org.apache.jena.tdb.StoreConnection ;
 
 /** Setup configuration.
@@ -66,8 +67,11 @@ public class FusekiServerListener implements 
ServletContextListener {
             return ;
         initialized = true ;
 
-        DataAccessPointRegistry registry = new DataAccessPointRegistry() ;
-        DataAccessPointRegistry.set(servletContext, registry);
+        ServiceDispatchRegistry serviceDispatchRegistry = new 
ServiceDispatchRegistry(true);
+        ServiceDispatchRegistry.set(servletContext, serviceDispatchRegistry);
+        DataAccessPointRegistry dataAccessPointRegistry = new 
DataAccessPointRegistry() ;
+        DataAccessPointRegistry.set(servletContext, dataAccessPointRegistry);
+        
         
         try {
             FusekiSystem.formatBaseArea() ; 
@@ -85,7 +89,7 @@ public class FusekiServerListener implements 
ServletContextListener {
             }
 
             if ( initialSetup != null ) {
-                FusekiSystem.initializeDataAccessPoints(registry,
+                
FusekiSystem.initializeDataAccessPoints(dataAccessPointRegistry,
                                                         initialSetup, 
FusekiSystem.dirConfiguration.toString()) ;
             } else {
                 Fuseki.serverLog.error("No configuration") ;
@@ -95,7 +99,7 @@ public class FusekiServerListener implements 
ServletContextListener {
             Fuseki.serverLog.error("Exception in initialization: {}", 
th.getMessage()) ;
             throw th ;
         }
-        FusekiInfo.info(initialSetup, registry);
+        FusekiInfo.info(initialSetup, dataAccessPointRegistry);
     }
 }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java
----------------------------------------------------------------------
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java
index 1a136e4..06331df 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java
@@ -18,10 +18,10 @@
 
 package org.apache.jena.fuseki.server;
 
-import org.apache.jena.fuseki.servlets.Dispatch;
+import org.apache.jena.fuseki.servlets.ServiceDispatchRegistry;
 
 /**
- * Operations are symbol to look up in the {@link Dispatch#operationToHandler} 
map. The name
+ * Operations are symbol to look up in the {@link 
ServiceDispatchRegistry#operationToHandler} map. The name
  * of an {@code Operation} is not related to the service name used to invoke 
the operation
  * which is determined by the {@link Endpoint}.
  */

http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java
----------------------------------------------------------------------
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java
index b026574..cc247ba 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java
@@ -97,7 +97,7 @@ public abstract class ActionService extends ActionBase {
                 ServletOps.errorBadRequest(format("dataset=%s", 
dataAccessPoint.getName()));
         }
 
-        ActionService handler = Dispatch.operationToHandler.get(operation);
+        ActionService handler = 
action.getServiceDispatchRegistry().findHandler(operation);
         if ( handler == null )
             ServletOps.errorBadRequest(format("dataset=%s: op=%s", 
dataAccessPoint.getName(), operation.getName()));
         // XXX -- replace action.setEndpoint

http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/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
deleted file mode 100644
index 2d66909..0000000
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/Dispatch.java
+++ /dev/null
@@ -1,62 +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 java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.jena.fuseki.server.DataService;
-import org.apache.jena.fuseki.server.Operation;
-import org.apache.jena.riot.WebContent;
-
-/** The global mapping of content-type to Operation. */
-
-public class Dispatch {
-    /** Map ContentType (lowercase, no charset) to the {@code Operation} for 
handling it. */  
-    public static Map<String, Operation> contentTypeToOperation = new 
ConcurrentHashMap<>();
-    static {
-        contentTypeToOperation.put(WebContent.contentTypeSPARQLQuery, 
Operation.Query);
-        contentTypeToOperation.put(WebContent.contentTypeSPARQLUpdate, 
Operation.Update);
-    }
-    
-    /** Map {@link Operation} to servlet handler.
-     * {@code Operation}s are the internal symbol identifying an operation,
-     * not the name used in the configuration file, 
-     * which is mapped by {@link DataService#getEndpoint(String)}. 
-     */  
-    public static Map<Operation, ActionService> operationToHandler = new 
ConcurrentHashMap<>();
-    
-    public static final ActionService queryServlet    = new 
SPARQL_QueryDataset() ;
-    public static final ActionService updateServlet   = new SPARQL_Update() ;
-    public static final ActionService uploadServlet   = new SPARQL_Upload() ;
-    public static final ActionService gspServlet_R    = new SPARQL_GSP_R() ;
-    public static final ActionService gspServlet_RW   = new SPARQL_GSP_RW() ;
-    public static final ActionService restQuads_R     = new REST_Quads_R() ;
-    public static final ActionService restQuads_RW    = new REST_Quads_RW() ;
-
-    static {
-        operationToHandler.put(Operation.Query,    queryServlet);
-        operationToHandler.put(Operation.Update,   updateServlet);
-        operationToHandler.put(Operation.Upload,   uploadServlet);
-        operationToHandler.put(Operation.GSP_R,    gspServlet_R);
-        operationToHandler.put(Operation.GSP_RW,   gspServlet_RW);
-        operationToHandler.put(Operation.Quads_R,  restQuads_R);
-        operationToHandler.put(Operation.Quads_RW, restQuads_RW);
-    }
-}

http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/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 55e32c2..9c10db1 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
@@ -91,7 +91,8 @@ public class HttpAction
     public HttpServletResponseTracker response ;
     private final String actionURI ;
     private final String contextPath ;
-    // Currently, global.
+
+    private final ServiceDispatchRegistry serviceDispatchRegistry;
     private final DataAccessPointRegistry dataAccessPointRegistry ;
     
     /**
@@ -113,6 +114,7 @@ public class HttpAction
         this.verbose = verbose ;
         this.contextPath = request.getServletContext().getContextPath() ;
         this.actionURI = ActionLib.actionURI(request) ;
+        this.serviceDispatchRegistry = 
ServiceDispatchRegistry.get(request.getServletContext()) ;
         this.dataAccessPointRegistry = 
DataAccessPointRegistry.get(request.getServletContext()) ;
     }
 
@@ -227,6 +229,13 @@ public class HttpAction
     }
     
     /**
+     * Get the ServiceRegistry for this action
+     */
+    public ServiceDispatchRegistry getServiceDispatchRegistry() {
+        return serviceDispatchRegistry ;
+    }
+
+    /**
      * Get the DataAccessPointRegistry for this action
      */
     public DataAccessPointRegistry getDataAccessPointRegistry() {

http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java
----------------------------------------------------------------------
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java
new file mode 100644
index 0000000..3d7303a
--- /dev/null
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java
@@ -0,0 +1,108 @@
+/*
+ * 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.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.servlet.ServletContext;
+
+import org.apache.jena.atlas.logging.Log;
+import org.apache.jena.fuseki.server.DataService;
+import org.apache.jena.fuseki.server.Operation;
+import org.apache.jena.riot.WebContent;
+
+/** 
+ * The global mapping of content-type to Operation and operation to 
implementation.
+ */
+
+public class ServiceDispatchRegistry {
+
+    public static final ActionService queryServlet    = new 
SPARQL_QueryDataset() ;
+    public static final ActionService updateServlet   = new SPARQL_Update() ;
+    public static final ActionService uploadServlet   = new SPARQL_Upload() ;
+    public static final ActionService gspServlet_R    = new SPARQL_GSP_R() ;
+    public static final ActionService gspServlet_RW   = new SPARQL_GSP_RW() ;
+    public static final ActionService restQuads_R     = new REST_Quads_R() ;
+    public static final ActionService restQuads_RW    = new REST_Quads_RW() ;
+    
+    /** Map ContentType (lowercase, no charset) to the {@code Operation} for 
handling it. */  
+    private final Map<String, Operation> contentTypeToOperation = new 
ConcurrentHashMap<>();
+    
+    /** Map {@link Operation} to servlet handler.
+     * {@code Operation}s are the internal symbol identifying an operation,
+     * not the name used in the configuration file, 
+     * which is mapped by {@link DataService#getEndpoint(String)}. 
+     */  
+    private final Map<Operation, ActionService> operationToHandler = new 
ConcurrentHashMap<>();
+    
+    public ServiceDispatchRegistry(boolean includeStdConfig) {
+        if ( includeStdConfig ) {
+            register(Operation.Query, WebContent.contentTypeSPARQLQuery, 
queryServlet);
+            register(Operation.Update, WebContent.contentTypeSPARQLUpdate, 
updateServlet);
+            register(Operation.Upload,   null, uploadServlet);
+            register(Operation.GSP_R,    null, gspServlet_R);
+            register(Operation.GSP_RW,   null, gspServlet_RW);
+            register(Operation.Quads_R,  null, restQuads_R);
+            register(Operation.Quads_RW, null, restQuads_RW);
+        }
+    }
+    
+    /** Find the {@link Operation} for a {@code Content-Type}, or return null. 
*/ 
+    public Operation findOperation(String contentType) {
+        if ( contentType == null )
+            return null;
+        return contentTypeToOperation.get(contentType);
+    }
+    
+    /** Find the {@link ActionService} implementation for an {@link 
Operation}, or return null..*/ 
+    public ActionService findHandler(Operation operation) {
+        if ( operation == null )
+            return null;
+        return operationToHandler.get(operation);
+    }
+    
+    /**
+     * Register a new {@link Operation}, with its {@code Content-Type} (may be 
null,
+     * meaning no dispatch by content type), and the implementation handler.
+     */
+    public void register(Operation operation, String contentType, 
ActionService action) {
+        Objects.requireNonNull(operation);
+        Objects.requireNonNull(action);
+        if ( contentType != null )
+            contentTypeToOperation.put(contentType, operation);
+        operationToHandler.put(operation, action);
+    }
+
+    // The server DataAccessPointRegistry is held in the ServletContext for 
the server.
+    
+    private static final String attrServiceRegistry = 
"jena-fuseki:ServiceDispatchRegistry" ;
+
+    public static ServiceDispatchRegistry get(ServletContext servletContext) {
+        ServiceDispatchRegistry registry = 
(ServiceDispatchRegistry)servletContext.getAttribute(attrServiceRegistry) ;
+        if ( registry == null )
+            Log.warn(ServiceDispatchRegistry.class, "No service registry for 
ServletContext") ;
+        return registry ;
+    }
+    
+    public static void set(ServletContext cxt, ServiceDispatchRegistry 
registry) {
+        cxt.setAttribute(attrServiceRegistry, registry) ;
+    }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
----------------------------------------------------------------------
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
index 4f4a2df..cb3cf1b 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
@@ -247,7 +247,7 @@ public abstract class ServiceRouter extends ActionService {
         // This does no have the ";charset="
         String ct = request.getContentType();
         if ( ct != null ) {
-            Operation operation = Dispatch.contentTypeToOperation.get(ct);
+            Operation operation = 
action.getServiceDispatchRegistry().findOperation(ct);
             if ( operation != null )
                 return operation;
         }

http://git-wip-us.apache.org/repos/asf/jena/blob/be57485f/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java
----------------------------------------------------------------------
diff --git 
a/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java
 
b/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java
index 6ac739f..ae38265 100644
--- 
a/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java
+++ 
b/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java
@@ -37,6 +37,7 @@ import org.apache.jena.fuseki.mgt.ActionStats ;
 import org.apache.jena.fuseki.server.DataAccessPoint ;
 import org.apache.jena.fuseki.server.DataAccessPointRegistry ;
 import org.apache.jena.fuseki.server.DataService ;
+import org.apache.jena.fuseki.servlets.ServiceDispatchRegistry;
 import org.apache.jena.fuseki.servlets.FusekiFilter ;
 import org.apache.jena.query.Dataset ;
 import org.apache.jena.riot.WebContent;
@@ -136,6 +137,13 @@ public class FusekiServer {
         return DataAccessPointRegistry.get(getServletContext()) ;
     }
 
+    /** Get the {@link DataAccessPointRegistry}.
+     * This method is intended for inspecting the registry.
+     */ 
+    public ServiceDispatchRegistry getServiceDispatchRegistry() {
+        return ServiceDispatchRegistry.get(getServletContext()) ;
+    }
+
     /** Start the server - the server continues to run after this call returns.
      *  To synchronise with the server stopping, call {@link #join}.  
      */
@@ -283,17 +291,22 @@ public class FusekiServer {
         
         /** Build a server according to the current description */ 
         public FusekiServer build() {
+            ServiceDispatchRegistry serviceRegistry = new 
ServiceDispatchRegistry(true);            
             DataAccessPointRegistry registry = new DataAccessPointRegistry() ;
+            
             map.forEach((name, dSrv) -> {
                 DataAccessPoint dap = new DataAccessPoint(name, dSrv) ;
                 registry.put(name, dap) ;
             }) ;
             ServletContextHandler handler = buildServletContext(contextPath, 
registry) ;
+
+            ServiceDispatchRegistry.set(handler.getServletContext(), 
serviceRegistry);
             
             setMimeTypes(handler);
             servlets(handler);
             
             DataAccessPointRegistry.set(handler.getServletContext(), registry) 
;
+
             Server server = jettyServer(port, loopback) ;
             server.setHandler(handler);
             return new FusekiServer(port, server) ;

Reply via email to