]> source.dussan.org Git - vaadin-framework.git/commitdiff
Add @VaadinServletConfiguration (#11970)
authorLeif Åstrand <leif@vaadin.com>
Tue, 4 Jun 2013 13:17:23 +0000 (16:17 +0300)
committerVaadin Code Review <review@vaadin.com>
Wed, 5 Jun 2013 09:15:40 +0000 (09:15 +0000)
Change-Id: Ic902028826adae8132bfa18b6cde7d80a2e876c4

server/src/com/vaadin/annotations/VaadinServletConfiguration.java [new file with mode: 0644]
server/src/com/vaadin/server/DefaultDeploymentConfiguration.java
server/src/com/vaadin/server/VaadinServlet.java
server/tests/src/com/vaadin/server/MockServletConfig.java
server/tests/src/com/vaadin/server/VaadinServletConfigurationTest.java [new file with mode: 0644]

diff --git a/server/src/com/vaadin/annotations/VaadinServletConfiguration.java b/server/src/com/vaadin/annotations/VaadinServletConfiguration.java
new file mode 100644 (file)
index 0000000..38e3ff2
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ * 
+ * Licensed 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 com.vaadin.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.vaadin.server.Constants;
+import com.vaadin.server.DefaultDeploymentConfiguration;
+import com.vaadin.server.DeploymentConfiguration;
+import com.vaadin.server.DeploymentConfiguration.LegacyProperyToStringMode;
+import com.vaadin.server.VaadinServlet;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.UI;
+
+/**
+ * Annotation for configuring subclasses of {@link VaadinServlet}. For a
+ * {@link VaadinServlet} class that has this annotation, the defined values are
+ * read during initialization and will be available using
+ * {@link DeploymentConfiguration#getApplicationOrSystemProperty(String, String)}
+ * as well as from specific methods in {@link DeploymentConfiguration}. Init
+ * params defined in <code>web.xml</code> or the <code>@WebServlet</code>
+ * annotation take precedence over values defined in this annotation.
+ * 
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface VaadinServletConfiguration {
+    /**
+     * Defines the init parameter name for methods in
+     * {@link VaadinServletConfiguration}.
+     * 
+     * @since 7.1
+     * @author Vaadin Ltd
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.METHOD)
+    @Documented
+    public @interface InitParameterName {
+        /**
+         * The name of the init parameter that the annotated method controls.
+         * 
+         * @return the parameter name
+         */
+        public String value();
+    }
+
+    /**
+     * Whether Vaadin is in production mode.
+     * 
+     * @return true if in production mode, false otherwise.
+     * 
+     * @see DeploymentConfiguration#isProductionMode()
+     */
+    @InitParameterName(Constants.SERVLET_PARAMETER_PRODUCTION_MODE)
+    public boolean productionMode();
+
+    /**
+     * Gets the default UI class to use for the servlet.
+     * 
+     * @return the default UI class
+     */
+    @InitParameterName(VaadinSession.UI_PARAMETER)
+    public Class<? extends UI> ui();
+
+    /**
+     * The time resources can be cached in the browser, in seconds. The default
+     * value is
+     * {@value DefaultDeploymentConfiguration#DEFAULT_RESOURCE_CACHE_TIME}.
+     * 
+     * @return the resource cache time
+     * 
+     * @see DeploymentConfiguration#getResourceCacheTime()
+     */
+    @InitParameterName(Constants.SERVLET_PARAMETER_RESOURCE_CACHE_TIME)
+    public int resourceCacheTime() default DefaultDeploymentConfiguration.DEFAULT_RESOURCE_CACHE_TIME;
+
+    /**
+     * The number of seconds between heartbeat requests of a UI, or a
+     * non-positive number if heartbeat is disabled. The default value is
+     * {@value DefaultDeploymentConfiguration#DEFAULT_HEARTBEAT_INTERVAL}.
+     * 
+     * @return the time between heartbeats
+     * 
+     * @see DeploymentConfiguration#getHeartbeatInterval()
+     */
+    @InitParameterName(Constants.SERVLET_PARAMETER_HEARTBEAT_INTERVAL)
+    public int heartbeatInterval() default DefaultDeploymentConfiguration.DEFAULT_HEARTBEAT_INTERVAL;
+
+    /**
+     * Whether a session should be closed when all its open UIs have been idle
+     * for longer than its configured maximum inactivity time. The default value
+     * is {@value DefaultDeploymentConfiguration#DEFAULT_CLOSE_IDLE_SESSIONS}.
+     * 
+     * @return true if UIs and sessions receiving only heartbeat requests are
+     *         eventually closed; false if heartbeat requests extend UI and
+     *         session lifetime indefinitely
+     * 
+     * @see DeploymentConfiguration#isCloseIdleSessions()
+     */
+    @InitParameterName(Constants.SERVLET_PARAMETER_CLOSE_IDLE_SESSIONS)
+    public boolean closeIdleSessions() default DefaultDeploymentConfiguration.DEFAULT_CLOSE_IDLE_SESSIONS;
+
+    /**
+     * The default widgetset to use for the servlet. The default value is
+     * {@value VaadinServlet#DEFAULT_WIDGETSET}.
+     * 
+     * @return the default widgetset name
+     */
+    @InitParameterName(VaadinServlet.PARAMETER_WIDGETSET)
+    public String widgetset() default VaadinServlet.DEFAULT_WIDGETSET;
+
+    /**
+     * The legacy Property.toString() mode used. The default value is
+     * {@link LegacyProperyToStringMode#DISABLED}
+     * 
+     * @return The Property.toString() mode in use.
+     * 
+     * @deprecated as of 7.1, should only be used to ease migration
+     */
+    @Deprecated
+    @InitParameterName(Constants.SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING)
+    public LegacyProperyToStringMode legacyPropertyToStringMode() default LegacyProperyToStringMode.DISABLED;
+}
index 80c3644d77962e6047e409c57bcbb075ebeda5e1..a55c3231f3f5e373221e796de8821e7d12d7af76 100644 (file)
@@ -30,6 +30,27 @@ import com.vaadin.shared.communication.PushMode;
  * @since 7.0.0
  */
 public class DefaultDeploymentConfiguration implements DeploymentConfiguration {
+    /**
+     * Default value for {@link #getResourceCacheTime()} = {@value} .
+     */
+    public static final int DEFAULT_RESOURCE_CACHE_TIME = 3600;
+
+    /**
+     * Default value for {@link #getHeartbeatInterval()} = {@value} .
+     */
+    public static final int DEFAULT_HEARTBEAT_INTERVAL = 300;
+
+    /**
+     * Default value for {@link #isCloseIdleSessions()} = {@value} .
+     */
+    public static final boolean DEFAULT_CLOSE_IDLE_SESSIONS = false;
+
+    /**
+     * Default value for {@link #getLegacyPropertyToStringMode()} =
+     * {@link LegacyProperyToStringMode#WARNING}.
+     */
+    public static final LegacyProperyToStringMode DEFAULT_LEGACY_PROPERTY_TO_STRING = LegacyProperyToStringMode.WARNING;
+
     private final Properties initParameters;
     private boolean productionMode;
     private boolean xsrfProtectionEnabled;
@@ -66,20 +87,17 @@ public class DefaultDeploymentConfiguration implements DeploymentConfiguration {
 
     private void checkLegacyPropertyToString() {
         String param = getApplicationOrSystemProperty(
-                Constants.SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING, "warning");
-        if ("true".equals(param)) {
-            legacyPropertyToStringMode = LegacyProperyToStringMode.ENABLED;
-        } else if ("false".equals(param)) {
-            legacyPropertyToStringMode = LegacyProperyToStringMode.DISABLED;
-        } else {
-            if (!"warning".equals(param)) {
-                getLogger()
-                        .log(Level.WARNING,
-                                Constants.WARNING_UNKNOWN_LEGACY_PROPERTY_TOSTRING_VALUE,
-                                param);
-            }
-            legacyPropertyToStringMode = LegacyProperyToStringMode.WARNING;
+                Constants.SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING,
+                DEFAULT_LEGACY_PROPERTY_TO_STRING.name().toLowerCase());
 
+        try {
+            legacyPropertyToStringMode = LegacyProperyToStringMode
+                    .valueOf(param.toUpperCase());
+        } catch (IllegalArgumentException e) {
+            getLogger().log(Level.WARNING,
+                    Constants.WARNING_UNKNOWN_LEGACY_PROPERTY_TOSTRING_VALUE,
+                    param);
+            legacyPropertyToStringMode = DEFAULT_LEGACY_PROPERTY_TO_STRING;
         }
     }
 
@@ -250,11 +268,11 @@ public class DefaultDeploymentConfiguration implements DeploymentConfiguration {
             resourceCacheTime = Integer
                     .parseInt(getApplicationOrSystemProperty(
                             Constants.SERVLET_PARAMETER_RESOURCE_CACHE_TIME,
-                            "3600"));
+                            Integer.toString(DEFAULT_RESOURCE_CACHE_TIME)));
         } catch (NumberFormatException e) {
             getLogger().warning(
                     Constants.WARNING_RESOURCE_CACHING_TIME_NOT_NUMERIC);
-            resourceCacheTime = 3600;
+            resourceCacheTime = DEFAULT_RESOURCE_CACHE_TIME;
         }
     }
 
