Browse Source

Make Servlet related classes more welcoming to DI (#9658)

VaadinCDIServlet can be made much cleaner when VaadinServletService can be proxied.
This also enables specialization, interceptors and delegators.
tags/8.2.0.alpha2
Dos Moonen 6 years ago
parent
commit
e83f012cf5

+ 21
- 2
server/src/main/java/com/vaadin/server/VaadinService.java View 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

+ 87
- 26
server/src/main/java/com/vaadin/server/VaadinServlet.java View 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

+ 20
- 3
server/src/main/java/com/vaadin/server/VaadinServletService.java View 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));

Loading…
Cancel
Save