diff options
10 files changed, 209 insertions, 151 deletions
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java index 7482748302..0a0e0e5082 100644 --- a/client/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java +++ b/client/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java @@ -23,10 +23,16 @@ import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.Position; +import com.google.gwt.http.client.Request; +import com.google.gwt.http.client.RequestBuilder; +import com.google.gwt.http.client.RequestCallback; +import com.google.gwt.http.client.RequestException; +import com.google.gwt.http.client.Response; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.History; +import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; @@ -84,6 +90,14 @@ public class RootConnector extends AbstractComponentContainerConnector com.google.gwt.user.client.Window.setTitle(title); } }); + final int heartbeatInterval = getState().getHeartbeatInterval(); + new Timer() { + @Override + public void run() { + sendHeartbeat(); + schedule(heartbeatInterval); + } + }.schedule(heartbeatInterval); } @Override @@ -442,4 +456,28 @@ public class RootConnector extends AbstractComponentContainerConnector }); } + private void sendHeartbeat() { + RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, "url"); + + rb.setCallback(new RequestCallback() { + + @Override + public void onResponseReceived(Request request, Response response) { + // TODO Auto-generated method stub + + } + + @Override + public void onError(Request request, Throwable exception) { + // TODO Auto-generated method stub + + } + }); + + try { + rb.send(); + } catch (RequestException re) { + + } + } } diff --git a/server/src/com/vaadin/Application.java b/server/src/com/vaadin/Application.java index 1d716d60c5..b120c8455a 100644 --- a/server/src/com/vaadin/Application.java +++ b/server/src/com/vaadin/Application.java @@ -361,31 +361,24 @@ public class Application implements Terminal.ErrorListener, Serializable { public static class ApplicationStartEvent implements Serializable { private final URL applicationUrl; - private final Properties applicationProperties; + private final DeploymentConfiguration configuration; private final ApplicationContext context; - private final boolean productionMode; - /** * @param applicationUrl * the URL the application should respond to. - * @param applicationProperties - * the Application properties as specified by the deployment - * configuration. + * @param configuration + * the deployment configuration for the application. * @param context * the context application will be running in. - * @param productionMode - * flag indicating whether the application is running in - * production mode. */ public ApplicationStartEvent(URL applicationUrl, - Properties applicationProperties, ApplicationContext context, - boolean productionMode) { + DeploymentConfiguration configuration, + ApplicationContext context) { this.applicationUrl = applicationUrl; - this.applicationProperties = applicationProperties; + this.configuration = configuration; this.context = context; - this.productionMode = productionMode; } /** @@ -401,15 +394,12 @@ public class Application implements Terminal.ErrorListener, Serializable { } /** - * Gets the Application properties as specified by the deployment - * configuration. - * - * @return the properties configured for the applciation. + * Returns the deployment configuration used by this application. * - * @see Application#getProperty(String) + * @return the deployment configuration. */ - public Properties getApplicationProperties() { - return applicationProperties; + public DeploymentConfiguration getConfiguration() { + return configuration; } /** @@ -422,18 +412,6 @@ public class Application implements Terminal.ErrorListener, Serializable { public ApplicationContext getContext() { return context; } - - /** - * Checks whether the application is running in production mode. - * - * @return <code>true</code> if in production mode, else - * <code>false</code> - * - * @see Application#isProductionMode() - */ - public boolean isProductionMode() { - return productionMode; - } } private final static Logger logger = Logger.getLogger(Application.class @@ -445,6 +423,11 @@ public class Application implements Terminal.ErrorListener, Serializable { private ApplicationContext context; /** + * Deployment configuration for the application. + */ + private DeploymentConfiguration configuration; + + /** * The current user or <code>null</code> if no user has logged in. */ private Object user; @@ -460,11 +443,6 @@ public class Application implements Terminal.ErrorListener, Serializable { private volatile boolean applicationIsRunning = false; /** - * Application properties. - */ - private Properties properties; - - /** * Default locale of the application. */ private Locale locale; @@ -512,8 +490,6 @@ public class Application implements Terminal.ErrorListener, Serializable { private int nextRootId = 0; private Map<Integer, Root> roots = new HashMap<Integer, Root>(); - private boolean productionMode = true; - private final Map<String, Integer> retainOnRefreshRoots = new HashMap<String, Integer>(); private final EventRouter eventRouter = new EventRouter(); @@ -638,8 +614,7 @@ public class Application implements Terminal.ErrorListener, Serializable { */ public void start(ApplicationStartEvent event) { applicationUrl = event.getApplicationUrl(); - productionMode = event.isProductionMode(); - properties = event.getApplicationProperties(); + configuration = event.getConfiguration(); context = event.getContext(); init(); applicationIsRunning = true; @@ -673,6 +648,16 @@ public class Application implements Terminal.ErrorListener, Serializable { } /** + * Returns the properties of this application as specified in the deployment + * configuration. + * + * @return Application properties + */ + protected Properties getProperties() { + return configuration.getInitParameters(); + } + + /** * Returns an enumeration of all the names in this application. * * <p> @@ -685,7 +670,7 @@ public class Application implements Terminal.ErrorListener, Serializable { * */ public Enumeration<?> getPropertyNames() { - return properties.propertyNames(); + return getProperties().propertyNames(); } /** @@ -700,7 +685,7 @@ public class Application implements Terminal.ErrorListener, Serializable { * @return the value in this property list with the specified key value. */ public String getProperty(String name) { - return properties.getProperty(name); + return getProperties().getProperty(name); } /** @@ -1930,7 +1915,7 @@ public class Application implements Terminal.ErrorListener, Serializable { * @since 7.0 */ protected String getRootClassName(WrappedRequest request) { - Object rootClassNameObj = properties.get(ROOT_PARAMETER); + Object rootClassNameObj = getProperties().get(ROOT_PARAMETER); if (rootClassNameObj instanceof String) { return (String) rootClassNameObj; } else { @@ -2181,7 +2166,7 @@ public class Application implements Terminal.ErrorListener, Serializable { * @since 7.0 */ public boolean isProductionMode() { - return productionMode; + return configuration.isProductionMode(); } /** diff --git a/server/src/com/vaadin/terminal/DeploymentConfiguration.java b/server/src/com/vaadin/terminal/DeploymentConfiguration.java index 74d0320ff8..14a5a3724f 100644 --- a/server/src/com/vaadin/terminal/DeploymentConfiguration.java +++ b/server/src/com/vaadin/terminal/DeploymentConfiguration.java @@ -132,4 +132,25 @@ public interface DeploymentConfiguration extends Serializable { public AddonContext getAddonContext(); public void setAddonContext(AddonContext vaadinContext); + + /** + * Returns whether Vaadin is in production mode. + * + * @return true if in production mode, false otherwise. + */ + public boolean isProductionMode(); + + /** + * Returns whether cross-site request forgery protection is enabled. + * + * @return true if XSRF protection is enabled, false otherwise. + */ + public boolean isXsrfProtectionEnabled(); + + /** + * Returns the time resources can be cached in the browsers, in seconds. + * + * @return The resource cache time. + */ + public int getResourceCacheTime(); } diff --git a/server/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/server/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java index 7892018218..06ed54990a 100644 --- a/server/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java +++ b/server/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java @@ -328,9 +328,6 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet config.getInitParameter(name)); } - checkProductionMode(); - checkCrossSiteProtection(); - addonContext.init(); } @@ -341,34 +338,6 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet addonContext.destroy(); } - private void checkCrossSiteProtection() { - if (getDeploymentConfiguration().getApplicationOrSystemProperty( - SERVLET_PARAMETER_DISABLE_XSRF_PROTECTION, "false").equals( - "true")) { - /* - * Print an information/warning message about running with xsrf - * protection disabled - */ - getLogger().warning(WARNING_XSRF_PROTECTION_DISABLED); - } - } - - private void checkProductionMode() { - // TODO Identical code in AbstractApplicationServlet -> refactor - // Check if the application is in production mode. - // We are in production mode if productionMode=true - if (getDeploymentConfiguration().getApplicationOrSystemProperty( - SERVLET_PARAMETER_PRODUCTION_MODE, "false").equals("true")) { - productionMode = true; - } - - if (!productionMode) { - /* Print an information/warning message about running in debug mode */ - // TODO Maybe we need a different message for portlets? - getLogger().warning(NOT_PRODUCTION_MODE_INFO); - } - } - protected enum RequestType { FILE_UPLOAD, UIDL, RENDER, STATIC_FILE, APPLICATION_RESOURCE, DUMMY, EVENT, ACTION, UNKNOWN, BROWSER_DETAILS, CONNECTOR_RESOURCE; } @@ -811,8 +780,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet application.setLocale(locale); // No application URL when running inside a portlet application.start(new ApplicationStartEvent(null, - getDeploymentConfiguration().getInitParameters(), context, - isProductionMode())); + getDeploymentConfiguration(), context)); addonContext.fireApplicationStarted(application); } } diff --git a/server/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/server/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java index dcab8b44f5..8857c0e964 100644 --- a/server/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java +++ b/server/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java @@ -97,12 +97,8 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements // TODO Move some (all?) of the constants to a separate interface (shared // with portlet) - private boolean productionMode = false; - private final String resourcePath = null; - private int resourceCacheTime = 3600; - private DeploymentConfiguration deploymentConfiguration = new AbstractDeploymentConfiguration( getClass()) { @@ -176,10 +172,6 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements servletConfig.getInitParameter(name)); } - checkProductionMode(); - checkCrossSiteProtection(); - checkResourceCacheTime(); - addonContext.init(); } @@ -190,47 +182,6 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements addonContext.destroy(); } - private void checkCrossSiteProtection() { - if (getDeploymentConfiguration().getApplicationOrSystemProperty( - SERVLET_PARAMETER_DISABLE_XSRF_PROTECTION, "false").equals( - "true")) { - /* - * Print an information/warning message about running with xsrf - * protection disabled - */ - getLogger().warning(WARNING_XSRF_PROTECTION_DISABLED); - } - } - - private void checkProductionMode() { - // Check if the application is in production mode. - // We are in production mode if productionMode=true - if (getDeploymentConfiguration().getApplicationOrSystemProperty( - SERVLET_PARAMETER_PRODUCTION_MODE, "false").equals("true")) { - productionMode = true; - } - - if (!productionMode) { - /* Print an information/warning message about running in debug mode */ - getLogger().warning(NOT_PRODUCTION_MODE_INFO); - } - - } - - private void checkResourceCacheTime() { - // Check if the browser caching time has been set in web.xml - try { - String rct = getDeploymentConfiguration() - .getApplicationOrSystemProperty( - SERVLET_PARAMETER_RESOURCE_CACHE_TIME, "3600"); - resourceCacheTime = Integer.parseInt(rct); - } catch (NumberFormatException nfe) { - // Default is 1h - resourceCacheTime = 3600; - getLogger().warning(WARNING_RESOURCE_CACHING_TIME_NOT_NUMERIC); - } - } - /** * Returns true if the servlet is running in production mode. Production * mode disables all debug facilities. @@ -238,17 +189,17 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * @return true if in production mode, false if in debug mode */ public boolean isProductionMode() { - return productionMode; + return getDeploymentConfiguration().isProductionMode(); } /** - * Returns the amount of milliseconds the browser should cache a file. - * Default is 1 hour (3600 ms). + * Returns the number of seconds the browser should cache a file. Default is + * 1 hour (3600 s). * - * @return The amount of milliseconds files are cached in the browser + * @return The number of seconds files are cached in the browser */ public int getResourceCacheTime() { - return resourceCacheTime; + return getDeploymentConfiguration().getResourceCacheTime(); } /** @@ -909,8 +860,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements Locale locale = request.getLocale(); application.setLocale(locale); application.start(new ApplicationStartEvent(applicationUrl, - getDeploymentConfiguration().getInitParameters(), - webApplicationContext, isProductionMode())); + getDeploymentConfiguration(), webApplicationContext)); addonContext.fireApplicationStarted(application); } } @@ -1056,7 +1006,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * parameter in web.xml */ response.setHeader("Cache-Control", - "max-age= " + String.valueOf(resourceCacheTime)); + "max-age= " + String.valueOf(getResourceCacheTime())); } // Write the resource to the client. diff --git a/server/src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java b/server/src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java index 33e1c43b38..a8e4cdfaca 100644 --- a/server/src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java +++ b/server/src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java @@ -20,6 +20,7 @@ import java.lang.reflect.Constructor; import java.util.Iterator; import java.util.Properties; import java.util.ServiceLoader; +import java.util.logging.Logger; import com.vaadin.terminal.DeploymentConfiguration; @@ -29,9 +30,16 @@ public abstract class AbstractDeploymentConfiguration implements private final Class<?> systemPropertyBaseClass; private final Properties applicationProperties = new Properties(); private AddonContext addonContext; + private boolean productionMode; + private boolean xsrfProtectionEnabled; + private int resourceCacheTime; public AbstractDeploymentConfiguration(Class<?> systemPropertyBaseClass) { this.systemPropertyBaseClass = systemPropertyBaseClass; + + checkProductionMode(); + checkXsrfProtection(); + checkResourceCacheTime(); } @Override @@ -152,4 +160,63 @@ public abstract class AbstractDeploymentConfiguration implements public AddonContext getAddonContext() { return addonContext; } + + @Override + public boolean isProductionMode() { + return productionMode; + } + + @Override + public boolean isXsrfProtectionEnabled() { + return xsrfProtectionEnabled; + } + + @Override + public int getResourceCacheTime() { + return resourceCacheTime; + } + + /** + * Log a warning if Vaadin is not running in production mode. + */ + private void checkProductionMode() { + productionMode = getApplicationOrSystemProperty( + Constants.SERVLET_PARAMETER_PRODUCTION_MODE, "false").equals( + "true"); + if (!productionMode) { + getLogger().warning(Constants.NOT_PRODUCTION_MODE_INFO); + } + } + + /** + * Log a warning if cross-site request forgery protection is disabled. + */ + private void checkXsrfProtection() { + xsrfProtectionEnabled = getApplicationOrSystemProperty( + Constants.SERVLET_PARAMETER_DISABLE_XSRF_PROTECTION, "false") + .equals("true"); + if (!xsrfProtectionEnabled) { + getLogger().warning(Constants.WARNING_XSRF_PROTECTION_DISABLED); + } + } + + /** + * Log a warning if resource cache time is set but is not an integer. + */ + private void checkResourceCacheTime() { + try { + resourceCacheTime = Integer + .parseInt(getApplicationOrSystemProperty( + Constants.SERVLET_PARAMETER_RESOURCE_CACHE_TIME, + "3600")); + } catch (NumberFormatException e) { + getLogger().warning( + Constants.WARNING_RESOURCE_CACHING_TIME_NOT_NUMERIC); + resourceCacheTime = 3600; + } + } + + private Logger getLogger() { + return Logger.getLogger(getClass().getName()); + } } diff --git a/shared/src/com/vaadin/shared/ui/root/RootState.java b/shared/src/com/vaadin/shared/ui/root/RootState.java index b7c2c88ce5..07c71c8167 100644 --- a/shared/src/com/vaadin/shared/ui/root/RootState.java +++ b/shared/src/com/vaadin/shared/ui/root/RootState.java @@ -20,6 +20,7 @@ import com.vaadin.shared.Connector; public class RootState extends ComponentState { private Connector content; + private int heartbeatInterval; public Connector getContent() { return content; @@ -29,4 +30,11 @@ public class RootState extends ComponentState { this.content = content; } + public int getHeartbeatInterval() { + return heartbeatInterval; + } + + public void setHeartbeatInterval(int heartbeatInterval) { + this.heartbeatInterval = heartbeatInterval; + } }
\ No newline at end of file diff --git a/tests/sass/src/com/vaadin/sass/testcases/scss/Comments.java b/tests/sass/src/com/vaadin/sass/testcases/scss/Comments.java index ea893f96e0..c76bbb8458 100644 --- a/tests/sass/src/com/vaadin/sass/testcases/scss/Comments.java +++ b/tests/sass/src/com/vaadin/sass/testcases/scss/Comments.java @@ -21,9 +21,6 @@ import java.net.URISyntaxException; import junit.framework.Assert; -import org.junit.Test; -import org.w3c.css.sac.CSSException; - import com.vaadin.sass.AbstractTestBase; import com.vaadin.sass.ScssStylesheet; import com.vaadin.sass.handler.SCSSDocumentHandler; @@ -31,6 +28,9 @@ import com.vaadin.sass.handler.SCSSDocumentHandlerImpl; import com.vaadin.sass.parser.Parser; import com.vaadin.sass.tree.CommentNode; +import org.junit.Test; +import org.w3c.css.sac.CSSException; + public class Comments extends AbstractTestBase { String scss = "/scss/comments.scss"; String css = "/css/comments.css"; diff --git a/tests/server-side/com/vaadin/tests/server/TransactionListenersConcurrency.java b/tests/server-side/com/vaadin/tests/server/TransactionListenersConcurrency.java index b567617fdd..f7ac55b6da 100644 --- a/tests/server-side/com/vaadin/tests/server/TransactionListenersConcurrency.java +++ b/tests/server-side/com/vaadin/tests/server/TransactionListenersConcurrency.java @@ -17,14 +17,15 @@ import javax.servlet.http.HttpSession; import junit.framework.TestCase; -import org.easymock.EasyMock; - import com.vaadin.Application; import com.vaadin.Application.ApplicationStartEvent; import com.vaadin.service.ApplicationContext.TransactionListener; +import com.vaadin.terminal.DeploymentConfiguration; import com.vaadin.terminal.gwt.server.AbstractWebApplicationContext; import com.vaadin.terminal.gwt.server.WebApplicationContext; +import org.easymock.EasyMock; + public class TransactionListenersConcurrency extends TestCase { /** @@ -71,10 +72,15 @@ public class TransactionListenersConcurrency extends TestCase { // Start the application so the transaction listener is // called later on. try { + DeploymentConfiguration dc = EasyMock + .createMock(DeploymentConfiguration.class); + EasyMock.expect(dc.isProductionMode()).andReturn(true); + EasyMock.expect(dc.getInitParameters()).andReturn( + new Properties()); + EasyMock.replay(dc); app.start(new ApplicationStartEvent(new URL( - "http://localhost/"), new Properties(), - context, true)); + "http://localhost/"), dc, context)); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -101,7 +107,9 @@ public class TransactionListenersConcurrency extends TestCase { @Override public void uncaughtException(Thread t, Throwable e) { - e = e.getCause(); + if (e.getCause() != null) { + e = e.getCause(); + } exceptions.add(e); } }); @@ -127,8 +135,10 @@ public class TransactionListenersConcurrency extends TestCase { if (t instanceof InvocationTargetException) { t = t.getCause(); } - t.printStackTrace(System.err); - fail(t.getClass().getName()); + if (t != null) { + t.printStackTrace(System.err); + fail(t.getClass().getName()); + } } System.out.println("Done, all ok"); diff --git a/tests/server-side/com/vaadin/tests/server/component/root/CustomRootClassLoader.java b/tests/server-side/com/vaadin/tests/server/component/root/CustomRootClassLoader.java index aa9753ebcc..fa730515a2 100644 --- a/tests/server-side/com/vaadin/tests/server/component/root/CustomRootClassLoader.java +++ b/tests/server-side/com/vaadin/tests/server/component/root/CustomRootClassLoader.java @@ -6,8 +6,6 @@ import java.util.Properties; import junit.framework.TestCase; -import org.easymock.EasyMock; - import com.vaadin.Application; import com.vaadin.Application.ApplicationStartEvent; import com.vaadin.RootRequiresMoreInformationException; @@ -15,6 +13,8 @@ import com.vaadin.terminal.DeploymentConfiguration; import com.vaadin.terminal.WrappedRequest; import com.vaadin.ui.Root; +import org.easymock.EasyMock; + public class CustomRootClassLoader extends TestCase { /** @@ -52,13 +52,24 @@ public class CustomRootClassLoader extends TestCase { */ public void testWithNullClassLoader() throws Exception { Application application = createStubApplication(); - application.start(new ApplicationStartEvent(null, new Properties(), - null, false)); + application.start(new ApplicationStartEvent(null, + createConfigurationMock(), null)); Root root = application.getRootForRequest(createRequestMock(null)); assertTrue(root instanceof MyRoot); } + private static DeploymentConfiguration createConfigurationMock() { + DeploymentConfiguration configurationMock = EasyMock + .createMock(DeploymentConfiguration.class); + EasyMock.expect(configurationMock.isProductionMode()).andReturn(false); + EasyMock.expect(configurationMock.getInitParameters()).andReturn( + new Properties()); + + EasyMock.replay(configurationMock); + return configurationMock; + } + private static WrappedRequest createRequestMock(ClassLoader classloader) { // Mock a DeploymentConfiguration to give the passed classloader DeploymentConfiguration configurationMock = EasyMock @@ -86,8 +97,8 @@ public class CustomRootClassLoader extends TestCase { LoggingClassLoader loggingClassLoader = new LoggingClassLoader(); Application application = createStubApplication(); - application.start(new ApplicationStartEvent(null, new Properties(), - null, false)); + application.start(new ApplicationStartEvent(null, + createConfigurationMock(), null)); Root root = application .getRootForRequest(createRequestMock(loggingClassLoader)); |