@@ -263,18 +281,18 @@ public class DefaultDeploymentConfiguration implements DeploymentConfiguration {
             heartbeatInterval = Integer
                     .parseInt(getApplicationOrSystemProperty(
                             Constants.SERVLET_PARAMETER_HEARTBEAT_INTERVAL,
-                            "300"));
+                            Integer.toString(DEFAULT_HEARTBEAT_INTERVAL)));
         } catch (NumberFormatException e) {
             getLogger().warning(
                     Constants.WARNING_HEARTBEAT_INTERVAL_NOT_NUMERIC);
-            heartbeatInterval = 300;
+            heartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL;
         }
     }
 
     private void checkCloseIdleSessions() {
         closeIdleSessions = getApplicationOrSystemProperty(
-                Constants.SERVLET_PARAMETER_CLOSE_IDLE_SESSIONS, "false")
-                .equals("true");
+                Constants.SERVLET_PARAMETER_CLOSE_IDLE_SESSIONS,
+                Boolean.toString(DEFAULT_CLOSE_IDLE_SESSIONS)).equals("true");
     }
 
     private void checkPushMode() {
index 6f166db2b5a00620d094fdb2e864ea328d2d5ce4..05e3335c0074b09c9fdb7704d2ea268cb2b33e5a 100644 (file)
@@ -21,6 +21,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
+import java.lang.reflect.Method;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
@@ -38,6 +39,8 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import com.vaadin.annotations.VaadinServletConfiguration;
+import com.vaadin.annotations.VaadinServletConfiguration.InitParameterName;
 import com.vaadin.sass.internal.ScssStylesheet;
 import com.vaadin.server.communication.ServletUIInitHandler;
 import com.vaadin.shared.JsonConstants;
@@ -66,6 +69,8 @@ public class VaadinServlet extends HttpServlet implements Constants {
         super.init(servletConfig);
         Properties initParameters = new Properties();
 
+        readConfigurationAnnotation(initParameters);
+
         // Read default parameters from server.xml
         final ServletContext context = servletConfig.getServletContext();
         for (final Enumeration<String> e = context.getInitParameterNames(); e
@@ -96,6 +101,39 @@ public class VaadinServlet extends HttpServlet implements Constants {
         CurrentInstance.clearAll();
     }
 
+    private void readConfigurationAnnotation(Properties initParameters)
+            throws ServletException {
+        VaadinServletConfiguration configAnnotation = UIProvider
+                .getAnnotationFor(getClass(), VaadinServletConfiguration.class);
+        if (configAnnotation != null) {
+            Method[] methods = VaadinServletConfiguration.class
+                    .getDeclaredMethods();
+            for (Method method : methods) {
+                InitParameterName name = method
+                        .getAnnotation(InitParameterName.class);
+                assert name != null : "All methods declared in VaadinServletConfiguration should have a @InitParameterName annotation";
+
+                try {
+                    Object value = method.invoke(configAnnotation);
+
+                    String stringValue;
+                    if (value instanceof Class<?>) {
+                        stringValue = ((Class<?>) value).getName();
+                    } else {
+                        stringValue = value.toString();
+                    }
+
+                    initParameters.setProperty(name.value(), stringValue);
+                } catch (Exception e) {
+                    // This should never happen
+                    throw new ServletException(
+                            "Could not read @VaadinServletConfiguration value "
+                                    + method.getName(), e);
+                }
+            }
+        }
+    }
+
     protected void servletInitialized() throws ServletException {
         // Empty by default
     }
index b1e046c8127445e281efbd152cd3565fbb3cfc88..cd1201c2491c09100a763a24a7e0f1b40fb8689e 100644 (file)
@@ -19,8 +19,8 @@
  */
 package com.vaadin.server;
 
-import java.util.Collections;
 import java.util.Enumeration;
+import java.util.Properties;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
@@ -33,6 +33,15 @@ import javax.servlet.ServletContext;
 public class MockServletConfig implements ServletConfig {
 
     private ServletContext context = new MockServletContext();
+    private final Properties initParameters;
+
+    public MockServletConfig() {
+        this(new Properties());
+    }
+
+    public MockServletConfig(Properties initParameters) {
+        this.initParameters = initParameters;
+    }
 
     /*
      * (non-Javadoc)
@@ -61,7 +70,7 @@ public class MockServletConfig implements ServletConfig {
      */
     @Override
     public String getInitParameter(String name) {
-        return null;
+        return initParameters.getProperty(name);
     }
 
     /*
@@ -71,7 +80,7 @@ public class MockServletConfig implements ServletConfig {
      */
     @Override
     public Enumeration getInitParameterNames() {
-        return Collections.enumeration(Collections.EMPTY_LIST);
+        return initParameters.propertyNames();
     }
 
 }
diff --git a/server/tests/src/com/vaadin/server/VaadinServletConfigurationTest.java b/server/tests/src/com/vaadin/server/VaadinServletConfigurationTest.java
new file mode 100644 (file)
index 0000000..80cb1d7
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ * 
+ * Licensed 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 com.vaadin.server;
+
+import java.util.Properties;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import junit.framework.Assert;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import com.vaadin.annotations.VaadinServletConfiguration;
+import com.vaadin.server.DeploymentConfiguration.LegacyProperyToStringMode;
+import com.vaadin.server.VaadinServletConfigurationTest.MockUI;
+import com.vaadin.ui.UI;
+
+public class VaadinServletConfigurationTest {
+    public static class MockUI extends UI {
+        @Override
+        protected void init(VaadinRequest request) {
+            // Do nothing
+        }
+    }
+
+    @Test
+    public void testValuesFromAnnotation() throws ServletException {
+        TestServlet servlet = new TestServlet();
+        servlet.init(new MockServletConfig());
+        DeploymentConfiguration configuration = servlet.getService()
+                .getDeploymentConfiguration();
+
+        Assert.assertEquals(true, configuration.isProductionMode());
+        Assert.assertEquals(LegacyProperyToStringMode.DISABLED,
+                configuration.getLegacyPropertyToStringMode());
+        Assert.assertEquals(true, configuration.isCloseIdleSessions());
+        Assert.assertEquals(1234, configuration.getHeartbeatInterval());
+        Assert.assertEquals(4321, configuration.getResourceCacheTime());
+
+        Class<? extends UI> uiClass = new DefaultUIProvider()
+                .getUIClass(new UIClassSelectionEvent(new VaadinServletRequest(
+                        EasyMock.createMock(HttpServletRequest.class), servlet
+                                .getService())));
+        Assert.assertEquals(MockUI.class, uiClass);
+    }
+
+    @Test
+    public void testValuesOverriddenForServlet() throws ServletException {
+        Properties servletInitParams = new Properties();
+        servletInitParams.setProperty("productionMode", "false");
+        servletInitParams.setProperty("heartbeatInterval", "1111");
+
+        TestServlet servlet = new TestServlet();
+        servlet.init(new MockServletConfig(servletInitParams));
+        DeploymentConfiguration configuration = servlet.getService()
+                .getDeploymentConfiguration();
+
+        // Values from servlet init params take precedence
+        Assert.assertEquals(1111, configuration.getHeartbeatInterval());
+        Assert.assertEquals(false, configuration.isProductionMode());
+
+        // Other params are as defined in the annotation
+        Assert.assertEquals(LegacyProperyToStringMode.DISABLED,
+                configuration.getLegacyPropertyToStringMode());
+        Assert.assertEquals(true, configuration.isCloseIdleSessions());
+        Assert.assertEquals(4321, configuration.getResourceCacheTime());
+
+        Class<? extends UI> uiClass = new DefaultUIProvider()
+                .getUIClass(new UIClassSelectionEvent(new VaadinServletRequest(
+                        EasyMock.createMock(HttpServletRequest.class), servlet
+                                .getService())));
+        Assert.assertEquals(MockUI.class, uiClass);
+    }
+}
+
+@VaadinServletConfiguration(productionMode = true, ui = MockUI.class, closeIdleSessions = true, heartbeatInterval = 1234, resourceCacheTime = 4321)
+class TestServlet extends VaadinServlet {
+
+}