]> source.dussan.org Git - vaadin-framework.git/commitdiff
Make Servlet related classes more welcoming to DI (#9658)
authorDos Moonen <darsstar@gmail.com>
Fri, 8 Sep 2017 13:05:14 +0000 (15:05 +0200)
committerHenri Sara <henri.sara@gmail.com>
Fri, 8 Sep 2017 13:05:14 +0000 (16:05 +0300)
VaadinCDIServlet can be made much cleaner when VaadinServletService can be proxied.
This also enables specialization, interceptors and delegators.

server/src/main/java/com/vaadin/server/VaadinService.java
server/src/main/java/com/vaadin/server/VaadinServlet.java
server/src/main/java/com/vaadin/server/VaadinServletService.java

index 27a6103211458f22afc1d2289c0a48a1ab45cef3..ba54ad014fd65e2e1b227b29335e09e7359c794b 100644 (file)
@@ -114,6 +114,9 @@ public abstract class VaadinService implements Serializable {
 
     private static final String REQUEST_START_TIME_ATTRIBUTE = "requestStartTime";
 
+    /**
+     * Should never be used directly, always use {@link #getDeploymentConfiguration()}
+     */
     private final DeploymentConfiguration deploymentConfiguration;
 
     /*
@@ -184,6 +187,20 @@ public abstract class VaadinService implements Serializable {
         }
     }
 
+    /**
+     * Creates a service. This method is for use by dependency injection
+     * frameworks etc. and must be followed by a call to
+     * {@link #setClassLoader(ClassLoader)} or {@link #setDefaultClassLoader()}
+     * before use. Furthermore {@link #getDeploymentConfiguration()} should be
+     * overridden (or otherwise intercepted) so it does not return
+     * <code>null</code>.
+     *
+     * @since
+     */
+    protected VaadinService() {
+        this.deploymentConfiguration = null;
+    }
+
     /**
      * Initializes this service. The service should be initialized before it is
      * used.
@@ -357,7 +374,9 @@ public abstract class VaadinService implements Serializable {
     public abstract String getMimeType(String resourceName);
 
     /**
-     * Gets the deployment configuration.
+     * Gets the deployment configuration. Should be overridden (or otherwise
+     * intercepted) if the no-arg constructor is used in order to prevent
+     * NPEs.
      *
      * @return the deployment configuration
      */
@@ -1520,7 +1539,7 @@ public abstract class VaadinService implements Serializable {
      * Gets the filters which all resource dependencies are passed through
      * before being sent to the client for loading.
      *
-     * @see #initDependencyFilters()
+     * @see #initDependencyFilters(List)
      *
      * @since 8.1
      * @return the dependency filters to pass resources dependencies through
index b0ea6f87ec95665e0a606d60f78aee2fdac36a27..0151d42b62d75060ccc116d5ebce81c45c1ed32f 100644 (file)
@@ -45,6 +45,7 @@ import java.util.Properties;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -200,32 +201,8 @@ public class VaadinServlet extends HttpServlet implements Constants {
             throws ServletException {
         CurrentInstance.clearAll();
         super.init(servletConfig);
-        Properties initParameters = new Properties();
-
-        readUiFromEnclosingClass(initParameters);
-
-        readConfigurationAnnotation(initParameters);
-
-        // Read default parameters from server.xml
-        final ServletContext context = servletConfig.getServletContext();
-        for (final Enumeration<String> e = context.getInitParameterNames(); e
-                .hasMoreElements();) {
-            final String name = e.nextElement();
-            initParameters.setProperty(name, context.getInitParameter(name));
-        }
-
-        // Override with application config from web.xml
-        for (final Enumeration<String> e = servletConfig
-                .getInitParameterNames(); e.hasMoreElements();) {
-            final String name = e.nextElement();
-            initParameters.setProperty(name,
-                    servletConfig.getInitParameter(name));
-        }
-
-        DeploymentConfiguration deploymentConfiguration = createDeploymentConfiguration(
-                initParameters);
         try {
-            servletService = createServletService(deploymentConfiguration);
+            servletService = createServletService();
         } catch (ServiceException e) {
             throw new ServletException("Could not initialize VaadinServlet", e);
         }
@@ -321,11 +298,95 @@ public class VaadinServlet extends HttpServlet implements Constants {
         }
     }
 
+    /**
+     * Creates a deployment configuration to be used for the creation of a
+     * {@link VaadinService}. Intended to be used by dependency injection
+     * frameworks.
+     *
+     * @return the created deployment configuration
+     *
+     * @throws ServletException
+     *            if construction of the {@link Properties} for
+     *            {@link #createDeploymentConfiguration(Properties)} fails
+     *
+     * @since
+     */
+    protected DeploymentConfiguration createDeploymentConfiguration() throws ServletException {
+        Properties initParameters = new Properties();
+
+        readUiFromEnclosingClass(initParameters);
+
+        readConfigurationAnnotation(initParameters);
+
+        // Read default parameters from server.xml
+        final ServletContext context = getServletConfig().getServletContext();
+        for (final Enumeration<String> e = context.getInitParameterNames(); e
+                .hasMoreElements();) {
+            final String name = e.nextElement();
+            initParameters.setProperty(name, context.getInitParameter(name));
+        }
+
+        // Override with application config from web.xml
+        for (final Enumeration<String> e = getServletConfig()
+                .getInitParameterNames(); e.hasMoreElements();) {
+            final String name = e.nextElement();
+            initParameters.setProperty(name,
+                    getServletConfig().getInitParameter(name));
+        }
+
+        return createDeploymentConfiguration(initParameters);
+    }
+
+    /**
+     * Creates a deployment configuration to be used for the creation of a
+     * {@link VaadinService}. Override this if you want to override certain
+     * properties.
+     *
+     * @param initParameters
+     *            the context-param and init-param values as properties
+     * @return the created deployment configuration
+     *
+     * @since 7.0.0
+     */
     protected DeploymentConfiguration createDeploymentConfiguration(
             Properties initParameters) {
         return new DefaultDeploymentConfiguration(getClass(), initParameters);
     }
 
+    /**
+     * Creates a vaadin servlet service. This method functions as a layer of
+     * indirection between {@link #init(ServletConfig)} and
+     * {@link #createServletService(DeploymentConfiguration)} so dependency
+     * injection frameworks can call {@link #createDeploymentConfiguration()}
+     * when creating a vaadin servlet service lazily.
+     *
+     * @return the created vaadin servlet service
+     *
+     * @throws ServletException
+     *            if creating a deployment configuration fails
+     * @throws ServiceException
+     *            if creating the vaadin servlet service fails
+     *
+     * @since
+     */
+    protected VaadinServletService createServletService()
+            throws ServletException, ServiceException {
+        return createServletService(createDeploymentConfiguration());
+    }
+
+    /**
+     * Creates a vaadin servlet service.
+     *
+     * @param deploymentConfiguration
+     *            the deployment configuration to be used
+     *
+     * @return the created vaadin servlet service
+     *
+     * @throws ServiceException
+     *            if creating the vaadin servlet service fails
+     *
+     * @since 7.0.0
+     */
     protected VaadinServletService createServletService(
             DeploymentConfiguration deploymentConfiguration)
             throws ServiceException {
@@ -471,7 +532,7 @@ public class VaadinServlet extends HttpServlet implements Constants {
     }
 
     /**
-     * Create a Vaadin request for a http servlet request. This method can be
+     * Creates a Vaadin request for a http servlet request. This method can be
      * overridden if the Vaadin request should have special properties.
      *
      * @param request
index 4675f3734041333f9c65f6d889c76a94bf91c72f..42213f60d000019768b75c8f6faf7f55f69ca30b 100644 (file)
@@ -33,6 +33,10 @@ import com.vaadin.server.communication.ServletUIInitHandler;
 import com.vaadin.ui.UI;
 
 public class VaadinServletService extends VaadinService {
+
+    /**
+     * Should never be used directly, always use {@link #getServlet()}
+     */
     private final VaadinServlet servlet;
 
     public VaadinServletService(VaadinServlet servlet,
@@ -42,6 +46,17 @@ public class VaadinServletService extends VaadinService {
         this.servlet = servlet;
     }
 
+    /**
+     * Creates a servlet service. This method is for use by dependency
+     * injection frameworks etc. {@link #getServlet()} should be overridden (or otherwise intercepted)
+     * so it does not return <code>null</code>.
+     *
+     * @since
+     */
+    protected VaadinServletService() {
+        this.servlet = null;
+    }
+
     @Override
     protected List<RequestHandler> createRequestHandlers()
             throws ServiceException {
@@ -65,6 +80,8 @@ public class VaadinServletService extends VaadinService {
 
     /**
      * Retrieves a reference to the servlet associated with this service.
+     * Should be overridden (or otherwise intercepted) if the no-arg
+     * constructor is used to prevent NPEs.
      *
      * @return A reference to the VaadinServlet this service is using
      */
@@ -167,7 +184,7 @@ public class VaadinServletService extends VaadinService {
     @Override
     public File getBaseDirectory() {
         final String realPath = VaadinServlet
-                .getResourcePath(servlet.getServletContext(), "/");
+                .getResourcePath(getServlet().getServletContext(), "/");
         if (realPath == null) {
             return null;
         }
@@ -226,12 +243,12 @@ public class VaadinServletService extends VaadinService {
             String resource) throws IOException {
         String filename = "/" + VaadinServlet.THEME_DIR_PATH + '/' + themeName
                 + "/" + resource;
-        URL resourceUrl = servlet.findResourceURL(filename);
+        URL resourceUrl = getServlet().findResourceURL(filename);
 
         if (resourceUrl != null) {
             // security check: do not permit navigation out of the VAADIN
             // directory
-            if (!servlet.isAllowedVAADINResourceUrl(null, resourceUrl)) {
+            if (!getServlet().isAllowedVAADINResourceUrl(null, resourceUrl)) {
                 throw new IOException(String.format(
                         "Requested resource [{0}] not accessible in the VAADIN directory or access to it is forbidden.",
                         filename));