From d1c361e251800c6f7d596ddf79ed1c7569196856 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Wed, 5 Sep 2012 19:04:20 +0300 Subject: Rename Application to VaadinSession (#9402) --- server/src/com/vaadin/Application.java | 1999 -------------------- server/src/com/vaadin/LegacyApplication.java | 27 +- .../vaadin/data/util/converter/ConverterUtil.java | 8 +- .../util/converter/DefaultConverterFactory.java | 4 +- .../com/vaadin/server/AbstractClientConnector.java | 3 +- .../server/AbstractCommunicationManager.java | 31 +- .../src/com/vaadin/server/AbstractUIProvider.java | 3 +- server/src/com/vaadin/server/AddonContext.java | 9 +- .../com/vaadin/server/ApplicationStartedEvent.java | 7 +- .../vaadin/server/ApplicationStartedListener.java | 5 +- .../vaadin/server/BootstrapFragmentResponse.java | 5 +- server/src/com/vaadin/server/BootstrapHandler.java | 11 +- .../com/vaadin/server/BootstrapPageResponse.java | 5 +- .../src/com/vaadin/server/BootstrapResponse.java | 7 +- server/src/com/vaadin/server/ClassResource.java | 3 +- server/src/com/vaadin/server/CombinedRequest.java | 3 +- .../com/vaadin/server/CommunicationManager.java | 11 +- .../vaadin/server/ConnectorResourceHandler.java | 5 +- .../src/com/vaadin/server/DefaultUIProvider.java | 5 +- server/src/com/vaadin/server/FileResource.java | 3 +- server/src/com/vaadin/server/GAEVaadinServlet.java | 9 +- .../com/vaadin/server/GlobalResourceHandler.java | 3 +- .../src/com/vaadin/server/LegacyVaadinPortlet.java | 7 +- .../src/com/vaadin/server/LegacyVaadinServlet.java | 7 +- .../vaadin/server/PortletApplicationContext2.java | 308 --- .../vaadin/server/PortletCommunicationManager.java | 7 +- server/src/com/vaadin/server/RequestHandler.java | 5 +- server/src/com/vaadin/server/RequestTimer.java | 3 +- .../vaadin/server/RestrictedRenderResponse.java | 2 +- .../vaadin/server/ServletApplicationContext.java | 101 - .../com/vaadin/server/ServletPortletHelper.java | 11 +- server/src/com/vaadin/server/StreamVariable.java | 3 +- server/src/com/vaadin/server/SystemMessages.java | 3 +- server/src/com/vaadin/server/UIProvider.java | 5 +- .../vaadin/server/UnsupportedBrowserHandler.java | 3 +- server/src/com/vaadin/server/VaadinPortlet.java | 35 +- .../com/vaadin/server/VaadinPortletSession.java | 307 +++ server/src/com/vaadin/server/VaadinServlet.java | 41 +- .../com/vaadin/server/VaadinServletSession.java | 100 + server/src/com/vaadin/server/VaadinSession.java | 1978 +++++++++++++++++++ .../vaadin/server/WrappedHttpServletRequest.java | 3 +- .../com/vaadin/server/WrappedPortletRequest.java | 3 +- server/src/com/vaadin/ui/AbstractComponent.java | 8 +- server/src/com/vaadin/ui/Component.java | 6 +- server/src/com/vaadin/ui/LoginForm.java | 4 +- server/src/com/vaadin/ui/UI.java | 28 +- .../tests/src/com/vaadin/tests/VaadinClasses.java | 4 +- .../tests/data/converter/ConverterFactory.java | 18 +- .../tests/server/TestStreamVariableMapping.java | 8 +- .../AbstractFieldValueConversions.java | 8 +- .../abstractfield/DefaultConverterFactory.java | 6 +- .../abstractfield/RemoveListenersOnDetach.java | 8 +- .../server/component/label/LabelConverters.java | 4 +- .../server/component/root/CustomUIClassLoader.java | 14 +- .../component/window/AttachDetachWindow.java | 6 +- .../vaadin/launcher/ApplicationRunnerServlet.java | 12 +- uitest/src/com/vaadin/tests/ModalWindow.java | 2 +- uitest/src/com/vaadin/tests/Parameters.java | 6 +- uitest/src/com/vaadin/tests/TestBench.java | 2 +- uitest/src/com/vaadin/tests/TreeFilesystem.java | 4 +- .../com/vaadin/tests/TreeFilesystemContainer.java | 4 +- .../tests/application/ThreadLocalInstances.java | 8 +- .../tests/applicationcontext/ChangeSessionId.java | 6 +- .../vaadin/tests/components/AbstractTestCase.java | 4 +- .../tests/components/AbstractTestUIProvider.java | 4 +- .../AbstractComponentDataBindingTest.java | 4 +- .../vaadin/tests/components/ui/LazyInitUIs.java | 10 +- .../tests/components/ui/UIsInMultipleTabs.java | 8 +- .../integration/JSR286PortletApplication.java | 8 +- .../v7a1/DifferentFeaturesForDifferentClients.java | 6 +- .../tests/minitutorials/v7a1/DynamicImageUI.java | 4 +- .../tests/minitutorials/v7a1/FindCurrentUI.java | 4 +- .../src/com/vaadin/tests/tickets/Ticket1589.java | 6 +- .../src/com/vaadin/tests/tickets/Ticket1921.java | 6 +- .../src/com/vaadin/tests/tickets/Ticket2292.java | 6 +- .../src/com/vaadin/tests/util/SampleDirectory.java | 4 +- 76 files changed, 2642 insertions(+), 2696 deletions(-) delete mode 100644 server/src/com/vaadin/Application.java delete mode 100644 server/src/com/vaadin/server/PortletApplicationContext2.java delete mode 100644 server/src/com/vaadin/server/ServletApplicationContext.java create mode 100644 server/src/com/vaadin/server/VaadinPortletSession.java create mode 100644 server/src/com/vaadin/server/VaadinServletSession.java create mode 100644 server/src/com/vaadin/server/VaadinSession.java diff --git a/server/src/com/vaadin/Application.java b/server/src/com/vaadin/Application.java deleted file mode 100644 index 6d37fbd5ae..0000000000 --- a/server/src/com/vaadin/Application.java +++ /dev/null @@ -1,1999 +0,0 @@ -/* - * Copyright 2011 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; - -import java.io.IOException; -import java.io.Serializable; -import java.lang.reflect.Method; -import java.net.SocketException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.EventObject; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; - -import com.vaadin.data.util.converter.Converter; -import com.vaadin.data.util.converter.ConverterFactory; -import com.vaadin.data.util.converter.DefaultConverterFactory; -import com.vaadin.event.EventRouter; -import com.vaadin.server.AbstractCommunicationManager; -import com.vaadin.server.AbstractErrorMessage; -import com.vaadin.server.ApplicationConfiguration; -import com.vaadin.server.BootstrapFragmentResponse; -import com.vaadin.server.BootstrapListener; -import com.vaadin.server.BootstrapPageResponse; -import com.vaadin.server.BootstrapResponse; -import com.vaadin.server.ChangeVariablesErrorEvent; -import com.vaadin.server.ClientConnector; -import com.vaadin.server.CombinedRequest; -import com.vaadin.server.DeploymentConfiguration; -import com.vaadin.server.GlobalResourceHandler; -import com.vaadin.server.RequestHandler; -import com.vaadin.server.Terminal; -import com.vaadin.server.UIProvider; -import com.vaadin.server.VaadinServlet; -import com.vaadin.server.VariableOwner; -import com.vaadin.server.WebBrowser; -import com.vaadin.server.WrappedRequest; -import com.vaadin.server.WrappedRequest.BrowserDetails; -import com.vaadin.server.WrappedResponse; -import com.vaadin.server.WrappedSession; -import com.vaadin.shared.ui.ui.UIConstants; -import com.vaadin.ui.AbstractComponent; -import com.vaadin.ui.AbstractField; -import com.vaadin.ui.Table; -import com.vaadin.ui.UI; -import com.vaadin.ui.Window; -import com.vaadin.util.CurrentInstance; -import com.vaadin.util.ReflectTools; - -/** - *

- * Base class required for all Vaadin applications. This class provides all the - * basic services required by Vaadin. These services allow external discovery - * and manipulation of the user, {@link com.vaadin.ui.Window windows} and - * themes, and starting and stopping the application. - *

- * - *

- * As mentioned, all Vaadin applications must inherit this class. However, this - * is almost all of what one needs to do to create a fully functional - * application. The only thing a class inheriting the Application - * needs to do is implement the init method where it creates the - * windows it needs to perform its function. Note that all applications must - * have at least one window: the main window. The first unnamed window - * constructed by an application automatically becomes the main window which - * behaves just like other windows with one exception: when accessing windows - * using URLs the main window corresponds to the application URL whereas other - * windows correspond to a URL gotten by catenating the window's name to the - * application URL. - *

- * - *

- * See the class com.vaadin.demo.HelloWorld for a simple example of - * a fully working application. - *

- * - *

- * Window access. Application provides methods to - * list, add and remove the windows it contains. - *

- * - *

- * Execution control. This class includes method to start and - * finish the execution of the application. Being finished means basically that - * no windows will be available from the application anymore. - *

- * - *

- * Theme selection. The theme selection process allows a theme - * to be specified at three different levels. When a window's theme needs to be - * found out, the window itself is queried for a preferred theme. If the window - * does not prefer a specific theme, the application containing the window is - * queried. If neither the application prefers a theme, the default theme for - * the {@link com.vaadin.server.Terminal terminal} is used. The terminal always - * defines a default theme. - *

- * - * @author Vaadin Ltd. - * @since 3.0 - */ -@SuppressWarnings("serial") -public class Application implements Terminal.ErrorListener, - HttpSessionBindingListener, Serializable { - - /** - * The name of the parameter that is by default used in e.g. web.xml to - * define the name of the default {@link UI} class. - */ - public static final String UI_PARAMETER = "UI"; - - private static final Method BOOTSTRAP_FRAGMENT_METHOD = ReflectTools - .findMethod(BootstrapListener.class, "modifyBootstrapFragment", - BootstrapFragmentResponse.class); - private static final Method BOOTSTRAP_PAGE_METHOD = ReflectTools - .findMethod(BootstrapListener.class, "modifyBootstrapPage", - BootstrapPageResponse.class); - - /** - * An event sent to {@link #start(ApplicationStartEvent)} when a new - * Application is being started. - * - * @since 7.0 - */ - public static class ApplicationStartEvent implements Serializable { - private final URL applicationUrl; - - private final ApplicationConfiguration configuration; - - private final AbstractCommunicationManager communicationManager; - - /** - * @param applicationUrl - * the URL the application should respond to. - * @param configuration - * the application configuration for the application. - * @param communicationManager - * the communication manager for the application. - */ - public ApplicationStartEvent(URL applicationUrl, - ApplicationConfiguration configuration, - AbstractCommunicationManager communicationManager) { - this.applicationUrl = applicationUrl; - this.configuration = configuration; - this.communicationManager = communicationManager; - } - - /** - * Gets the URL the application should respond to. - * - * @return the URL the application should respond to or - * null if the URL is not defined. - * - * @see Application#getURL() - */ - public URL getApplicationUrl() { - return applicationUrl; - } - - /** - * Returns the application configuration used by this application. - * - * @return the deployment configuration. - */ - public ApplicationConfiguration getConfiguration() { - return configuration; - } - - /** - * Gets the communication manager for this application. - * - * @return the communication manager for this application. - * - * @see Application#getCommunicationManager - */ - public AbstractCommunicationManager getCommunicationManager() { - return communicationManager; - } - } - - private final static Logger logger = Logger.getLogger(Application.class - .getName()); - - /** - * Configuration for the application. - */ - private ApplicationConfiguration configuration; - - /** - * The application's URL. - */ - private URL applicationUrl; - - /** - * Application status. - */ - private volatile boolean applicationIsRunning = false; - - /** - * Default locale of the application. - */ - private Locale locale; - - /** - * URL where the user is redirected to on application close, or null if - * application is just closed without redirection. - */ - private String logoutURL = null; - - /** - * Application wide error handler which is used by default if an error is - * left unhandled. - */ - private Terminal.ErrorListener errorHandler = this; - - /** - * The converter factory that is used to provide default converters for the - * application. - */ - private ConverterFactory converterFactory = new DefaultConverterFactory(); - - private LinkedList requestHandlers = new LinkedList(); - - private int nextUIId = 0; - private Map uIs = new HashMap(); - - private final Map retainOnRefreshUIs = new HashMap(); - - private final EventRouter eventRouter = new EventRouter(); - - private List uiProviders = new LinkedList(); - - private GlobalResourceHandler globalResourceHandler; - - protected WebBrowser browser = new WebBrowser(); - - private AbstractCommunicationManager communicationManager; - - private long totalSessionTime = 0; - - private long lastRequestTime = -1; - - private transient WrappedSession session; - - /** - * @see javax.servlet.http.HttpSessionBindingListener#valueBound(HttpSessionBindingEvent) - */ - @Override - public void valueBound(HttpSessionBindingEvent arg0) { - // We are not interested in bindings - } - - /** - * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(HttpSessionBindingEvent) - */ - @Override - public void valueUnbound(HttpSessionBindingEvent event) { - // If we are going to be unbound from the session, the session must be - // closing - close(); - } - - /** - * Get the web browser associated with this application context. - * - * Because application context is related to the http session and server - * maintains one session per browser-instance, each context has exactly one - * web browser associated with it. - * - * @return - */ - public WebBrowser getBrowser() { - return browser; - } - - /** - * @return The total time spent servicing requests in this session. - */ - public long getTotalSessionTime() { - return totalSessionTime; - } - - /** - * Sets the time spent servicing the last request in the session and updates - * the total time spent servicing requests in this session. - * - * @param time - * the time spent in the last request. - */ - public void setLastRequestTime(long time) { - lastRequestTime = time; - totalSessionTime += time; - } - - /** - * @return the time spent servicing the last request in this session. - */ - public long getLastRequestTime() { - return lastRequestTime; - } - - /** - * Gets the session to which this application context is currently - * associated. - * - * @return the wrapped session for this context - */ - public WrappedSession getSession() { - return session; - } - - public AbstractCommunicationManager getApplicationManager() { - return communicationManager; - } - - /** - * Gets the URL of the application. - * - *

- * This is the URL what can be entered to a browser window to start the - * application. Navigating to the application URL shows the main window ( - * {@link #getMainWindow()}) of the application. Note that the main window - * can also be shown by navigating to the window url ( - * {@link com.vaadin.ui.Window#getURL()}). - *

- * - * @return the application's URL. - */ - public URL getURL() { - return applicationUrl; - } - - /** - * Ends the Application. - *

- * In effect this will cause the application stop returning any windows when - * asked. When the application is closed, close events are fired for its - * UIs, its state is removed from the session, and the browser window is - * redirected to the application logout url set with - * {@link #setLogoutURL(String)}. If the logout url has not been set, the - * browser window is reloaded and the application is restarted. - */ - public void close() { - applicationIsRunning = false; - for (UI ui : getUIs()) { - ui.fireCloseEvent(); - } - } - - public static Application getForSession(WrappedSession session) { - Object attribute = session.getAttribute(Application.class.getName()); - if (attribute instanceof Application) { - Application application = (Application) attribute; - application.session = session; - return application; - } - - return null; - } - - public void removeFromSession() { - assert (getForSession(session) == this); - - session.setAttribute(Application.class.getName(), null); - } - - public void storeInSession(WrappedSession session) { - session.setAttribute(Application.class.getName(), this); - this.session = session; - } - - /** - * Starts the application on the given URL. - * - *

- * This method is called by Vaadin framework when a user navigates to the - * application. After this call the application corresponds to the given URL - * and it will return windows when asked for them. There is no need to call - * this method directly. - *

- * - *

- * Application properties are defined by servlet configuration object - * {@link javax.servlet.ServletConfig} and they are overridden by - * context-wide initialization parameters - * {@link javax.servlet.ServletContext}. - *

- * - * @param event - * the application start event containing details required for - * starting the application. - * - */ - public void start(ApplicationStartEvent event) { - applicationUrl = event.getApplicationUrl(); - configuration = event.getConfiguration(); - communicationManager = event.getCommunicationManager(); - applicationIsRunning = true; - } - - /** - * Tests if the application is running or if it has been finished. - * - *

- * Application starts running when its {@link #start(ApplicationStartEvent)} - * method has been called and stops when the {@link #close()} is called. - *

- * - * @return true if the application is running, - * false if not. - */ - public boolean isRunning() { - return applicationIsRunning; - } - - /** - * Gets the configuration for this application - * - * @return the application configuration - */ - public ApplicationConfiguration getConfiguration() { - return configuration; - } - - /** - * Gets the default locale for this application. - * - * By default this is the preferred locale of the user using the - * application. In most cases it is read from the browser defaults. - * - * @return the locale of this application. - */ - public Locale getLocale() { - if (locale != null) { - return locale; - } - return Locale.getDefault(); - } - - /** - * Sets the default locale for this application. - * - * By default this is the preferred locale of the user using the - * application. In most cases it is read from the browser defaults. - * - * @param locale - * the Locale object. - * - */ - public void setLocale(Locale locale) { - this.locale = locale; - } - - /** - * Window detach event. - * - * This event is sent each time a window is removed from the application - * with {@link com.vaadin.Application#removeWindow(Window)}. - */ - public static class WindowDetachEvent extends EventObject { - - private final Window window; - - /** - * Creates a event. - * - * @param application - * the application to which the detached window belonged. - * @param window - * the Detached window. - */ - public WindowDetachEvent(Application application, Window window) { - super(application); - this.window = window; - } - - /** - * Gets the detached window. - * - * @return the detached window. - */ - public Window getWindow() { - return window; - } - - /** - * Gets the application from which the window was detached. - * - * @return the Application. - */ - public Application getApplication() { - return (Application) getSource(); - } - } - - /** - * Window attach event. - * - * This event is sent each time a window is attached tothe application with - * {@link com.vaadin.Application#addWindow(Window)}. - */ - public static class WindowAttachEvent extends EventObject { - - private final Window window; - - /** - * Creates a event. - * - * @param application - * the application to which the detached window belonged. - * @param window - * the Attached window. - */ - public WindowAttachEvent(Application application, Window window) { - super(application); - this.window = window; - } - - /** - * Gets the attached window. - * - * @return the attached window. - */ - public Window getWindow() { - return window; - } - - /** - * Gets the application to which the window was attached. - * - * @return the Application. - */ - public Application getApplication() { - return (Application) getSource(); - } - } - - /** - * Window attach listener interface. - */ - public interface WindowAttachListener extends Serializable { - - /** - * Window attached - * - * @param event - * the window attach event. - */ - public void windowAttached(WindowAttachEvent event); - } - - /** - * Window detach listener interface. - */ - public interface WindowDetachListener extends Serializable { - - /** - * Window detached. - * - * @param event - * the window detach event. - */ - public void windowDetached(WindowDetachEvent event); - } - - /** - * Returns the URL user is redirected to on application close. If the URL is - * null, the application is closed normally as defined by the - * application running environment. - *

- * Desktop application just closes the application window and - * web-application redirects the browser to application main URL. - *

- * - * @return the URL. - */ - public String getLogoutURL() { - return logoutURL; - } - - /** - * Sets the URL user is redirected to on application close. If the URL is - * null, the application is closed normally as defined by the - * application running environment: Desktop application just closes the - * application window and web-application redirects the browser to - * application main URL. - * - * @param logoutURL - * the logoutURL to set. - */ - public void setLogoutURL(String logoutURL) { - this.logoutURL = logoutURL; - } - - /** - *

- * Invoked by the terminal on any exception that occurs in application and - * is thrown by the setVariable to the terminal. The default - * implementation sets the exceptions as ComponentErrors to the - * component that initiated the exception and prints stack trace to standard - * error stream. - *

- *

- * You can safely override this method in your application in order to - * direct the errors to some other destination (for example log). - *

- * - * @param event - * the change event. - * @see com.vaadin.server.Terminal.ErrorListener#terminalError(com.vaadin.server.Terminal.ErrorEvent) - */ - - @Override - public void terminalError(Terminal.ErrorEvent event) { - final Throwable t = event.getThrowable(); - if (t instanceof SocketException) { - // Most likely client browser closed socket - getLogger().info( - "SocketException in CommunicationManager." - + " Most likely client (browser) closed socket."); - return; - } - - // Finds the original source of the error/exception - Object owner = null; - if (event instanceof VariableOwner.ErrorEvent) { - owner = ((VariableOwner.ErrorEvent) event).getVariableOwner(); - } else if (event instanceof ChangeVariablesErrorEvent) { - owner = ((ChangeVariablesErrorEvent) event).getComponent(); - } - - // Shows the error in AbstractComponent - if (owner instanceof AbstractComponent) { - ((AbstractComponent) owner).setComponentError(AbstractErrorMessage - .getErrorMessageForException(t)); - } - - // also print the error on console - getLogger().log(Level.SEVERE, "Terminal error:", t); - } - - /** - * Gets the application error handler. - * - * The default error handler is the application itself. - * - * @return Application error handler - */ - public Terminal.ErrorListener getErrorHandler() { - return errorHandler; - } - - /** - * Sets the application error handler. - * - * The default error handler is the application itself. By overriding this, - * you can redirect the error messages to your selected target (log for - * example). - * - * @param errorHandler - */ - public void setErrorHandler(Terminal.ErrorListener errorHandler) { - this.errorHandler = errorHandler; - } - - /** - * Gets the {@link ConverterFactory} used to locate a suitable - * {@link Converter} for fields in the application. - * - * See {@link #setConverterFactory(ConverterFactory)} for more details - * - * @return The converter factory used in the application - */ - public ConverterFactory getConverterFactory() { - return converterFactory; - } - - /** - * Sets the {@link ConverterFactory} used to locate a suitable - * {@link Converter} for fields in the application. - *

- * The {@link ConverterFactory} is used to find a suitable converter when - * binding data to a UI component and the data type does not match the UI - * component type, e.g. binding a Double to a TextField (which is based on a - * String). - *

- *

- * The {@link Converter} for an individual field can be overridden using - * {@link AbstractField#setConverter(Converter)} and for individual property - * ids in a {@link Table} using - * {@link Table#setConverter(Object, Converter)}. - *

- *

- * The converter factory must never be set to null. - * - * @param converterFactory - * The converter factory used in the application - */ - public void setConverterFactory(ConverterFactory converterFactory) { - this.converterFactory = converterFactory; - } - - /** - * Contains the system messages used to notify the user about various - * critical situations that can occur. - *

- * Customize by overriding the static - * {@link Application#getSystemMessages()} and returning - * {@link CustomizedSystemMessages}. - *

- *

- * The defaults defined in this class are: - *

    - *
  • sessionExpiredURL = null
  • - *
  • sessionExpiredNotificationEnabled = true
  • - *
  • sessionExpiredCaption = ""
  • - *
  • sessionExpiredMessage = - * "Take note of any unsaved data, and click here to continue."
  • - *
  • communicationErrorURL = null
  • - *
  • communicationErrorNotificationEnabled = true
  • - *
  • communicationErrorCaption = "Communication problem"
  • - *
  • communicationErrorMessage = - * "Take note of any unsaved data, and click here to continue."
  • - *
  • internalErrorURL = null
  • - *
  • internalErrorNotificationEnabled = true
  • - *
  • internalErrorCaption = "Internal error"
  • - *
  • internalErrorMessage = "Please notify the administrator.
    - * Take note of any unsaved data, and click here to continue."
  • - *
  • outOfSyncURL = null
  • - *
  • outOfSyncNotificationEnabled = true
  • - *
  • outOfSyncCaption = "Out of sync"
  • - *
  • outOfSyncMessage = "Something has caused us to be out of sync - * with the server.
    - * Take note of any unsaved data, and click here to re-sync."
  • - *
  • cookiesDisabledURL = null
  • - *
  • cookiesDisabledNotificationEnabled = true
  • - *
  • cookiesDisabledCaption = "Cookies disabled"
  • - *
  • cookiesDisabledMessage = "This application requires cookies to - * function.
    - * Please enable cookies in your browser and click here to try again. - *
  • - *
- *

- * - */ - public static class SystemMessages implements Serializable { - protected String sessionExpiredURL = null; - protected boolean sessionExpiredNotificationEnabled = true; - protected String sessionExpiredCaption = "Session Expired"; - protected String sessionExpiredMessage = "Take note of any unsaved data, and click here to continue."; - - protected String communicationErrorURL = null; - protected boolean communicationErrorNotificationEnabled = true; - protected String communicationErrorCaption = "Communication problem"; - protected String communicationErrorMessage = "Take note of any unsaved data, and click here to continue."; - - protected String authenticationErrorURL = null; - protected boolean authenticationErrorNotificationEnabled = true; - protected String authenticationErrorCaption = "Authentication problem"; - protected String authenticationErrorMessage = "Take note of any unsaved data, and click here to continue."; - - protected String internalErrorURL = null; - protected boolean internalErrorNotificationEnabled = true; - protected String internalErrorCaption = "Internal error"; - protected String internalErrorMessage = "Please notify the administrator.
Take note of any unsaved data, and click here to continue."; - - protected String outOfSyncURL = null; - protected boolean outOfSyncNotificationEnabled = true; - protected String outOfSyncCaption = "Out of sync"; - protected String outOfSyncMessage = "Something has caused us to be out of sync with the server.
Take note of any unsaved data, and click here to re-sync."; - - protected String cookiesDisabledURL = null; - protected boolean cookiesDisabledNotificationEnabled = true; - protected String cookiesDisabledCaption = "Cookies disabled"; - protected String cookiesDisabledMessage = "This application requires cookies to function.
Please enable cookies in your browser and click here to try again."; - - /** - * Use {@link CustomizedSystemMessages} to customize - */ - private SystemMessages() { - - } - - /** - * @return null to indicate that the application will be restarted after - * session expired message has been shown. - */ - public String getSessionExpiredURL() { - return sessionExpiredURL; - } - - /** - * @return true to show session expiration message. - */ - public boolean isSessionExpiredNotificationEnabled() { - return sessionExpiredNotificationEnabled; - } - - /** - * @return "" to show no caption. - */ - public String getSessionExpiredCaption() { - return (sessionExpiredNotificationEnabled ? sessionExpiredCaption - : null); - } - - /** - * @return - * "Take note of any unsaved data, and click here to continue." - */ - public String getSessionExpiredMessage() { - return (sessionExpiredNotificationEnabled ? sessionExpiredMessage - : null); - } - - /** - * @return null to reload the application after communication error - * message. - */ - public String getCommunicationErrorURL() { - return communicationErrorURL; - } - - /** - * @return true to show the communication error message. - */ - public boolean isCommunicationErrorNotificationEnabled() { - return communicationErrorNotificationEnabled; - } - - /** - * @return "Communication problem" - */ - public String getCommunicationErrorCaption() { - return (communicationErrorNotificationEnabled ? communicationErrorCaption - : null); - } - - /** - * @return - * "Take note of any unsaved data, and click here to continue." - */ - public String getCommunicationErrorMessage() { - return (communicationErrorNotificationEnabled ? communicationErrorMessage - : null); - } - - /** - * @return null to reload the application after authentication error - * message. - */ - public String getAuthenticationErrorURL() { - return authenticationErrorURL; - } - - /** - * @return true to show the authentication error message. - */ - public boolean isAuthenticationErrorNotificationEnabled() { - return authenticationErrorNotificationEnabled; - } - - /** - * @return "Authentication problem" - */ - public String getAuthenticationErrorCaption() { - return (authenticationErrorNotificationEnabled ? authenticationErrorCaption - : null); - } - - /** - * @return - * "Take note of any unsaved data, and click here to continue." - */ - public String getAuthenticationErrorMessage() { - return (authenticationErrorNotificationEnabled ? authenticationErrorMessage - : null); - } - - /** - * @return null to reload the current URL after internal error message - * has been shown. - */ - public String getInternalErrorURL() { - return internalErrorURL; - } - - /** - * @return true to enable showing of internal error message. - */ - public boolean isInternalErrorNotificationEnabled() { - return internalErrorNotificationEnabled; - } - - /** - * @return "Internal error" - */ - public String getInternalErrorCaption() { - return (internalErrorNotificationEnabled ? internalErrorCaption - : null); - } - - /** - * @return "Please notify the administrator.
- * Take note of any unsaved data, and click here to - * continue." - */ - public String getInternalErrorMessage() { - return (internalErrorNotificationEnabled ? internalErrorMessage - : null); - } - - /** - * @return null to reload the application after out of sync message. - */ - public String getOutOfSyncURL() { - return outOfSyncURL; - } - - /** - * @return true to enable showing out of sync message - */ - public boolean isOutOfSyncNotificationEnabled() { - return outOfSyncNotificationEnabled; - } - - /** - * @return "Out of sync" - */ - public String getOutOfSyncCaption() { - return (outOfSyncNotificationEnabled ? outOfSyncCaption : null); - } - - /** - * @return "Something has caused us to be out of sync with the server.
- * Take note of any unsaved data, and click here to - * re-sync." - */ - public String getOutOfSyncMessage() { - return (outOfSyncNotificationEnabled ? outOfSyncMessage : null); - } - - /** - * Returns the URL the user should be redirected to after dismissing the - * "you have to enable your cookies" message. Typically null. - * - * @return A URL the user should be redirected to after dismissing the - * message or null to reload the current URL. - */ - public String getCookiesDisabledURL() { - return cookiesDisabledURL; - } - - /** - * Determines if "cookies disabled" messages should be shown to the end - * user or not. If the notification is disabled the user will be - * immediately redirected to the URL returned by - * {@link #getCookiesDisabledURL()}. - * - * @return true to show "cookies disabled" messages to the end user, - * false to redirect to the given URL directly - */ - public boolean isCookiesDisabledNotificationEnabled() { - return cookiesDisabledNotificationEnabled; - } - - /** - * Returns the caption of the message shown to the user when cookies are - * disabled in the browser. - * - * @return The caption of the "cookies disabled" message - */ - public String getCookiesDisabledCaption() { - return (cookiesDisabledNotificationEnabled ? cookiesDisabledCaption - : null); - } - - /** - * Returns the message shown to the user when cookies are disabled in - * the browser. - * - * @return The "cookies disabled" message - */ - public String getCookiesDisabledMessage() { - return (cookiesDisabledNotificationEnabled ? cookiesDisabledMessage - : null); - } - - } - - /** - * Contains the system messages used to notify the user about various - * critical situations that can occur. - *

- * Vaadin gets the SystemMessages from your application by calling a static - * getSystemMessages() method. By default the - * Application.getSystemMessages() is used. You can customize this by - * defining a static MyApplication.getSystemMessages() and returning - * CustomizedSystemMessages. Note that getSystemMessages() is static - - * changing the system messages will by default change the message for all - * users of the application. - *

- *

- * The default behavior is to show a notification, and restart the - * application the the user clicks the message.
- * Instead of restarting the application, you can set a specific URL that - * the user is taken to.
- * Setting both caption and message to null will restart the application (or - * go to the specified URL) without displaying a notification. - * set*NotificationEnabled(false) will achieve the same thing. - *

- *

- * The situations are: - *

  • Session expired: the user session has expired, usually due to - * inactivity.
  • - *
  • Communication error: the client failed to contact the server, or the - * server returned and invalid response.
  • - *
  • Internal error: unhandled critical server error (e.g out of memory, - * database crash) - *
  • Out of sync: the client is not in sync with the server. E.g the user - * opens two windows showing the same application, but the application does - * not support this and uses the same Window instance. When the user makes - * changes in one of the windows - the other window is no longer in sync, - * and (for instance) pressing a button that is no longer present in the UI - * will cause a out-of-sync -situation. - *

    - */ - - public static class CustomizedSystemMessages extends SystemMessages - implements Serializable { - - /** - * Sets the URL to go to when the session has expired. - * - * @param sessionExpiredURL - * the URL to go to, or null to reload current - */ - public void setSessionExpiredURL(String sessionExpiredURL) { - this.sessionExpiredURL = sessionExpiredURL; - } - - /** - * Enables or disables the notification. If disabled, the set URL (or - * current) is loaded directly when next transaction between server and - * client happens. - * - * @param sessionExpiredNotificationEnabled - * true = enabled, false = disabled - */ - public void setSessionExpiredNotificationEnabled( - boolean sessionExpiredNotificationEnabled) { - this.sessionExpiredNotificationEnabled = sessionExpiredNotificationEnabled; - } - - /** - * Sets the caption of the notification. Set to null for no caption. If - * both caption and message are null, client automatically forwards to - * sessionExpiredUrl after timeout timer expires. Timer uses value read - * from HTTPSession.getMaxInactiveInterval() - * - * @param sessionExpiredCaption - * the caption - */ - public void setSessionExpiredCaption(String sessionExpiredCaption) { - this.sessionExpiredCaption = sessionExpiredCaption; - } - - /** - * Sets the message of the notification. Set to null for no message. If - * both caption and message are null, client automatically forwards to - * sessionExpiredUrl after timeout timer expires. Timer uses value read - * from HTTPSession.getMaxInactiveInterval() - * - * @param sessionExpiredMessage - * the message - */ - public void setSessionExpiredMessage(String sessionExpiredMessage) { - this.sessionExpiredMessage = sessionExpiredMessage; - } - - /** - * Sets the URL to go to when there is a authentication error. - * - * @param authenticationErrorURL - * the URL to go to, or null to reload current - */ - public void setAuthenticationErrorURL(String authenticationErrorURL) { - this.authenticationErrorURL = authenticationErrorURL; - } - - /** - * Enables or disables the notification. If disabled, the set URL (or - * current) is loaded directly. - * - * @param authenticationErrorNotificationEnabled - * true = enabled, false = disabled - */ - public void setAuthenticationErrorNotificationEnabled( - boolean authenticationErrorNotificationEnabled) { - this.authenticationErrorNotificationEnabled = authenticationErrorNotificationEnabled; - } - - /** - * Sets the caption of the notification. Set to null for no caption. If - * both caption and message is null, the notification is disabled; - * - * @param authenticationErrorCaption - * the caption - */ - public void setAuthenticationErrorCaption( - String authenticationErrorCaption) { - this.authenticationErrorCaption = authenticationErrorCaption; - } - - /** - * Sets the message of the notification. Set to null for no message. If - * both caption and message is null, the notification is disabled; - * - * @param authenticationErrorMessage - * the message - */ - public void setAuthenticationErrorMessage( - String authenticationErrorMessage) { - this.authenticationErrorMessage = authenticationErrorMessage; - } - - /** - * Sets the URL to go to when there is a communication error. - * - * @param communicationErrorURL - * the URL to go to, or null to reload current - */ - public void setCommunicationErrorURL(String communicationErrorURL) { - this.communicationErrorURL = communicationErrorURL; - } - - /** - * Enables or disables the notification. If disabled, the set URL (or - * current) is loaded directly. - * - * @param communicationErrorNotificationEnabled - * true = enabled, false = disabled - */ - public void setCommunicationErrorNotificationEnabled( - boolean communicationErrorNotificationEnabled) { - this.communicationErrorNotificationEnabled = communicationErrorNotificationEnabled; - } - - /** - * Sets the caption of the notification. Set to null for no caption. If - * both caption and message is null, the notification is disabled; - * - * @param communicationErrorCaption - * the caption - */ - public void setCommunicationErrorCaption( - String communicationErrorCaption) { - this.communicationErrorCaption = communicationErrorCaption; - } - - /** - * Sets the message of the notification. Set to null for no message. If - * both caption and message is null, the notification is disabled; - * - * @param communicationErrorMessage - * the message - */ - public void setCommunicationErrorMessage( - String communicationErrorMessage) { - this.communicationErrorMessage = communicationErrorMessage; - } - - /** - * Sets the URL to go to when an internal error occurs. - * - * @param internalErrorURL - * the URL to go to, or null to reload current - */ - public void setInternalErrorURL(String internalErrorURL) { - this.internalErrorURL = internalErrorURL; - } - - /** - * Enables or disables the notification. If disabled, the set URL (or - * current) is loaded directly. - * - * @param internalErrorNotificationEnabled - * true = enabled, false = disabled - */ - public void setInternalErrorNotificationEnabled( - boolean internalErrorNotificationEnabled) { - this.internalErrorNotificationEnabled = internalErrorNotificationEnabled; - } - - /** - * Sets the caption of the notification. Set to null for no caption. If - * both caption and message is null, the notification is disabled; - * - * @param internalErrorCaption - * the caption - */ - public void setInternalErrorCaption(String internalErrorCaption) { - this.internalErrorCaption = internalErrorCaption; - } - - /** - * Sets the message of the notification. Set to null for no message. If - * both caption and message is null, the notification is disabled; - * - * @param internalErrorMessage - * the message - */ - public void setInternalErrorMessage(String internalErrorMessage) { - this.internalErrorMessage = internalErrorMessage; - } - - /** - * Sets the URL to go to when the client is out-of-sync. - * - * @param outOfSyncURL - * the URL to go to, or null to reload current - */ - public void setOutOfSyncURL(String outOfSyncURL) { - this.outOfSyncURL = outOfSyncURL; - } - - /** - * Enables or disables the notification. If disabled, the set URL (or - * current) is loaded directly. - * - * @param outOfSyncNotificationEnabled - * true = enabled, false = disabled - */ - public void setOutOfSyncNotificationEnabled( - boolean outOfSyncNotificationEnabled) { - this.outOfSyncNotificationEnabled = outOfSyncNotificationEnabled; - } - - /** - * Sets the caption of the notification. Set to null for no caption. If - * both caption and message is null, the notification is disabled; - * - * @param outOfSyncCaption - * the caption - */ - public void setOutOfSyncCaption(String outOfSyncCaption) { - this.outOfSyncCaption = outOfSyncCaption; - } - - /** - * Sets the message of the notification. Set to null for no message. If - * both caption and message is null, the notification is disabled; - * - * @param outOfSyncMessage - * the message - */ - public void setOutOfSyncMessage(String outOfSyncMessage) { - this.outOfSyncMessage = outOfSyncMessage; - } - - /** - * Sets the URL to redirect to when the browser has cookies disabled. - * - * @param cookiesDisabledURL - * the URL to redirect to, or null to reload the current URL - */ - public void setCookiesDisabledURL(String cookiesDisabledURL) { - this.cookiesDisabledURL = cookiesDisabledURL; - } - - /** - * Enables or disables the notification for "cookies disabled" messages. - * If disabled, the URL returned by {@link #getCookiesDisabledURL()} is - * loaded directly. - * - * @param cookiesDisabledNotificationEnabled - * true to enable "cookies disabled" messages, false - * otherwise - */ - public void setCookiesDisabledNotificationEnabled( - boolean cookiesDisabledNotificationEnabled) { - this.cookiesDisabledNotificationEnabled = cookiesDisabledNotificationEnabled; - } - - /** - * Sets the caption of the "cookies disabled" notification. Set to null - * for no caption. If both caption and message is null, the notification - * is disabled. - * - * @param cookiesDisabledCaption - * the caption for the "cookies disabled" notification - */ - public void setCookiesDisabledCaption(String cookiesDisabledCaption) { - this.cookiesDisabledCaption = cookiesDisabledCaption; - } - - /** - * Sets the message of the "cookies disabled" notification. Set to null - * for no message. If both caption and message is null, the notification - * is disabled. - * - * @param cookiesDisabledMessage - * the message for the "cookies disabled" notification - */ - public void setCookiesDisabledMessage(String cookiesDisabledMessage) { - this.cookiesDisabledMessage = cookiesDisabledMessage; - } - - } - - /** - * Application error is an error message defined on the application level. - * - * When an error occurs on the application level, this error message type - * should be used. This indicates that the problem is caused by the - * application - not by the user. - */ - public class ApplicationError implements Terminal.ErrorEvent { - private final Throwable throwable; - - public ApplicationError(Throwable throwable) { - this.throwable = throwable; - } - - @Override - public Throwable getThrowable() { - return throwable; - } - - } - - /** - * Gets the UI class for a request for which no UI is already known. This - * method is called when the framework processes a request that does not - * originate from an existing UI instance. This typically happens when a - * host page is requested. - *

    - * Subclasses of Application may override this method to provide custom - * logic for choosing what kind of UI to use. - *

    - * The default implementation in {@link Application} uses the - * {@value #UI_PARAMETER} parameter from web.xml for finding the name of the - * UI class. If {@link DeploymentConfiguration#getClassLoader()} does not - * return null, the returned {@link ClassLoader} is used for - * loading the UI class. Otherwise the {@link ClassLoader} used to load this - * class is used. - * - *

    - * - * @param request - * the wrapped request for which a UI is needed - * @return a UI instance to use for the request - * - * @see UI - * @see WrappedRequest#getBrowserDetails() - * - * @since 7.0 - */ - public Class getUIClass(WrappedRequest request) { - UIProvider uiProvider = getUiProvider(request, null); - return uiProvider.getUIClass(this, request); - } - - /** - * Creates an UI instance for a request for which no UI is already known. - * This method is called when the framework processes a request that does - * not originate from an existing UI instance. This typically happens when a - * host page is requested. - *

    - * Subclasses of Application may override this method to provide custom - * logic for choosing how to create a suitable UI or for picking an already - * created UI. If an existing UI is picked, care should be taken to avoid - * keeping the same UI open in multiple browser windows, as that will cause - * the states to go out of sync. - *

    - * - * @param request - * @param uiClass - * @return - */ - protected T createUIInstance(WrappedRequest request, - Class uiClass) { - UIProvider uiProvider = getUiProvider(request, uiClass); - return uiClass.cast(uiProvider.createInstance(this, uiClass, request)); - } - - /** - * Gets the {@link UIProvider} that should be used for a request. The - * selection can further be restricted by also requiring the UI provider to - * support a specific UI class. - * - * @see UIProvider - * @see #addUIProvider(UIProvider) - * - * @param request - * the request for which to get an UI provider - * @param uiClass - * the UI class for which a provider is required, or - * null to use the first UI provider supporting the - * request. - * @return an UI provider supporting the request (and the UI class if - * provided). - * - * @since 7.0.0 - */ - public UIProvider getUiProvider(WrappedRequest request, Class uiClass) { - UIProvider provider = (UIProvider) request - .getAttribute(UIProvider.class.getName()); - if (provider != null) { - // Cached provider found, verify that it's a sensible selection - Class providerClass = provider.getUIClass(this, - request); - if (uiClass == null && providerClass != null) { - // Use it if it gives any answer if no specific class is - // required - return provider; - } else if (uiClass == providerClass) { - // Use it if it gives the expected UI class - return provider; - } else { - // Don't keep it cached if it doesn't match the expectations - request.setAttribute(UIProvider.class.getName(), null); - } - } - - // Iterate all current providers if no matching cached provider found - provider = doGetUiProvider(request, uiClass); - - // Cache the found provider - request.setAttribute(UIProvider.class.getName(), provider); - - return provider; - } - - private UIProvider doGetUiProvider(WrappedRequest request, Class uiClass) { - int providersSize = uiProviders.size(); - if (providersSize == 0) { - throw new IllegalStateException("There are no UI providers"); - } - - for (int i = providersSize - 1; i >= 0; i--) { - UIProvider provider = uiProviders.get(i); - - Class providerClass = provider.getUIClass(this, - request); - // If we found something - if (providerClass != null) { - if (uiClass == null) { - // Not looking for anything particular -> anything is ok - return provider; - } else if (providerClass == uiClass) { - // Looking for a specific provider -> only use if matching - return provider; - } else { - getLogger().warning( - "Mismatching UI classes. Expected " + uiClass - + " but got " + providerClass + " from " - + provider); - // Continue looking - } - } - } - - throw new RuntimeException("No UI provider found for request"); - } - - /** - * Handles a request by passing it to each registered {@link RequestHandler} - * in turn until one produces a response. This method is used for requests - * that have not been handled by any specific functionality in the terminal - * implementation (e.g. {@link VaadinServlet}). - *

    - * The request handlers are invoked in the revere order in which they were - * added to the application until a response has been produced. This means - * that the most recently added handler is used first and the first request - * handler that was added to the application is invoked towards the end - * unless any previous handler has already produced a response. - *

    - * - * @param request - * the wrapped request to get information from - * @param response - * the response to which data can be written - * @return returns true if a {@link RequestHandler} has - * produced a response and false if no response has - * been written. - * @throws IOException - * - * @see #addRequestHandler(RequestHandler) - * @see RequestHandler - * - * @since 7.0 - */ - public boolean handleRequest(WrappedRequest request, - WrappedResponse response) throws IOException { - // Use a copy to avoid ConcurrentModificationException - for (RequestHandler handler : new ArrayList( - requestHandlers)) { - if (handler.handleRequest(this, request, response)) { - return true; - } - } - // If not handled - return false; - } - - /** - * Adds a request handler to this application. Request handlers can be added - * to provide responses to requests that are not handled by the default - * functionality of the framework. - *

    - * Handlers are called in reverse order of addition, so the most recently - * added handler will be called first. - *

    - * - * @param handler - * the request handler to add - * - * @see #handleRequest(WrappedRequest, WrappedResponse) - * @see #removeRequestHandler(RequestHandler) - * - * @since 7.0 - */ - public void addRequestHandler(RequestHandler handler) { - requestHandlers.addFirst(handler); - } - - /** - * Removes a request handler from the application. - * - * @param handler - * the request handler to remove - * - * @since 7.0 - */ - public void removeRequestHandler(RequestHandler handler) { - requestHandlers.remove(handler); - } - - /** - * Gets the request handlers that are registered to the application. The - * iteration order of the returned collection is the same as the order in - * which the request handlers will be invoked when a request is handled. - * - * @return a collection of request handlers, with the iteration order - * according to the order they would be invoked - * - * @see #handleRequest(WrappedRequest, WrappedResponse) - * @see #addRequestHandler(RequestHandler) - * @see #removeRequestHandler(RequestHandler) - * - * @since 7.0 - */ - public Collection getRequestHandlers() { - return Collections.unmodifiableCollection(requestHandlers); - } - - /** - * Gets the currently used application. The current application is - * automatically defined when processing requests to the server. In other - * cases, (e.g. from background threads), the current application is not - * automatically defined. - * - * @return the current application instance if available, otherwise - * null - * - * @see #setCurrent(Application) - * - * @since 7.0 - */ - public static Application getCurrent() { - return CurrentInstance.get(Application.class); - } - - /** - * Sets the thread local for the current application. This method is used by - * the framework to set the current application whenever a new request is - * processed and it is cleared when the request has been processed. - *

    - * The application developer can also use this method to define the current - * application outside the normal request handling, e.g. when initiating - * custom background threads. - *

    - * - * @param application - * - * @see #getCurrent() - * @see ThreadLocal - * - * @since 7.0 - */ - public static void setCurrent(Application application) { - CurrentInstance.setInheritable(Application.class, application); - } - - /** - * Check whether this application is in production mode. If an application - * is in production mode, certain debugging facilities are not available. - * - * @return the status of the production mode flag - * - * @since 7.0 - */ - public boolean isProductionMode() { - return configuration.isProductionMode(); - } - - public void addUIProvider(UIProvider uIProvider) { - uiProviders.add(uIProvider); - } - - public void removeUIProvider(UIProvider uIProvider) { - uiProviders.remove(uIProvider); - } - - /** - * Finds the {@link UI} to which a particular request belongs. If the - * request originates from an existing UI, that UI is returned. In other - * cases, the method attempts to create and initialize a new UI and might - * throw a {@link UIRequiresMoreInformationException} if all required - * information is not available. - *

    - * Please note that this method can also return a newly created - * UI which has not yet been initialized. You can use - * {@link #isUIInitPending(int)} with the UI's id ( {@link UI#getUIId()} to - * check whether the initialization is still pending. - *

    - * - * @param request - * the request for which a UI is desired - * @return a UI belonging to the request - * - * @see #createUI(WrappedRequest) - * - * @since 7.0 - */ - public UI getUIForRequest(WrappedRequest request) { - UI uI = UI.getCurrent(); - if (uI != null) { - return uI; - } - Integer uiId = getUIId(request); - - synchronized (this) { - uI = uIs.get(uiId); - - if (uI == null) { - uI = findExistingUi(request); - } - - } // end synchronized block - - UI.setCurrent(uI); - - return uI; - } - - private UI findExistingUi(WrappedRequest request) { - // Check if some UI provider has an existing UI available - for (int i = uiProviders.size() - 1; i >= 0; i--) { - UIProvider provider = uiProviders.get(i); - UI existingUi = provider.getExistingUI(request); - if (existingUi != null) { - return existingUi; - } - } - - BrowserDetails browserDetails = request.getBrowserDetails(); - boolean hasBrowserDetails = browserDetails != null - && browserDetails.getUriFragment() != null; - - if (hasBrowserDetails && !retainOnRefreshUIs.isEmpty()) { - // Check for a known UI - - @SuppressWarnings("null") - String windowName = browserDetails.getWindowName(); - Integer retainedUIId = retainOnRefreshUIs.get(windowName); - - if (retainedUIId != null) { - Class expectedUIClass = getUIClass(request); - UI retainedUI = uIs.get(retainedUIId); - // We've had the same UI instance in a window with this - // name, but should we still use it? - if (retainedUI.getClass() == expectedUIClass) { - return retainedUI; - } else { - getLogger().info( - "Not using retained UI in " + windowName - + " because retained UI was of type " - + retainedUIId.getClass() + " but " - + expectedUIClass - + " is expected for the request."); - } - } - } - - return null; - } - - public UI createUI(WrappedRequest request) { - Class uiClass = getUIClass(request); - - UI ui = createUIInstance(request, uiClass); - - // Initialize some fields for a newly created UI - if (ui.getApplication() == null) { - ui.setApplication(this); - } - // Get the next id - Integer uiId = Integer.valueOf(nextUIId++); - - uIs.put(uiId, ui); - - // Set thread local here so it is available in init - UI.setCurrent(ui); - - ui.doInit(request, uiId.intValue()); - - if (getUiProvider(request, uiClass).isUiPreserved(request, uiClass)) { - // Remember this UI - String windowName = request.getBrowserDetails().getWindowName(); - if (windowName == null) { - getLogger().warning( - "There is no window.name available for UI " + uiClass - + " that should be preserved."); - } else { - retainOnRefreshUIs.put(windowName, uiId); - } - } - - return ui; - } - - /** - * Internal helper to finds the UI id for a request. - * - * @param request - * the request to get the UI id for - * @return a UI id, or null if no UI id is defined - * - * @since 7.0 - */ - private static Integer getUIId(WrappedRequest request) { - if (request instanceof CombinedRequest) { - // Combined requests has the uiId parameter in the second request - CombinedRequest combinedRequest = (CombinedRequest) request; - request = combinedRequest.getSecondRequest(); - } - String uiIdString = request.getParameter(UIConstants.UI_ID_PARAMETER); - Integer uiId = uiIdString == null ? null : new Integer(uiIdString); - return uiId; - } - - /** - * Gets all the uIs of this application. This includes uIs that have been - * requested but not yet initialized. Please note, that uIs are not - * automatically removed e.g. if the browser window is closed and that there - * is no way to manually remove a UI. Inactive uIs will thus not be released - * for GC until the entire application is released when the session has - * timed out (unless there are dangling references). Improved support for - * releasing unused uIs is planned for an upcoming alpha release of Vaadin - * 7. - * - * @return a collection of uIs belonging to this application - * - * @since 7.0 - */ - public Collection getUIs() { - return Collections.unmodifiableCollection(uIs.values()); - } - - private int connectorIdSequence = 0; - - /** - * Generate an id for the given Connector. Connectors must not call this - * method more than once, the first time they need an id. - * - * @param connector - * A connector that has not yet been assigned an id. - * @return A new id for the connector - */ - public String createConnectorId(ClientConnector connector) { - return String.valueOf(connectorIdSequence++); - } - - private static final Logger getLogger() { - return Logger.getLogger(Application.class.getName()); - } - - /** - * Returns a UI with the given id. - *

    - * This is meant for framework internal use. - *

    - * - * @param uiId - * The UI id - * @return The UI with the given id or null if not found - */ - public UI getUIById(int uiId) { - return uIs.get(uiId); - } - - /** - * Adds a listener that will be invoked when the bootstrap HTML is about to - * be generated. This can be used to modify the contents of the HTML that - * loads the Vaadin application in the browser and the HTTP headers that are - * included in the response serving the HTML. - * - * @see BootstrapListener#modifyBootstrapFragment(BootstrapFragmentResponse) - * @see BootstrapListener#modifyBootstrapPage(BootstrapPageResponse) - * - * @param listener - * the bootstrap listener to add - */ - public void addBootstrapListener(BootstrapListener listener) { - eventRouter.addListener(BootstrapFragmentResponse.class, listener, - BOOTSTRAP_FRAGMENT_METHOD); - eventRouter.addListener(BootstrapPageResponse.class, listener, - BOOTSTRAP_PAGE_METHOD); - } - - /** - * Remove a bootstrap listener that was previously added. - * - * @see #addBootstrapListener(BootstrapListener) - * - * @param listener - * the bootstrap listener to remove - */ - public void removeBootstrapListener(BootstrapListener listener) { - eventRouter.removeListener(BootstrapFragmentResponse.class, listener, - BOOTSTRAP_FRAGMENT_METHOD); - eventRouter.removeListener(BootstrapPageResponse.class, listener, - BOOTSTRAP_PAGE_METHOD); - } - - /** - * Fires a bootstrap event to all registered listeners. There are currently - * two supported events, both inheriting from {@link BootstrapResponse}: - * {@link BootstrapFragmentResponse} and {@link BootstrapPageResponse}. - * - * @param response - * the bootstrap response event for which listeners should be - * fired - */ - public void modifyBootstrapResponse(BootstrapResponse response) { - eventRouter.fireEvent(response); - } - - /** - * Removes all those UIs from the application for which {@link #isUIAlive} - * returns false. Close events are fired for the removed UIs. - *

    - * Called by the framework at the end of every request. - * - * @see UI.CloseEvent - * @see UI.CloseListener - * @see #isUIAlive(UI) - * - * @since 7.0.0 - */ - public void closeInactiveUIs() { - for (Iterator i = uIs.values().iterator(); i.hasNext();) { - UI ui = i.next(); - if (!isUIAlive(ui)) { - i.remove(); - retainOnRefreshUIs.values().remove(ui.getUIId()); - ui.fireCloseEvent(); - getLogger().info( - "Closed UI #" + ui.getUIId() + " due to inactivity"); - } - } - } - - /** - * Returns the number of seconds that must pass without a valid heartbeat or - * UIDL request being received from a UI before that UI is removed from the - * application. This is a lower bound; it might take longer to close an - * inactive UI. Returns a negative number if heartbeat is disabled and - * timeout never occurs. - * - * @see #getUidlRequestTimeout() - * @see #closeInactiveUIs() - * @see DeploymentConfiguration#getHeartbeatInterval() - * - * @since 7.0.0 - * - * @return The heartbeat timeout in seconds or a negative number if timeout - * never occurs. - */ - protected int getHeartbeatTimeout() { - // Permit three missed heartbeats before closing the UI - return (int) (configuration.getHeartbeatInterval() * (3.1)); - } - - /** - * Returns the number of seconds that must pass without a valid UIDL request - * being received from a UI before the UI is removed from the application, - * even though heartbeat requests are received. This is a lower bound; it - * might take longer to close an inactive UI. Returns a negative number if - *

    - * This timeout only has effect if cleanup of inactive UIs is enabled; - * otherwise heartbeat requests are enough to extend UI lifetime - * indefinitely. - * - * @see DeploymentConfiguration#isIdleUICleanupEnabled() - * @see #getHeartbeatTimeout() - * @see #closeInactiveUIs() - * - * @since 7.0.0 - * - * @return The UIDL request timeout in seconds, or a negative number if - * timeout never occurs. - */ - protected int getUidlRequestTimeout() { - return configuration.isIdleUICleanupEnabled() ? getSession() - .getMaxInactiveInterval() : -1; - } - - /** - * Returns whether the given UI is alive (the client-side actively - * communicates with the server) or whether it can be removed from the - * application and eventually collected. - * - * @since 7.0.0 - * - * @param ui - * The UI whose status to check - * @return true if the UI is alive, false if it could be removed. - */ - protected boolean isUIAlive(UI ui) { - long now = System.currentTimeMillis(); - if (getHeartbeatTimeout() >= 0 - && now - ui.getLastHeartbeatTime() > 1000 * getHeartbeatTimeout()) { - return false; - } - if (getUidlRequestTimeout() >= 0 - && now - ui.getLastUidlRequestTime() > 1000 * getUidlRequestTimeout()) { - return false; - } - return true; - } - - /** - * Gets this application's global resource handler that takes care of - * serving connector resources that are not served by any single connector - * because e.g. because they are served with strong caching or because of - * legacy reasons. - * - * @param createOnDemand - * true if a resource handler should be initialized - * if there is no handler associated with this application. - * false if null should be returned - * if there is no registered handler. - * @return this application's global resource handler, or null - * if there is no handler and the createOnDemand parameter is - * false. - * - * @since 7.0.0 - */ - public GlobalResourceHandler getGlobalResourceHandler(boolean createOnDemand) { - if (globalResourceHandler == null && createOnDemand) { - globalResourceHandler = new GlobalResourceHandler(); - addRequestHandler(globalResourceHandler); - } - - return globalResourceHandler; - } - - public Collection getUIProviders() { - return Collections.unmodifiableCollection(uiProviders); - } - -} diff --git a/server/src/com/vaadin/LegacyApplication.java b/server/src/com/vaadin/LegacyApplication.java index b884136767..9f02a2d588 100644 --- a/server/src/com/vaadin/LegacyApplication.java +++ b/server/src/com/vaadin/LegacyApplication.java @@ -26,6 +26,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import com.vaadin.server.AbstractUIProvider; +import com.vaadin.server.VaadinSession; import com.vaadin.server.Terminal.ErrorEvent; import com.vaadin.server.Terminal.ErrorListener; import com.vaadin.server.WrappedRequest; @@ -68,8 +69,8 @@ public abstract class LegacyApplication extends AbstractUIProvider implements throw new IllegalStateException("mainWindow has already been set"); } if (mainWindow.getApplication() == null) { - mainWindow.setApplication(Application.getCurrent()); - } else if (mainWindow.getApplication() != Application.getCurrent()) { + mainWindow.setApplication(VaadinSession.getCurrent()); + } else if (mainWindow.getApplication() != VaadinSession.getCurrent()) { throw new IllegalStateException( "mainWindow is attached to another application"); } @@ -82,14 +83,14 @@ public abstract class LegacyApplication extends AbstractUIProvider implements } public void doInit() { - Application.getCurrent().setErrorHandler(this); + VaadinSession.getCurrent().setErrorHandler(this); init(); } protected abstract void init(); @Override - public Class getUIClass(Application application, + public Class getUIClass(VaadinSession application, WrappedRequest request) { UI uiInstance = getUIInstance(request); if (uiInstance != null) { @@ -99,7 +100,7 @@ public abstract class LegacyApplication extends AbstractUIProvider implements } @Override - public UI createInstance(Application application, Class type, + public UI createInstance(VaadinSession application, Class type, WrappedRequest request) { return getUIInstance(request); } @@ -179,7 +180,7 @@ public abstract class LegacyApplication extends AbstractUIProvider implements * Sets the application's theme. *

    * Note that this theme can be overridden for a specific UI with - * {@link Application#getThemeForUI(UI)}. Setting theme to be + * {@link VaadinSession#getThemeForUI(UI)}. Setting theme to be * null selects the default theme. For the available theme * names, see the contents of the VAADIN/themes directory. *

    @@ -241,7 +242,7 @@ public abstract class LegacyApplication extends AbstractUIProvider implements } legacyUINames.put(uI.getName(), uI); - uI.setApplication(Application.getCurrent()); + uI.setApplication(VaadinSession.getCurrent()); } /** @@ -280,22 +281,22 @@ public abstract class LegacyApplication extends AbstractUIProvider implements @Override public void terminalError(ErrorEvent event) { - Application.getCurrent().terminalError(event); + VaadinSession.getCurrent().terminalError(event); } - public Application getContext() { - return Application.getCurrent(); + public VaadinSession getContext() { + return VaadinSession.getCurrent(); } protected void close() { - Application.getCurrent().close(); + VaadinSession.getCurrent().close(); } public boolean isRunning() { - return Application.getCurrent().isRunning(); + return VaadinSession.getCurrent().isRunning(); } public URL getURL() { - return Application.getCurrent().getURL(); + return VaadinSession.getCurrent().getURL(); } } \ No newline at end of file diff --git a/server/src/com/vaadin/data/util/converter/ConverterUtil.java b/server/src/com/vaadin/data/util/converter/ConverterUtil.java index 36cd6d0859..a6014bb3eb 100644 --- a/server/src/com/vaadin/data/util/converter/ConverterUtil.java +++ b/server/src/com/vaadin/data/util/converter/ConverterUtil.java @@ -18,7 +18,7 @@ package com.vaadin.data.util.converter; import java.io.Serializable; import java.util.Locale; -import com.vaadin.Application; +import com.vaadin.server.VaadinSession; public class ConverterUtil implements Serializable { @@ -26,7 +26,7 @@ public class ConverterUtil implements Serializable { * Finds a converter that can convert from the given presentation type to * the given model type and back. Uses the given application to find a * {@link ConverterFactory} or, if application is null, uses the - * {@link Application#getCurrent()}. + * {@link VaadinSession#getCurrent()}. * * @param * The presentation type @@ -44,10 +44,10 @@ public class ConverterUtil implements Serializable { */ public static Converter getConverter( Class presentationType, - Class modelType, Application application) { + Class modelType, VaadinSession application) { Converter converter = null; if (application == null) { - application = Application.getCurrent(); + application = VaadinSession.getCurrent(); } if (application != null) { diff --git a/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java b/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java index ffd432076f..17b89ccb20 100644 --- a/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java +++ b/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java @@ -19,14 +19,14 @@ package com.vaadin.data.util.converter; import java.util.Date; import java.util.logging.Logger; -import com.vaadin.Application; +import com.vaadin.server.VaadinSession; /** * Default implementation of {@link ConverterFactory}. Provides converters for * standard types like {@link String}, {@link Double} and {@link Date}.

    *

    * Custom converters can be provided by extending this class and using - * {@link Application#setConverterFactory(ConverterFactory)}. + * {@link VaadinSession#setConverterFactory(ConverterFactory)}. *

    * * @author Vaadin Ltd diff --git a/server/src/com/vaadin/server/AbstractClientConnector.java b/server/src/com/vaadin/server/AbstractClientConnector.java index 09e366260b..82a154d4e5 100644 --- a/server/src/com/vaadin/server/AbstractClientConnector.java +++ b/server/src/com/vaadin/server/AbstractClientConnector.java @@ -31,7 +31,6 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.logging.Logger; -import com.vaadin.Application; import com.vaadin.external.json.JSONException; import com.vaadin.external.json.JSONObject; import com.vaadin.shared.communication.ClientRpc; @@ -358,7 +357,7 @@ public abstract class AbstractClientConnector implements ClientConnector { * * @return The connector's application, or null if not attached */ - protected Application getApplication() { + protected VaadinSession getApplication() { UI uI = getUI(); if (uI == null) { return null; diff --git a/server/src/com/vaadin/server/AbstractCommunicationManager.java b/server/src/com/vaadin/server/AbstractCommunicationManager.java index 47bf652a3a..71f5a07d77 100644 --- a/server/src/com/vaadin/server/AbstractCommunicationManager.java +++ b/server/src/com/vaadin/server/AbstractCommunicationManager.java @@ -56,7 +56,6 @@ import java.util.logging.Logger; import javax.servlet.http.HttpServletResponse; -import com.vaadin.Application; import com.vaadin.annotations.JavaScript; import com.vaadin.annotations.StyleSheet; import com.vaadin.external.json.JSONArray; @@ -143,7 +142,7 @@ public abstract class AbstractCommunicationManager implements Serializable { /** * The application this communication manager is used for */ - private final Application application; + private final VaadinSession application; private List locales; @@ -170,7 +169,7 @@ public abstract class AbstractCommunicationManager implements Serializable { * * @param application */ - public AbstractCommunicationManager(Application application) { + public AbstractCommunicationManager(VaadinSession application) { this.application = application; application.addRequestHandler(getBootstrapHandler()); application.addRequestHandler(UNSUPPORTED_BROWSER_HANDLER); @@ -178,7 +177,7 @@ public abstract class AbstractCommunicationManager implements Serializable { requireLocale(application.getLocale().toString()); } - protected Application getApplication() { + protected VaadinSession getApplication() { return application; } @@ -366,7 +365,7 @@ public abstract class AbstractCommunicationManager implements Serializable { "StreamVariable for the post not found"); } - final Application application = getApplication(); + final VaadinSession application = getApplication(); OutputStream out = null; int totalBytes = 0; @@ -491,7 +490,7 @@ public abstract class AbstractCommunicationManager implements Serializable { * Internally process a UIDL request from the client. * * This method calls - * {@link #handleVariables(WrappedRequest, WrappedResponse, Callback, Application, UI)} + * {@link #handleVariables(WrappedRequest, WrappedResponse, Callback, VaadinSession, UI)} * to process any changes to variables by the client and then repaints * affected components using {@link #paintAfterVariableChanges()}. * @@ -677,7 +676,7 @@ public abstract class AbstractCommunicationManager implements Serializable { } sb.append("\nComponent hierarchy:\n"); - Application application2 = component.getApplication(); + VaadinSession application2 = component.getApplication(); sb.append(application2.getClass().getName()); sb.append("."); sb.append(application2.getClass().getSimpleName()); @@ -790,7 +789,7 @@ public abstract class AbstractCommunicationManager implements Serializable { final PrintWriter outWriter, UI ui, boolean analyzeLayouts) throws PaintException, JSONException { ArrayList dirtyVisibleConnectors = new ArrayList(); - Application application = ui.getApplication(); + VaadinSession application = ui.getApplication(); // Paints components ConnectorTracker uiConnectorTracker = ui.getConnectorTracker(); getLogger().log(Level.FINE, "* Creating response to client"); @@ -1521,7 +1520,7 @@ public abstract class AbstractCommunicationManager implements Serializable { * @param application * @return false if the XSRF is turned off, true otherwise */ - public boolean isXSRFEnabled(Application application) { + public boolean isXSRFEnabled(VaadinSession application) { return application.getConfiguration().isXsrfProtectionEnabled(); } @@ -1536,7 +1535,7 @@ public abstract class AbstractCommunicationManager implements Serializable { */ private boolean handleVariables(WrappedRequest request, WrappedResponse response, Callback callback, - Application application2, UI uI) throws IOException, + VaadinSession application2, UI uI) throws IOException, InvalidUIDLSecurityKeyException, JSONException { boolean success = true; @@ -1943,7 +1942,7 @@ public abstract class AbstractCommunicationManager implements Serializable { * @param m * map from variable names to values */ - private void handleChangeVariablesError(Application application, + private void handleChangeVariablesError(VaadinSession application, Component owner, Throwable t, Map m) { boolean handled = false; ChangeVariablesErrorEvent errorEvent = new ChangeVariablesErrorEvent( @@ -2155,7 +2154,7 @@ public abstract class AbstractCommunicationManager implements Serializable { * Ends the Application. * * The browser is redirected to the Application logout URL set with - * {@link Application#setLogoutURL(String)}, or to the application URL if no + * {@link VaadinSession#setLogoutURL(String)}, or to the application URL if no * logout URL is given. * * @param request @@ -2168,7 +2167,7 @@ public abstract class AbstractCommunicationManager implements Serializable { * if the writing failed due to input/output error. */ private void endApplication(WrappedRequest request, - WrappedResponse response, Application application) + WrappedResponse response, VaadinSession application) throws IOException { String logoutUrl = application.getLogoutURL(); @@ -2394,7 +2393,7 @@ public abstract class AbstractCommunicationManager implements Serializable { } public void handleBrowserDetailsRequest(WrappedRequest request, - WrappedResponse response, Application application) + WrappedResponse response, VaadinSession application) throws IOException { assert UI.getCurrent() == null; @@ -2572,7 +2571,7 @@ public abstract class AbstractCommunicationManager implements Serializable { * @throws IOException * @throws InvalidUIDLSecurityKeyException */ - public void handleFileUpload(Application application, + public void handleFileUpload(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException, InvalidUIDLSecurityKeyException { @@ -2634,7 +2633,7 @@ public abstract class AbstractCommunicationManager implements Serializable { * @throws IOException */ public void handleHeartbeatRequest(WrappedRequest request, - WrappedResponse response, Application application) + WrappedResponse response, VaadinSession application) throws IOException { UI ui = null; try { diff --git a/server/src/com/vaadin/server/AbstractUIProvider.java b/server/src/com/vaadin/server/AbstractUIProvider.java index c7a137ebbd..ee8ebd2745 100644 --- a/server/src/com/vaadin/server/AbstractUIProvider.java +++ b/server/src/com/vaadin/server/AbstractUIProvider.java @@ -18,7 +18,6 @@ package com.vaadin.server; import java.lang.annotation.Annotation; -import com.vaadin.Application; import com.vaadin.annotations.PreserveOnRefresh; import com.vaadin.annotations.Theme; import com.vaadin.annotations.Title; @@ -28,7 +27,7 @@ import com.vaadin.ui.UI; public abstract class AbstractUIProvider implements UIProvider { @Override - public UI createInstance(Application application, Class type, + public UI createInstance(VaadinSession application, Class type, WrappedRequest request) { try { return type.newInstance(); diff --git a/server/src/com/vaadin/server/AddonContext.java b/server/src/com/vaadin/server/AddonContext.java index c9f2ac07eb..ca8c837a2e 100644 --- a/server/src/com/vaadin/server/AddonContext.java +++ b/server/src/com/vaadin/server/AddonContext.java @@ -22,7 +22,6 @@ import java.util.Iterator; import java.util.List; import java.util.ServiceLoader; -import com.vaadin.Application; import com.vaadin.event.EventRouter; import com.vaadin.util.ReflectTools; @@ -116,7 +115,7 @@ public class AddonContext { * application. * * @see #addApplicationStartedListener(ApplicationStartedListener) - * @see Application#addBootstrapListener(BootstrapListener) + * @see VaadinSession#addBootstrapListener(BootstrapListener) * * @param listener * the bootstrap listener that should be added to all new @@ -136,7 +135,7 @@ public class AddonContext { * @param application * the newly started application */ - public void fireApplicationStarted(Application application) { + public void fireApplicationStarted(VaadinSession application) { eventRouter.fireEvent(new ApplicationStartedEvent(this, application)); for (BootstrapListener l : bootstrapListeners) { application.addBootstrapListener(l); @@ -144,9 +143,9 @@ public class AddonContext { } /** - * Adds a listener that will be notified any time a new {@link Application} + * Adds a listener that will be notified any time a new {@link VaadinSession} * instance is started or more precisely directly after - * {@link Application#init()} has been invoked. + * {@link VaadinSession#init()} has been invoked. * * @param applicationStartListener * the application start listener that should be added diff --git a/server/src/com/vaadin/server/ApplicationStartedEvent.java b/server/src/com/vaadin/server/ApplicationStartedEvent.java index d06744ae40..9ecab4d477 100644 --- a/server/src/com/vaadin/server/ApplicationStartedEvent.java +++ b/server/src/com/vaadin/server/ApplicationStartedEvent.java @@ -18,7 +18,6 @@ package com.vaadin.server; import java.util.EventObject; -import com.vaadin.Application; /** * Event used by @@ -29,7 +28,7 @@ import com.vaadin.Application; * @since 7.0.0 */ public class ApplicationStartedEvent extends EventObject { - private final Application application; + private final VaadinSession application; /** * Creates a new event. @@ -39,7 +38,7 @@ public class ApplicationStartedEvent extends EventObject { * @param application * the application that has been started */ - public ApplicationStartedEvent(AddonContext context, Application application) { + public ApplicationStartedEvent(AddonContext context, VaadinSession application) { super(context); this.application = application; } @@ -58,7 +57,7 @@ public class ApplicationStartedEvent extends EventObject { * * @return the newly created application */ - public Application getApplication() { + public VaadinSession getApplication() { return application; } diff --git a/server/src/com/vaadin/server/ApplicationStartedListener.java b/server/src/com/vaadin/server/ApplicationStartedListener.java index c54132d875..b7858447df 100644 --- a/server/src/com/vaadin/server/ApplicationStartedListener.java +++ b/server/src/com/vaadin/server/ApplicationStartedListener.java @@ -18,10 +18,9 @@ package com.vaadin.server; import java.util.EventListener; -import com.vaadin.Application; /** - * Listener that gets notified when a new {@link Application} has been started. + * Listener that gets notified when a new {@link VaadinSession} has been started. * Add-ons can use this listener to automatically integrate with API tied to the * Application API. * @@ -33,7 +32,7 @@ import com.vaadin.Application; public interface ApplicationStartedListener extends EventListener { /** * Tells the listener that an application has been started (meaning that - * {@link Application#init()} has been invoked. + * {@link VaadinSession#init()} has been invoked. * * @param event * details about the event diff --git a/server/src/com/vaadin/server/BootstrapFragmentResponse.java b/server/src/com/vaadin/server/BootstrapFragmentResponse.java index 149f59e7a5..4b960263e7 100644 --- a/server/src/com/vaadin/server/BootstrapFragmentResponse.java +++ b/server/src/com/vaadin/server/BootstrapFragmentResponse.java @@ -20,7 +20,6 @@ import java.util.List; import org.jsoup.nodes.Node; -import com.vaadin.Application; import com.vaadin.ui.UI; /** @@ -38,7 +37,7 @@ public class BootstrapFragmentResponse extends BootstrapResponse { * Crate a new bootstrap fragment response. * * @see BootstrapResponse#BootstrapResponse(BootstrapHandler, - * WrappedRequest, Application, Class) + * WrappedRequest, VaadinSession, Class) * * @param handler * the bootstrap handler that is firing the event @@ -55,7 +54,7 @@ public class BootstrapFragmentResponse extends BootstrapResponse { * application HTML */ public BootstrapFragmentResponse(BootstrapHandler handler, - WrappedRequest request, Application application, + WrappedRequest request, VaadinSession application, Class uiClass, List fragmentNodes) { super(handler, request, application, uiClass); this.fragmentNodes = fragmentNodes; diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java index a793214942..6b8fb1952a 100644 --- a/server/src/com/vaadin/server/BootstrapHandler.java +++ b/server/src/com/vaadin/server/BootstrapHandler.java @@ -36,7 +36,6 @@ import org.jsoup.nodes.Element; import org.jsoup.nodes.Node; import org.jsoup.parser.Tag; -import com.vaadin.Application; import com.vaadin.external.json.JSONException; import com.vaadin.external.json.JSONObject; import com.vaadin.shared.ApplicationConstants; @@ -68,7 +67,7 @@ public abstract class BootstrapHandler implements RequestHandler { return bootstrapResponse.getRequest(); } - public Application getApplication() { + public VaadinSession getApplication() { return bootstrapResponse.getApplication(); } @@ -104,7 +103,7 @@ public abstract class BootstrapHandler implements RequestHandler { } @Override - public boolean handleRequest(Application application, + public boolean handleRequest(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException { @@ -246,7 +245,7 @@ public abstract class BootstrapHandler implements RequestHandler { } private BootstrapContext createContext(WrappedRequest request, - WrappedResponse response, Application application, + WrappedResponse response, VaadinSession application, Class uiClass) { BootstrapContext context = new BootstrapContext(response, new BootstrapFragmentResponse(this, request, application, @@ -392,7 +391,7 @@ public abstract class BootstrapHandler implements RequestHandler { protected JSONObject getApplicationParameters(BootstrapContext context) throws JSONException, PaintException { - Application application = context.getApplication(); + VaadinSession application = context.getApplication(); JSONObject appConfig = new JSONObject(); @@ -421,7 +420,7 @@ public abstract class BootstrapHandler implements RequestHandler { JSONObject defaults = new JSONObject(); WrappedRequest request = context.getRequest(); - Application application = context.getApplication(); + VaadinSession application = context.getApplication(); DeploymentConfiguration deploymentConfiguration = request .getDeploymentConfiguration(); diff --git a/server/src/com/vaadin/server/BootstrapPageResponse.java b/server/src/com/vaadin/server/BootstrapPageResponse.java index a5fdfe4707..8f56042f8f 100644 --- a/server/src/com/vaadin/server/BootstrapPageResponse.java +++ b/server/src/com/vaadin/server/BootstrapPageResponse.java @@ -20,7 +20,6 @@ import java.util.Map; import org.jsoup.nodes.Document; -import com.vaadin.Application; import com.vaadin.ui.UI; /** @@ -40,7 +39,7 @@ public class BootstrapPageResponse extends BootstrapResponse { * Crate a new bootstrap page response. * * @see BootstrapResponse#BootstrapResponse(BootstrapHandler, - * WrappedRequest, Application, Class) + * WrappedRequest, VaadinSession, Class) * * @param handler * the bootstrap handler that is firing the event @@ -58,7 +57,7 @@ public class BootstrapPageResponse extends BootstrapResponse { * a map into which header data can be added */ public BootstrapPageResponse(BootstrapHandler handler, - WrappedRequest request, Application application, + WrappedRequest request, VaadinSession application, Class uiClass, Document document, Map headers) { super(handler, request, application, uiClass); diff --git a/server/src/com/vaadin/server/BootstrapResponse.java b/server/src/com/vaadin/server/BootstrapResponse.java index 3173569059..b75544a87c 100644 --- a/server/src/com/vaadin/server/BootstrapResponse.java +++ b/server/src/com/vaadin/server/BootstrapResponse.java @@ -18,7 +18,6 @@ package com.vaadin.server; import java.util.EventObject; -import com.vaadin.Application; import com.vaadin.ui.UI; /** @@ -30,7 +29,7 @@ import com.vaadin.ui.UI; */ public abstract class BootstrapResponse extends EventObject { private final WrappedRequest request; - private final Application application; + private final VaadinSession application; private final Class uiClass; /** @@ -48,7 +47,7 @@ public abstract class BootstrapResponse extends EventObject { * the class of the UI that will be displayed on the page */ public BootstrapResponse(BootstrapHandler handler, WrappedRequest request, - Application application, Class uiClass) { + VaadinSession application, Class uiClass) { super(handler); this.request = request; this.application = application; @@ -83,7 +82,7 @@ public abstract class BootstrapResponse extends EventObject { * * @return the application */ - public Application getApplication() { + public VaadinSession getApplication() { return application; } diff --git a/server/src/com/vaadin/server/ClassResource.java b/server/src/com/vaadin/server/ClassResource.java index 2f05115fd4..27643eda13 100644 --- a/server/src/com/vaadin/server/ClassResource.java +++ b/server/src/com/vaadin/server/ClassResource.java @@ -18,7 +18,6 @@ package com.vaadin.server; import java.io.Serializable; -import com.vaadin.Application; import com.vaadin.service.FileTypeResolver; import com.vaadin.ui.UI; import com.vaadin.ui.UI.LegacyWindow; @@ -115,7 +114,7 @@ public class ClassResource implements ConnectorResource, Serializable { if (associatedClass == null) { Class associatedClass = UI.getCurrent().getClass(); if (associatedClass == LegacyWindow.class) { - return Application.getCurrent().getClass(); + return VaadinSession.getCurrent().getClass(); } return associatedClass; } diff --git a/server/src/com/vaadin/server/CombinedRequest.java b/server/src/com/vaadin/server/CombinedRequest.java index 9176754d93..cc336ffa73 100644 --- a/server/src/com/vaadin/server/CombinedRequest.java +++ b/server/src/com/vaadin/server/CombinedRequest.java @@ -24,7 +24,6 @@ import java.util.Iterator; import java.util.Locale; import java.util.Map; -import com.vaadin.Application; import com.vaadin.external.json.JSONArray; import com.vaadin.external.json.JSONException; import com.vaadin.external.json.JSONObject; @@ -143,7 +142,7 @@ public class CombinedRequest implements WrappedRequest { @Override public WebBrowser getWebBrowser() { - return Application.getCurrent().getBrowser(); + return VaadinSession.getCurrent().getBrowser(); } }; } diff --git a/server/src/com/vaadin/server/CommunicationManager.java b/server/src/com/vaadin/server/CommunicationManager.java index beea884aae..3cc8831901 100644 --- a/server/src/com/vaadin/server/CommunicationManager.java +++ b/server/src/com/vaadin/server/CommunicationManager.java @@ -21,7 +21,6 @@ import java.net.URL; import javax.servlet.ServletContext; -import com.vaadin.Application; import com.vaadin.ui.UI; /** @@ -39,12 +38,12 @@ import com.vaadin.ui.UI; public class CommunicationManager extends AbstractCommunicationManager { /** - * @deprecated use {@link #CommunicationManager(Application)} instead + * @deprecated use {@link #CommunicationManager(VaadinSession)} instead * @param application * @param applicationServlet */ @Deprecated - public CommunicationManager(Application application, + public CommunicationManager(VaadinSession application, VaadinServlet applicationServlet) { super(application); } @@ -54,7 +53,7 @@ public class CommunicationManager extends AbstractCommunicationManager { * * @param application */ - public CommunicationManager(Application application) { + public CommunicationManager(VaadinSession application) { super(application); } @@ -88,7 +87,7 @@ public class CommunicationManager extends AbstractCommunicationManager { // don't use server and port in uri. It may cause problems with // some // virtual server configurations which lose the server name - Application application = context.getApplication(); + VaadinSession application = context.getApplication(); URL url = application.getURL(); String appUrl = url.getPath(); if (appUrl.endsWith("/")) { @@ -112,7 +111,7 @@ public class CommunicationManager extends AbstractCommunicationManager { @Override protected InputStream getThemeResourceAsStream(UI uI, String themeName, String resource) { - ServletApplicationContext context = (ServletApplicationContext) uI + VaadinServletSession context = (VaadinServletSession) uI .getApplication(); ServletContext servletContext = context.getHttpSession() .getServletContext(); diff --git a/server/src/com/vaadin/server/ConnectorResourceHandler.java b/server/src/com/vaadin/server/ConnectorResourceHandler.java index b988510b8e..80d3a60a1a 100644 --- a/server/src/com/vaadin/server/ConnectorResourceHandler.java +++ b/server/src/com/vaadin/server/ConnectorResourceHandler.java @@ -8,7 +8,6 @@ import java.util.regex.Pattern; import javax.servlet.http.HttpServletResponse; -import com.vaadin.Application; import com.vaadin.shared.ApplicationConstants; import com.vaadin.ui.UI; @@ -25,7 +24,7 @@ public class ConnectorResourceHandler implements RequestHandler { } @Override - public boolean handleRequest(Application application, + public boolean handleRequest(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException { String requestPath = request.getRequestPathInfo(); @@ -45,7 +44,7 @@ public class ConnectorResourceHandler implements RequestHandler { } UI.setCurrent(ui); - Application.setCurrent(ui.getApplication()); + VaadinSession.setCurrent(ui.getApplication()); ClientConnector connector = ui.getConnectorTracker().getConnector( cid); diff --git a/server/src/com/vaadin/server/DefaultUIProvider.java b/server/src/com/vaadin/server/DefaultUIProvider.java index b326e3229e..9babf4704e 100644 --- a/server/src/com/vaadin/server/DefaultUIProvider.java +++ b/server/src/com/vaadin/server/DefaultUIProvider.java @@ -16,16 +16,15 @@ package com.vaadin.server; -import com.vaadin.Application; import com.vaadin.ui.UI; public class DefaultUIProvider extends AbstractUIProvider { @Override - public Class getUIClass(Application application, + public Class getUIClass(VaadinSession application, WrappedRequest request) { Object uiClassNameObj = application.getConfiguration() - .getInitParameters().getProperty(Application.UI_PARAMETER); + .getInitParameters().getProperty(VaadinSession.UI_PARAMETER); if (uiClassNameObj instanceof String) { String uiClassName = uiClassNameObj.toString(); diff --git a/server/src/com/vaadin/server/FileResource.java b/server/src/com/vaadin/server/FileResource.java index fbf353362e..2dd5b7f589 100644 --- a/server/src/com/vaadin/server/FileResource.java +++ b/server/src/com/vaadin/server/FileResource.java @@ -20,7 +20,6 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import com.vaadin.Application; import com.vaadin.server.Terminal.ErrorEvent; import com.vaadin.service.FileTypeResolver; @@ -74,7 +73,7 @@ public class FileResource implements ConnectorResource { return ds; } catch (final FileNotFoundException e) { // Log the exception using the application error handler - Application.getCurrent().getErrorHandler() + VaadinSession.getCurrent().getErrorHandler() .terminalError(new ErrorEvent() { @Override diff --git a/server/src/com/vaadin/server/GAEVaadinServlet.java b/server/src/com/vaadin/server/GAEVaadinServlet.java index 1175d6a960..4ea1dff7f4 100644 --- a/server/src/com/vaadin/server/GAEVaadinServlet.java +++ b/server/src/com/vaadin/server/GAEVaadinServlet.java @@ -47,7 +47,6 @@ import com.google.appengine.api.memcache.Expiration; import com.google.appengine.api.memcache.MemcacheService; import com.google.appengine.api.memcache.MemcacheServiceFactory; import com.google.apphosting.api.DeadlineExceededException; -import com.vaadin.Application; /** * ApplicationServlet to be used when deploying to Google App Engine, in @@ -242,7 +241,7 @@ public class GAEVaadinServlet extends VaadinServlet { } // de-serialize or create application context, store in session - Application ctx = getApplicationContext(request, memcache); + VaadinSession ctx = getApplicationContext(request, memcache); super.service(request, response); @@ -292,7 +291,7 @@ public class GAEVaadinServlet extends VaadinServlet { } } - protected Application getApplicationContext(HttpServletRequest request, + protected VaadinSession getApplicationContext(HttpServletRequest request, MemcacheService memcache) { HttpSession session = request.getSession(); String id = AC_BASE + session.getId(); @@ -321,7 +320,7 @@ public class GAEVaadinServlet extends VaadinServlet { ObjectInputStream ois; try { ois = new ObjectInputStream(bais); - Application applicationContext = (Application) ois.readObject(); + VaadinSession applicationContext = (VaadinSession) ois.readObject(); applicationContext.storeInSession(new WrappedHttpSession( session)); } catch (IOException e) { @@ -360,7 +359,7 @@ public class GAEVaadinServlet extends VaadinServlet { private void cleanSession(HttpServletRequest request) { HttpSession session = request.getSession(false); if (session != null) { - session.removeAttribute(ServletApplicationContext.class.getName()); + session.removeAttribute(VaadinServletSession.class.getName()); } } diff --git a/server/src/com/vaadin/server/GlobalResourceHandler.java b/server/src/com/vaadin/server/GlobalResourceHandler.java index 441d884f58..03dab9817d 100644 --- a/server/src/com/vaadin/server/GlobalResourceHandler.java +++ b/server/src/com/vaadin/server/GlobalResourceHandler.java @@ -28,7 +28,6 @@ import java.util.regex.Pattern; import javax.servlet.http.HttpServletResponse; -import com.vaadin.Application; import com.vaadin.shared.ApplicationConstants; import com.vaadin.ui.UI; @@ -66,7 +65,7 @@ public class GlobalResourceHandler implements RequestHandler { ""); @Override - public boolean handleRequest(Application application, + public boolean handleRequest(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException { String pathInfo = request.getRequestPathInfo(); diff --git a/server/src/com/vaadin/server/LegacyVaadinPortlet.java b/server/src/com/vaadin/server/LegacyVaadinPortlet.java index 77a94e4d0a..6efd9b29b3 100644 --- a/server/src/com/vaadin/server/LegacyVaadinPortlet.java +++ b/server/src/com/vaadin/server/LegacyVaadinPortlet.java @@ -19,7 +19,6 @@ package com.vaadin.server; import javax.portlet.PortletException; import javax.portlet.PortletRequest; -import com.vaadin.Application; import com.vaadin.LegacyApplication; import com.vaadin.server.ServletPortletHelper.ApplicationClassException; @@ -46,13 +45,13 @@ public class LegacyVaadinPortlet extends VaadinPortlet { } @Override - protected PortletApplicationContext2 createApplication( + protected VaadinPortletSession createApplication( PortletRequest request) throws PortletException { - PortletApplicationContext2 application = super + VaadinPortletSession application = super .createApplication(request); // Must set current before running init() - Application.setCurrent(application); + VaadinSession.setCurrent(application); LegacyApplication legacyApplication = getNewApplication(request); legacyApplication.doInit(); diff --git a/server/src/com/vaadin/server/LegacyVaadinServlet.java b/server/src/com/vaadin/server/LegacyVaadinServlet.java index aa78c401f5..d853e55099 100644 --- a/server/src/com/vaadin/server/LegacyVaadinServlet.java +++ b/server/src/com/vaadin/server/LegacyVaadinServlet.java @@ -19,7 +19,6 @@ package com.vaadin.server; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; -import com.vaadin.Application; import com.vaadin.LegacyApplication; import com.vaadin.server.ServletPortletHelper.ApplicationClassException; @@ -46,13 +45,13 @@ public class LegacyVaadinServlet extends VaadinServlet { } @Override - protected ServletApplicationContext createApplication( + protected VaadinServletSession createApplication( HttpServletRequest request) throws ServletException { - ServletApplicationContext application = super + VaadinServletSession application = super .createApplication(request); // Must set current before running init() - Application.setCurrent(application); + VaadinSession.setCurrent(application); LegacyApplication legacyApplication = getNewApplication(request); legacyApplication.doInit(); diff --git a/server/src/com/vaadin/server/PortletApplicationContext2.java b/server/src/com/vaadin/server/PortletApplicationContext2.java deleted file mode 100644 index ff23d12f4c..0000000000 --- a/server/src/com/vaadin/server/PortletApplicationContext2.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright 2011 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.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import javax.portlet.ActionRequest; -import javax.portlet.ActionResponse; -import javax.portlet.EventRequest; -import javax.portlet.EventResponse; -import javax.portlet.MimeResponse; -import javax.portlet.PortletConfig; -import javax.portlet.PortletMode; -import javax.portlet.PortletModeException; -import javax.portlet.PortletResponse; -import javax.portlet.PortletSession; -import javax.portlet.PortletURL; -import javax.portlet.RenderRequest; -import javax.portlet.RenderResponse; -import javax.portlet.ResourceRequest; -import javax.portlet.ResourceResponse; -import javax.portlet.StateAwareResponse; -import javax.servlet.http.HttpSessionBindingListener; -import javax.xml.namespace.QName; - -import com.vaadin.Application; -import com.vaadin.ui.UI; -import com.vaadin.util.CurrentInstance; - -/** - * TODO Write documentation, fix JavaDoc tags. - * - * This is automatically registered as a {@link HttpSessionBindingListener} when - * {@link PortletSession#setAttribute()} is called with the context as value. - * - * @author peholmst - */ -@SuppressWarnings("serial") -public class PortletApplicationContext2 extends Application { - - private final Set portletListeners = new LinkedHashSet(); - - private final Map eventActionDestinationMap = new HashMap(); - private final Map eventActionValueMap = new HashMap(); - - private final Map sharedParameterActionNameMap = new HashMap(); - private final Map sharedParameterActionValueMap = new HashMap(); - - public PortletSession getPortletSession() { - WrappedSession wrappedSession = getSession(); - PortletSession session = ((WrappedPortletSession) wrappedSession) - .getPortletSession(); - return session; - } - - private PortletResponse getCurrentResponse() { - WrappedPortletResponse currentResponse = (WrappedPortletResponse) CurrentInstance - .get(WrappedResponse.class); - - if (currentResponse != null) { - return currentResponse.getPortletResponse(); - } else { - return null; - } - } - - public PortletConfig getPortletConfig() { - WrappedPortletResponse response = (WrappedPortletResponse) CurrentInstance - .get(WrappedResponse.class); - return response.getDeploymentConfiguration().getPortlet() - .getPortletConfig(); - } - - public void addPortletListener(PortletListener listener) { - portletListeners.add(listener); - } - - public void removePortletListener(PortletListener listener) { - portletListeners.remove(listener); - } - - public void firePortletRenderRequest(UI uI, RenderRequest request, - RenderResponse response) { - for (PortletListener l : new ArrayList( - portletListeners)) { - l.handleRenderRequest(request, new RestrictedRenderResponse( - response), uI); - } - } - - public void firePortletActionRequest(UI uI, ActionRequest request, - ActionResponse response) { - String key = request.getParameter(ActionRequest.ACTION_NAME); - if (eventActionDestinationMap.containsKey(key)) { - // this action request is only to send queued portlet events - response.setEvent(eventActionDestinationMap.get(key), - eventActionValueMap.get(key)); - // cleanup - eventActionDestinationMap.remove(key); - eventActionValueMap.remove(key); - } else if (sharedParameterActionNameMap.containsKey(key)) { - // this action request is only to set shared render parameters - response.setRenderParameter(sharedParameterActionNameMap.get(key), - sharedParameterActionValueMap.get(key)); - // cleanup - sharedParameterActionNameMap.remove(key); - sharedParameterActionValueMap.remove(key); - } else { - // normal action request, notify listeners - for (PortletListener l : new ArrayList( - portletListeners)) { - l.handleActionRequest(request, response, uI); - } - } - } - - public void firePortletEventRequest(UI uI, EventRequest request, - EventResponse response) { - for (PortletListener l : new ArrayList( - portletListeners)) { - l.handleEventRequest(request, response, uI); - } - } - - public void firePortletResourceRequest(UI uI, ResourceRequest request, - ResourceResponse response) { - for (PortletListener l : new ArrayList( - portletListeners)) { - l.handleResourceRequest(request, response, uI); - } - } - - public interface PortletListener extends Serializable { - - public void handleRenderRequest(RenderRequest request, - RenderResponse response, UI uI); - - public void handleActionRequest(ActionRequest request, - ActionResponse response, UI uI); - - public void handleEventRequest(EventRequest request, - EventResponse response, UI uI); - - public void handleResourceRequest(ResourceRequest request, - ResourceResponse response, UI uI); - } - - /** - * Creates a new action URL. - * - * @param action - * @return action URL or null if called outside a MimeRequest (outside a - * UIDL request or similar) - */ - public PortletURL generateActionURL(String action) { - PortletURL url = null; - PortletResponse response = getCurrentResponse(); - if (response instanceof MimeResponse) { - url = ((MimeResponse) response).createActionURL(); - url.setParameter("javax.portlet.action", action); - } else { - return null; - } - return url; - } - - /** - * Sends a portlet event to the indicated destination. - * - * Internally, an action may be created and opened, as an event cannot be - * sent directly from all types of requests. - * - * The event destinations and values need to be kept in the context until - * sent. Any memory leaks if the action fails are limited to the session. - * - * Event names for events sent and received by a portlet need to be declared - * in portlet.xml . - * - * @param uI - * a window in which a temporary action URL can be opened if - * necessary - * @param name - * event name - * @param value - * event value object that is Serializable and, if appropriate, - * has a valid JAXB annotation - */ - public void sendPortletEvent(UI uI, QName name, Serializable value) - throws IllegalStateException { - PortletResponse response = getCurrentResponse(); - if (response instanceof MimeResponse) { - String actionKey = "" + System.currentTimeMillis(); - while (eventActionDestinationMap.containsKey(actionKey)) { - actionKey = actionKey + "."; - } - PortletURL actionUrl = generateActionURL(actionKey); - if (actionUrl != null) { - eventActionDestinationMap.put(actionKey, name); - eventActionValueMap.put(actionKey, value); - uI.getPage().open(new ExternalResource(actionUrl.toString())); - } else { - // this should never happen as we already know the response is a - // MimeResponse - throw new IllegalStateException( - "Portlet events can only be sent from a portlet request"); - } - } else if (response instanceof StateAwareResponse) { - ((StateAwareResponse) response).setEvent(name, value); - } else { - throw new IllegalStateException( - "Portlet events can only be sent from a portlet request"); - } - } - - /** - * Sets a shared portlet parameter. - * - * Internally, an action may be created and opened, as shared parameters - * cannot be set directly from all types of requests. - * - * The parameters and values need to be kept in the context until sent. Any - * memory leaks if the action fails are limited to the session. - * - * Shared parameters set or read by a portlet need to be declared in - * portlet.xml . - * - * @param uI - * a window in which a temporary action URL can be opened if - * necessary - * @param name - * parameter identifier - * @param value - * parameter value - */ - public void setSharedRenderParameter(UI uI, String name, String value) - throws IllegalStateException { - PortletResponse response = getCurrentResponse(); - if (response instanceof MimeResponse) { - String actionKey = "" + System.currentTimeMillis(); - while (sharedParameterActionNameMap.containsKey(actionKey)) { - actionKey = actionKey + "."; - } - PortletURL actionUrl = generateActionURL(actionKey); - if (actionUrl != null) { - sharedParameterActionNameMap.put(actionKey, name); - sharedParameterActionValueMap.put(actionKey, value); - uI.getPage().open(new ExternalResource(actionUrl.toString())); - } else { - // this should never happen as we already know the response is a - // MimeResponse - throw new IllegalStateException( - "Shared parameters can only be set from a portlet request"); - } - } else if (response instanceof StateAwareResponse) { - ((StateAwareResponse) response).setRenderParameter(name, value); - } else { - throw new IllegalStateException( - "Shared parameters can only be set from a portlet request"); - } - } - - /** - * Sets the portlet mode. This may trigger a new render request. - * - * Portlet modes used by a portlet need to be declared in portlet.xml . - * - * @param uI - * a window in which the render URL can be opened if necessary - * @param portletMode - * the portlet mode to switch to - * @throws PortletModeException - * if the portlet mode is not allowed for some reason - * (configuration, permissions etc.) - */ - public void setPortletMode(UI uI, PortletMode portletMode) - throws IllegalStateException, PortletModeException { - PortletResponse response = getCurrentResponse(); - if (response instanceof MimeResponse) { - PortletURL url = ((MimeResponse) response).createRenderURL(); - url.setPortletMode(portletMode); - throw new RuntimeException("UI.open has not yet been implemented"); - // UI.open(new ExternalResource(url.toString())); - } else if (response instanceof StateAwareResponse) { - ((StateAwareResponse) response).setPortletMode(portletMode); - } else { - throw new IllegalStateException( - "Portlet mode can only be changed from a portlet request"); - } - } -} diff --git a/server/src/com/vaadin/server/PortletCommunicationManager.java b/server/src/com/vaadin/server/PortletCommunicationManager.java index ada42140c6..6eccfa6084 100644 --- a/server/src/com/vaadin/server/PortletCommunicationManager.java +++ b/server/src/com/vaadin/server/PortletCommunicationManager.java @@ -26,7 +26,6 @@ import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import javax.portlet.ResourceURL; -import com.vaadin.Application; import com.vaadin.external.json.JSONException; import com.vaadin.external.json.JSONObject; import com.vaadin.shared.ApplicationConstants; @@ -41,7 +40,7 @@ import com.vaadin.ui.UI; @SuppressWarnings("serial") public class PortletCommunicationManager extends AbstractCommunicationManager { - public PortletCommunicationManager(Application application) { + public PortletCommunicationManager(VaadinSession application) { super(application); } @@ -49,7 +48,7 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { protected BootstrapHandler createBootstrapHandler() { return new BootstrapHandler() { @Override - public boolean handleRequest(Application application, + public boolean handleRequest(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException { PortletRequest portletRequest = WrappedPortletRequest.cast( @@ -157,7 +156,7 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { @Override protected InputStream getThemeResourceAsStream(UI uI, String themeName, String resource) { - PortletApplicationContext2 context = (PortletApplicationContext2) uI + VaadinPortletSession context = (VaadinPortletSession) uI .getApplication(); PortletContext portletContext = context.getPortletSession() .getPortletContext(); diff --git a/server/src/com/vaadin/server/RequestHandler.java b/server/src/com/vaadin/server/RequestHandler.java index fcc506cc54..0557c06378 100644 --- a/server/src/com/vaadin/server/RequestHandler.java +++ b/server/src/com/vaadin/server/RequestHandler.java @@ -19,11 +19,10 @@ package com.vaadin.server; import java.io.IOException; import java.io.Serializable; -import com.vaadin.Application; /** * Handler for producing a response to non-UIDL requests. Handlers can be added - * to applications using {@link Application#addRequestHandler(RequestHandler)} + * to applications using {@link VaadinSession#addRequestHandler(RequestHandler)} */ public interface RequestHandler extends Serializable { @@ -42,7 +41,7 @@ public interface RequestHandler extends Serializable { * handlers should be called, otherwise false * @throws IOException */ - boolean handleRequest(Application application, WrappedRequest request, + boolean handleRequest(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException; } diff --git a/server/src/com/vaadin/server/RequestTimer.java b/server/src/com/vaadin/server/RequestTimer.java index afff901d2f..149a1499e7 100644 --- a/server/src/com/vaadin/server/RequestTimer.java +++ b/server/src/com/vaadin/server/RequestTimer.java @@ -18,7 +18,6 @@ package com.vaadin.server; import java.io.Serializable; -import com.vaadin.Application; /** * Times the handling of requests and stores the information as an attribute in @@ -45,7 +44,7 @@ public class RequestTimer implements Serializable { * * @param context */ - public void stop(Application context) { + public void stop(VaadinSession context) { // Measure and store the total handling time. This data can be // used in TestBench 3 tests. long time = (System.nanoTime() - requestStartTime) / 1000000; diff --git a/server/src/com/vaadin/server/RestrictedRenderResponse.java b/server/src/com/vaadin/server/RestrictedRenderResponse.java index 6923a042d6..206c5f349c 100644 --- a/server/src/com/vaadin/server/RestrictedRenderResponse.java +++ b/server/src/com/vaadin/server/RestrictedRenderResponse.java @@ -36,7 +36,7 @@ import org.w3c.dom.Element; * Read-only wrapper for a {@link RenderResponse}. * * Only for use by {@link PortletApplicationContext} and - * {@link PortletApplicationContext2}. + * {@link VaadinPortletSession}. */ class RestrictedRenderResponse implements RenderResponse, Serializable { diff --git a/server/src/com/vaadin/server/ServletApplicationContext.java b/server/src/com/vaadin/server/ServletApplicationContext.java deleted file mode 100644 index 0945de6cb5..0000000000 --- a/server/src/com/vaadin/server/ServletApplicationContext.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2011 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.Enumeration; -import java.util.HashMap; - -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; - -import com.vaadin.Application; -import com.vaadin.util.CurrentInstance; - -/** - * Web application context for Vaadin applications. - * - * This is automatically added as a {@link HttpSessionBindingListener} when - * added to a {@link HttpSession}. - * - * @author Vaadin Ltd. - * @since 3.1 - */ -@SuppressWarnings("serial") -public class ServletApplicationContext extends Application { - - private transient boolean reinitializingSession = false; - - @Override - public void valueUnbound(HttpSessionBindingEvent event) { - if (!reinitializingSession) { - // Avoid closing the application if we are only reinitializing the - // session. Closing the application would cause the state to be lost - // and a new application to be created, which is not what we want. - super.valueUnbound(event); - } - } - - /** - * Discards the current session and creates a new session with the same - * contents. The purpose of this is to introduce a new session key in order - * to avoid session fixation attacks. - */ - public void reinitializeSession() { - - HttpSession oldSession = getHttpSession(); - - // Stores all attributes (security key, reference to this context - // instance) so they can be added to the new session - HashMap attrs = new HashMap(); - for (Enumeration e = oldSession.getAttributeNames(); e - .hasMoreElements();) { - String name = e.nextElement(); - attrs.put(name, oldSession.getAttribute(name)); - } - - // Invalidate the current session, set flag to avoid call to - // valueUnbound - reinitializingSession = true; - oldSession.invalidate(); - reinitializingSession = false; - - // Create a new session - HttpSession newSession = WrappedHttpServletRequest.cast( - CurrentInstance.get(WrappedRequest.class)).getSession(); - - // Restores all attributes (security key, reference to this context - // instance) - for (String name : attrs.keySet()) { - newSession.setAttribute(name, attrs.get(name)); - } - - // Update the "current session" variable - storeInSession(new WrappedHttpSession(newSession)); - } - - /** - * Gets the http-session application is running in. - * - * @return HttpSession this application context resides in. - */ - public HttpSession getHttpSession() { - WrappedSession session = getSession(); - return ((WrappedHttpSession) session).getHttpSession(); - } - -} diff --git a/server/src/com/vaadin/server/ServletPortletHelper.java b/server/src/com/vaadin/server/ServletPortletHelper.java index 28a63fe35b..068a9f9192 100644 --- a/server/src/com/vaadin/server/ServletPortletHelper.java +++ b/server/src/com/vaadin/server/ServletPortletHelper.java @@ -3,7 +3,6 @@ package com.vaadin.server; import java.io.Serializable; import java.util.Properties; -import com.vaadin.Application; import com.vaadin.LegacyApplication; import com.vaadin.shared.ApplicationConstants; import com.vaadin.ui.UI; @@ -68,7 +67,7 @@ class ServletPortletHelper implements Serializable { private static void verifyUIClass(String className, ClassLoader classLoader) throws ApplicationClassException { if (className == null) { - throw new ApplicationClassException(Application.UI_PARAMETER + throw new ApplicationClassException(VaadinSession.UI_PARAMETER + " init parameter not defined"); } @@ -133,24 +132,24 @@ class ServletPortletHelper implements Serializable { ApplicationConstants.HEARTBEAT_REQUEST_PATH); } - public static void initDefaultUIProvider(Application application, + public static void initDefaultUIProvider(VaadinSession application, DeploymentConfiguration deploymentConfiguration) throws ApplicationClassException { String uiProperty = deploymentConfiguration .getApplicationConfiguration().getInitParameters() - .getProperty(Application.UI_PARAMETER); + .getProperty(VaadinSession.UI_PARAMETER); if (uiProperty != null) { verifyUIClass(uiProperty, deploymentConfiguration.getClassLoader()); application.addUIProvider(new DefaultUIProvider()); } } - public static void checkUiProviders(Application newApplication) + public static void checkUiProviders(VaadinSession newApplication) throws ApplicationClassException { if (newApplication.getUIProviders().isEmpty()) { throw new ApplicationClassException( "No UIProvider has been added to the application and there is no \"" - + Application.UI_PARAMETER + "\" init parameter."); + + VaadinSession.UI_PARAMETER + "\" init parameter."); } } diff --git a/server/src/com/vaadin/server/StreamVariable.java b/server/src/com/vaadin/server/StreamVariable.java index f289e7612a..a75cc2f0d7 100644 --- a/server/src/com/vaadin/server/StreamVariable.java +++ b/server/src/com/vaadin/server/StreamVariable.java @@ -18,7 +18,6 @@ package com.vaadin.server; import java.io.OutputStream; import java.io.Serializable; -import com.vaadin.Application; import com.vaadin.server.StreamVariable.StreamingEndEvent; import com.vaadin.server.StreamVariable.StreamingErrorEvent; import com.vaadin.server.StreamVariable.StreamingStartEvent; @@ -152,7 +151,7 @@ public interface StreamVariable extends Serializable { * the streaming ended before the end of the input. The streaming may fail * due an interruption by {@link } or due an other unknown exception in * communication. In the latter case the exception is also passed to - * {@link Application#terminalError(com.vaadin.server.Terminal.ErrorEvent)} + * {@link VaadinSession#terminalError(com.vaadin.server.Terminal.ErrorEvent)} * . */ public interface StreamingErrorEvent extends StreamingEvent { diff --git a/server/src/com/vaadin/server/SystemMessages.java b/server/src/com/vaadin/server/SystemMessages.java index 17aed0003e..3f6a0f9a68 100644 --- a/server/src/com/vaadin/server/SystemMessages.java +++ b/server/src/com/vaadin/server/SystemMessages.java @@ -18,7 +18,6 @@ package com.vaadin.server; import java.io.Serializable; -import com.vaadin.Application; /** @@ -26,7 +25,7 @@ import com.vaadin.Application; * critical situations that can occur. *

    * Customize by overriding the static - * {@link Application#getSystemMessages()} and returning + * {@link VaadinSession#getSystemMessages()} and returning * {@link CustomizedSystemMessages}. *

    *

    diff --git a/server/src/com/vaadin/server/UIProvider.java b/server/src/com/vaadin/server/UIProvider.java index 6a45b06c63..b2908a04d6 100644 --- a/server/src/com/vaadin/server/UIProvider.java +++ b/server/src/com/vaadin/server/UIProvider.java @@ -16,15 +16,14 @@ package com.vaadin.server; -import com.vaadin.Application; import com.vaadin.annotations.Widgetset; import com.vaadin.ui.UI; public interface UIProvider { - public Class getUIClass(Application application, + public Class getUIClass(VaadinSession application, WrappedRequest request); - public UI createInstance(Application application, Class type, + public UI createInstance(VaadinSession application, Class type, WrappedRequest request); public String getPageTitleForUI(WrappedRequest request, diff --git a/server/src/com/vaadin/server/UnsupportedBrowserHandler.java b/server/src/com/vaadin/server/UnsupportedBrowserHandler.java index 325edb5d61..dccbf7ba7b 100644 --- a/server/src/com/vaadin/server/UnsupportedBrowserHandler.java +++ b/server/src/com/vaadin/server/UnsupportedBrowserHandler.java @@ -18,7 +18,6 @@ package com.vaadin.server; import java.io.IOException; import java.io.Writer; -import com.vaadin.Application; /** * A {@link RequestHandler} that presents an informative page if the browser in @@ -36,7 +35,7 @@ public class UnsupportedBrowserHandler implements RequestHandler { public static final String FORCE_LOAD_COOKIE = "vaadinforceload=1"; @Override - public boolean handleRequest(Application application, + public boolean handleRequest(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException { diff --git a/server/src/com/vaadin/server/VaadinPortlet.java b/server/src/com/vaadin/server/VaadinPortlet.java index e69a635b76..941d96ea25 100644 --- a/server/src/com/vaadin/server/VaadinPortlet.java +++ b/server/src/com/vaadin/server/VaadinPortlet.java @@ -55,11 +55,10 @@ import javax.servlet.http.HttpServletResponse; import com.liferay.portal.kernel.util.PortalClassInvoker; import com.liferay.portal.kernel.util.PropsUtil; -import com.vaadin.Application; -import com.vaadin.Application.ApplicationStartEvent; import com.vaadin.DefaultApplicationConfiguration; import com.vaadin.server.AbstractCommunicationManager.Callback; import com.vaadin.server.ServletPortletHelper.ApplicationClassException; +import com.vaadin.server.VaadinSession.ApplicationStartEvent; import com.vaadin.ui.UI; import com.vaadin.util.CurrentInstance; @@ -456,7 +455,7 @@ public class VaadinPortlet extends GenericPortlet implements Constants { serveStaticResources((ResourceRequest) request, (ResourceResponse) response); } else { - Application application = null; + VaadinSession application = null; boolean applicationRunning = false; try { @@ -468,13 +467,13 @@ public class VaadinPortlet extends GenericPortlet implements Constants { if (application == null) { return; } - Application.setCurrent(application); + VaadinSession.setCurrent(application); /* * Get or create an application context and an application * manager for the session */ - PortletApplicationContext2 applicationContext = (PortletApplicationContext2) application; + VaadinPortletSession applicationContext = (VaadinPortletSession) application; PortletCommunicationManager applicationManager = (PortletCommunicationManager) applicationContext .getApplicationManager(); @@ -652,8 +651,8 @@ public class VaadinPortlet extends GenericPortlet implements Constants { */ private void handleOtherRequest(WrappedPortletRequest request, WrappedResponse response, RequestType requestType, - Application application, - PortletApplicationContext2 applicationContext, + VaadinSession application, + VaadinPortletSession applicationContext, PortletCommunicationManager applicationManager) throws PortletException, IOException, MalformedURLException { if (requestType == RequestType.APPLICATION_RESOURCE @@ -761,13 +760,13 @@ public class VaadinPortlet extends GenericPortlet implements Constants { } private void endApplication(PortletRequest request, - PortletResponse response, Application application) + PortletResponse response, VaadinSession application) throws IOException { application.removeFromSession(); // Do not send any redirects when running inside a portlet. } - private Application findApplicationInstance( + private VaadinSession findApplicationInstance( WrappedPortletRequest wrappedRequest, RequestType requestType) throws PortletException, SessionExpiredException, MalformedURLException { @@ -777,7 +776,7 @@ public class VaadinPortlet extends GenericPortlet implements Constants { request, requestType); /* Find an existing application for this request. */ - Application application = getExistingApplication(request, + VaadinSession application = getExistingApplication(request, requestCanCreateApplication); if (application != null) { @@ -811,7 +810,7 @@ public class VaadinPortlet extends GenericPortlet implements Constants { } } - private void closeApplication(Application application, + private void closeApplication(VaadinSession application, PortletSession session) { if (application == null) { return; @@ -821,9 +820,9 @@ public class VaadinPortlet extends GenericPortlet implements Constants { application.removeFromSession(); } - private Application createAndRegisterApplication(PortletRequest request) + private VaadinSession createAndRegisterApplication(PortletRequest request) throws PortletException { - Application newApplication = createApplication(request); + VaadinSession newApplication = createApplication(request); try { ServletPortletHelper.checkUiProviders(newApplication); @@ -845,9 +844,9 @@ public class VaadinPortlet extends GenericPortlet implements Constants { return newApplication; } - protected PortletApplicationContext2 createApplication( + protected VaadinPortletSession createApplication( PortletRequest request) throws PortletException { - PortletApplicationContext2 application = new PortletApplicationContext2(); + VaadinPortletSession application = new VaadinPortletSession(); try { ServletPortletHelper.initDefaultUIProvider(application, @@ -859,7 +858,7 @@ public class VaadinPortlet extends GenericPortlet implements Constants { return application; } - private Application getExistingApplication(PortletRequest request, + private VaadinSession getExistingApplication(PortletRequest request, boolean allowSessionCreation) throws MalformedURLException, SessionExpiredException { @@ -870,7 +869,7 @@ public class VaadinPortlet extends GenericPortlet implements Constants { throw new SessionExpiredException(); } - Application application = Application + VaadinSession application = VaadinSession .getForSession(new WrappedPortletSession(session)); if (application == null) { return null; @@ -884,7 +883,7 @@ public class VaadinPortlet extends GenericPortlet implements Constants { } private void handleServiceException(WrappedPortletRequest request, - WrappedPortletResponse response, Application application, + WrappedPortletResponse response, VaadinSession application, Throwable e) throws IOException, PortletException { // TODO Check that this error handler is working when running inside a // portlet diff --git a/server/src/com/vaadin/server/VaadinPortletSession.java b/server/src/com/vaadin/server/VaadinPortletSession.java new file mode 100644 index 0000000000..8d1ae84fca --- /dev/null +++ b/server/src/com/vaadin/server/VaadinPortletSession.java @@ -0,0 +1,307 @@ +/* + * Copyright 2011 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.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import javax.portlet.ActionRequest; +import javax.portlet.ActionResponse; +import javax.portlet.EventRequest; +import javax.portlet.EventResponse; +import javax.portlet.MimeResponse; +import javax.portlet.PortletConfig; +import javax.portlet.PortletMode; +import javax.portlet.PortletModeException; +import javax.portlet.PortletResponse; +import javax.portlet.PortletSession; +import javax.portlet.PortletURL; +import javax.portlet.RenderRequest; +import javax.portlet.RenderResponse; +import javax.portlet.ResourceRequest; +import javax.portlet.ResourceResponse; +import javax.portlet.StateAwareResponse; +import javax.servlet.http.HttpSessionBindingListener; +import javax.xml.namespace.QName; + +import com.vaadin.ui.UI; +import com.vaadin.util.CurrentInstance; + +/** + * TODO Write documentation, fix JavaDoc tags. + * + * This is automatically registered as a {@link HttpSessionBindingListener} when + * {@link PortletSession#setAttribute()} is called with the context as value. + * + * @author peholmst + */ +@SuppressWarnings("serial") +public class VaadinPortletSession extends VaadinSession { + + private final Set portletListeners = new LinkedHashSet(); + + private final Map eventActionDestinationMap = new HashMap(); + private final Map eventActionValueMap = new HashMap(); + + private final Map sharedParameterActionNameMap = new HashMap(); + private final Map sharedParameterActionValueMap = new HashMap(); + + public PortletSession getPortletSession() { + WrappedSession wrappedSession = getSession(); + PortletSession session = ((WrappedPortletSession) wrappedSession) + .getPortletSession(); + return session; + } + + private PortletResponse getCurrentResponse() { + WrappedPortletResponse currentResponse = (WrappedPortletResponse) CurrentInstance + .get(WrappedResponse.class); + + if (currentResponse != null) { + return currentResponse.getPortletResponse(); + } else { + return null; + } + } + + public PortletConfig getPortletConfig() { + WrappedPortletResponse response = (WrappedPortletResponse) CurrentInstance + .get(WrappedResponse.class); + return response.getDeploymentConfiguration().getPortlet() + .getPortletConfig(); + } + + public void addPortletListener(PortletListener listener) { + portletListeners.add(listener); + } + + public void removePortletListener(PortletListener listener) { + portletListeners.remove(listener); + } + + public void firePortletRenderRequest(UI uI, RenderRequest request, + RenderResponse response) { + for (PortletListener l : new ArrayList( + portletListeners)) { + l.handleRenderRequest(request, new RestrictedRenderResponse( + response), uI); + } + } + + public void firePortletActionRequest(UI uI, ActionRequest request, + ActionResponse response) { + String key = request.getParameter(ActionRequest.ACTION_NAME); + if (eventActionDestinationMap.containsKey(key)) { + // this action request is only to send queued portlet events + response.setEvent(eventActionDestinationMap.get(key), + eventActionValueMap.get(key)); + // cleanup + eventActionDestinationMap.remove(key); + eventActionValueMap.remove(key); + } else if (sharedParameterActionNameMap.containsKey(key)) { + // this action request is only to set shared render parameters + response.setRenderParameter(sharedParameterActionNameMap.get(key), + sharedParameterActionValueMap.get(key)); + // cleanup + sharedParameterActionNameMap.remove(key); + sharedParameterActionValueMap.remove(key); + } else { + // normal action request, notify listeners + for (PortletListener l : new ArrayList( + portletListeners)) { + l.handleActionRequest(request, response, uI); + } + } + } + + public void firePortletEventRequest(UI uI, EventRequest request, + EventResponse response) { + for (PortletListener l : new ArrayList( + portletListeners)) { + l.handleEventRequest(request, response, uI); + } + } + + public void firePortletResourceRequest(UI uI, ResourceRequest request, + ResourceResponse response) { + for (PortletListener l : new ArrayList( + portletListeners)) { + l.handleResourceRequest(request, response, uI); + } + } + + public interface PortletListener extends Serializable { + + public void handleRenderRequest(RenderRequest request, + RenderResponse response, UI uI); + + public void handleActionRequest(ActionRequest request, + ActionResponse response, UI uI); + + public void handleEventRequest(EventRequest request, + EventResponse response, UI uI); + + public void handleResourceRequest(ResourceRequest request, + ResourceResponse response, UI uI); + } + + /** + * Creates a new action URL. + * + * @param action + * @return action URL or null if called outside a MimeRequest (outside a + * UIDL request or similar) + */ + public PortletURL generateActionURL(String action) { + PortletURL url = null; + PortletResponse response = getCurrentResponse(); + if (response instanceof MimeResponse) { + url = ((MimeResponse) response).createActionURL(); + url.setParameter("javax.portlet.action", action); + } else { + return null; + } + return url; + } + + /** + * Sends a portlet event to the indicated destination. + * + * Internally, an action may be created and opened, as an event cannot be + * sent directly from all types of requests. + * + * The event destinations and values need to be kept in the context until + * sent. Any memory leaks if the action fails are limited to the session. + * + * Event names for events sent and received by a portlet need to be declared + * in portlet.xml . + * + * @param uI + * a window in which a temporary action URL can be opened if + * necessary + * @param name + * event name + * @param value + * event value object that is Serializable and, if appropriate, + * has a valid JAXB annotation + */ + public void sendPortletEvent(UI uI, QName name, Serializable value) + throws IllegalStateException { + PortletResponse response = getCurrentResponse(); + if (response instanceof MimeResponse) { + String actionKey = "" + System.currentTimeMillis(); + while (eventActionDestinationMap.containsKey(actionKey)) { + actionKey = actionKey + "."; + } + PortletURL actionUrl = generateActionURL(actionKey); + if (actionUrl != null) { + eventActionDestinationMap.put(actionKey, name); + eventActionValueMap.put(actionKey, value); + uI.getPage().open(new ExternalResource(actionUrl.toString())); + } else { + // this should never happen as we already know the response is a + // MimeResponse + throw new IllegalStateException( + "Portlet events can only be sent from a portlet request"); + } + } else if (response instanceof StateAwareResponse) { + ((StateAwareResponse) response).setEvent(name, value); + } else { + throw new IllegalStateException( + "Portlet events can only be sent from a portlet request"); + } + } + + /** + * Sets a shared portlet parameter. + * + * Internally, an action may be created and opened, as shared parameters + * cannot be set directly from all types of requests. + * + * The parameters and values need to be kept in the context until sent. Any + * memory leaks if the action fails are limited to the session. + * + * Shared parameters set or read by a portlet need to be declared in + * portlet.xml . + * + * @param uI + * a window in which a temporary action URL can be opened if + * necessary + * @param name + * parameter identifier + * @param value + * parameter value + */ + public void setSharedRenderParameter(UI uI, String name, String value) + throws IllegalStateException { + PortletResponse response = getCurrentResponse(); + if (response instanceof MimeResponse) { + String actionKey = "" + System.currentTimeMillis(); + while (sharedParameterActionNameMap.containsKey(actionKey)) { + actionKey = actionKey + "."; + } + PortletURL actionUrl = generateActionURL(actionKey); + if (actionUrl != null) { + sharedParameterActionNameMap.put(actionKey, name); + sharedParameterActionValueMap.put(actionKey, value); + uI.getPage().open(new ExternalResource(actionUrl.toString())); + } else { + // this should never happen as we already know the response is a + // MimeResponse + throw new IllegalStateException( + "Shared parameters can only be set from a portlet request"); + } + } else if (response instanceof StateAwareResponse) { + ((StateAwareResponse) response).setRenderParameter(name, value); + } else { + throw new IllegalStateException( + "Shared parameters can only be set from a portlet request"); + } + } + + /** + * Sets the portlet mode. This may trigger a new render request. + * + * Portlet modes used by a portlet need to be declared in portlet.xml . + * + * @param uI + * a window in which the render URL can be opened if necessary + * @param portletMode + * the portlet mode to switch to + * @throws PortletModeException + * if the portlet mode is not allowed for some reason + * (configuration, permissions etc.) + */ + public void setPortletMode(UI uI, PortletMode portletMode) + throws IllegalStateException, PortletModeException { + PortletResponse response = getCurrentResponse(); + if (response instanceof MimeResponse) { + PortletURL url = ((MimeResponse) response).createRenderURL(); + url.setPortletMode(portletMode); + throw new RuntimeException("UI.open has not yet been implemented"); + // UI.open(new ExternalResource(url.toString())); + } else if (response instanceof StateAwareResponse) { + ((StateAwareResponse) response).setPortletMode(portletMode); + } else { + throw new IllegalStateException( + "Portlet mode can only be changed from a portlet request"); + } + } +} diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java index eb21096c9b..d2e04da2e9 100644 --- a/server/src/com/vaadin/server/VaadinServlet.java +++ b/server/src/com/vaadin/server/VaadinServlet.java @@ -44,11 +44,10 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import com.vaadin.Application; -import com.vaadin.Application.ApplicationStartEvent; import com.vaadin.DefaultApplicationConfiguration; import com.vaadin.server.AbstractCommunicationManager.Callback; import com.vaadin.server.ServletPortletHelper.ApplicationClassException; +import com.vaadin.server.VaadinSession.ApplicationStartEvent; import com.vaadin.shared.ApplicationConstants; import com.vaadin.ui.UI; import com.vaadin.util.CurrentInstance; @@ -285,7 +284,7 @@ public class VaadinServlet extends HttpServlet implements Constants { return; } - Application application = null; + VaadinSession application = null; boolean applicationRunning = false; try { @@ -312,13 +311,13 @@ public class VaadinServlet extends HttpServlet implements Constants { if (application == null) { return; } - Application.setCurrent(application); + VaadinSession.setCurrent(application); /* * Get or create a WebApplicationContext and an ApplicationManager * for the session */ - ServletApplicationContext webApplicationContext = (ServletApplicationContext) application; + VaadinServletSession webApplicationContext = (VaadinServletSession) application; CommunicationManager applicationManager = (CommunicationManager) webApplicationContext .getApplicationManager(); @@ -575,7 +574,7 @@ public class VaadinServlet extends HttpServlet implements Constants { * @throws ServletException * @throws SessionExpiredException */ - private Application findApplicationInstance(HttpServletRequest request, + private VaadinSession findApplicationInstance(HttpServletRequest request, RequestType requestType) throws MalformedURLException, ServletException, SessionExpiredException { @@ -583,7 +582,7 @@ public class VaadinServlet extends HttpServlet implements Constants { request, requestType); /* Find an existing application for this request. */ - Application application = getExistingApplication(request, + VaadinSession application = getExistingApplication(request, requestCanCreateApplication); if (application != null) { @@ -626,9 +625,9 @@ public class VaadinServlet extends HttpServlet implements Constants { } - private Application createAndRegisterApplication(HttpServletRequest request) + private VaadinSession createAndRegisterApplication(HttpServletRequest request) throws ServletException, MalformedURLException { - Application newApplication = createApplication(request); + VaadinSession newApplication = createApplication(request); try { ServletPortletHelper.checkUiProviders(newApplication); @@ -722,9 +721,9 @@ public class VaadinServlet extends HttpServlet implements Constants { * @throws ServletException * @throws MalformedURLException */ - protected ServletApplicationContext createApplication( + protected VaadinServletSession createApplication( HttpServletRequest request) throws ServletException { - ServletApplicationContext newApplication = new ServletApplicationContext(); + VaadinServletSession newApplication = new VaadinServletSession(); try { ServletPortletHelper.initDefaultUIProvider(newApplication, @@ -737,7 +736,7 @@ public class VaadinServlet extends HttpServlet implements Constants { } private void handleServiceException(WrappedHttpServletRequest request, - WrappedHttpServletResponse response, Application application, + WrappedHttpServletResponse response, VaadinSession application, Throwable e) throws IOException, ServletException { // if this was an UIDL request, response UIDL back to client if (getRequestType(request) == RequestType.UIDL) { @@ -1270,7 +1269,7 @@ public class VaadinServlet extends HttpServlet implements Constants { * @throws InstantiationException * @throws SessionExpiredException */ - protected Application getExistingApplication(HttpServletRequest request, + protected VaadinSession getExistingApplication(HttpServletRequest request, boolean allowSessionCreation) throws MalformedURLException, SessionExpiredException { @@ -1280,7 +1279,7 @@ public class VaadinServlet extends HttpServlet implements Constants { throw new SessionExpiredException(); } - Application sessionApplication = getApplicationContext(session); + VaadinSession sessionApplication = getApplicationContext(session); if (sessionApplication == null) { return null; @@ -1307,7 +1306,7 @@ public class VaadinServlet extends HttpServlet implements Constants { * if the writing failed due to input/output error. */ private void endApplication(HttpServletRequest request, - HttpServletResponse response, Application application) + HttpServletResponse response, VaadinSession application) throws IOException { String logoutUrl = application.getLogoutURL(); @@ -1362,7 +1361,7 @@ public class VaadinServlet extends HttpServlet implements Constants { && (request.getParameter(URL_PARAMETER_REPAINT_ALL).equals("1")); } - private void closeApplication(Application application, HttpSession session) { + private void closeApplication(VaadinSession application, HttpSession session) { if (application == null) { return; } @@ -1373,8 +1372,8 @@ public class VaadinServlet extends HttpServlet implements Constants { } } - protected Application getApplicationContext(final HttpSession session) { - Application sessionApplication = Application + protected VaadinSession getApplicationContext(final HttpSession session) { + VaadinSession sessionApplication = VaadinSession .getForSession(new WrappedHttpSession(session)); return sessionApplication; } @@ -1399,11 +1398,11 @@ public class VaadinServlet extends HttpServlet implements Constants { * mananger implementation. * * @deprecated Instead of overriding this method, override - * {@link ServletApplicationContext} implementation via + * {@link VaadinServletSession} implementation via * {@link VaadinServlet#getApplicationContext(HttpSession)} * method and in that customized implementation return your * CommunicationManager in - * {@link ServletApplicationContext#getApplicationManager(Application, VaadinServlet)} + * {@link VaadinServletSession#getApplicationManager(VaadinSession, VaadinServlet)} * method. * * @param application @@ -1411,7 +1410,7 @@ public class VaadinServlet extends HttpServlet implements Constants { */ @Deprecated public CommunicationManager createCommunicationManager( - Application application) { + VaadinSession application) { return new CommunicationManager(application); } diff --git a/server/src/com/vaadin/server/VaadinServletSession.java b/server/src/com/vaadin/server/VaadinServletSession.java new file mode 100644 index 0000000000..72b744da72 --- /dev/null +++ b/server/src/com/vaadin/server/VaadinServletSession.java @@ -0,0 +1,100 @@ +/* + * Copyright 2011 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.Enumeration; +import java.util.HashMap; + +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; + +import com.vaadin.util.CurrentInstance; + +/** + * Web application context for Vaadin applications. + * + * This is automatically added as a {@link HttpSessionBindingListener} when + * added to a {@link HttpSession}. + * + * @author Vaadin Ltd. + * @since 3.1 + */ +@SuppressWarnings("serial") +public class VaadinServletSession extends VaadinSession { + + private transient boolean reinitializingSession = false; + + @Override + public void valueUnbound(HttpSessionBindingEvent event) { + if (!reinitializingSession) { + // Avoid closing the application if we are only reinitializing the + // session. Closing the application would cause the state to be lost + // and a new application to be created, which is not what we want. + super.valueUnbound(event); + } + } + + /** + * Discards the current session and creates a new session with the same + * contents. The purpose of this is to introduce a new session key in order + * to avoid session fixation attacks. + */ + public void reinitializeSession() { + + HttpSession oldSession = getHttpSession(); + + // Stores all attributes (security key, reference to this context + // instance) so they can be added to the new session + HashMap attrs = new HashMap(); + for (Enumeration e = oldSession.getAttributeNames(); e + .hasMoreElements();) { + String name = e.nextElement(); + attrs.put(name, oldSession.getAttribute(name)); + } + + // Invalidate the current session, set flag to avoid call to + // valueUnbound + reinitializingSession = true; + oldSession.invalidate(); + reinitializingSession = false; + + // Create a new session + HttpSession newSession = WrappedHttpServletRequest.cast( + CurrentInstance.get(WrappedRequest.class)).getSession(); + + // Restores all attributes (security key, reference to this context + // instance) + for (String name : attrs.keySet()) { + newSession.setAttribute(name, attrs.get(name)); + } + + // Update the "current session" variable + storeInSession(new WrappedHttpSession(newSession)); + } + + /** + * Gets the http-session application is running in. + * + * @return HttpSession this application context resides in. + */ + public HttpSession getHttpSession() { + WrappedSession session = getSession(); + return ((WrappedHttpSession) session).getHttpSession(); + } + +} diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java new file mode 100644 index 0000000000..10532559f0 --- /dev/null +++ b/server/src/com/vaadin/server/VaadinSession.java @@ -0,0 +1,1978 @@ +/* + * Copyright 2011 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.io.IOException; +import java.io.Serializable; +import java.lang.reflect.Method; +import java.net.SocketException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.EventObject; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; + +import com.vaadin.data.util.converter.Converter; +import com.vaadin.data.util.converter.ConverterFactory; +import com.vaadin.data.util.converter.DefaultConverterFactory; +import com.vaadin.event.EventRouter; +import com.vaadin.server.WrappedRequest.BrowserDetails; +import com.vaadin.shared.ui.ui.UIConstants; +import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.AbstractField; +import com.vaadin.ui.Table; +import com.vaadin.ui.UI; +import com.vaadin.ui.Window; +import com.vaadin.util.CurrentInstance; +import com.vaadin.util.ReflectTools; + +/** + *

    + * Base class required for all Vaadin applications. This class provides all the + * basic services required by Vaadin. These services allow external discovery + * and manipulation of the user, {@link com.vaadin.ui.Window windows} and + * themes, and starting and stopping the application. + *

    + * + *

    + * As mentioned, all Vaadin applications must inherit this class. However, this + * is almost all of what one needs to do to create a fully functional + * application. The only thing a class inheriting the Application + * needs to do is implement the init method where it creates the + * windows it needs to perform its function. Note that all applications must + * have at least one window: the main window. The first unnamed window + * constructed by an application automatically becomes the main window which + * behaves just like other windows with one exception: when accessing windows + * using URLs the main window corresponds to the application URL whereas other + * windows correspond to a URL gotten by catenating the window's name to the + * application URL. + *

    + * + *

    + * See the class com.vaadin.demo.HelloWorld for a simple example of + * a fully working application. + *

    + * + *

    + * Window access. Application provides methods to + * list, add and remove the windows it contains. + *

    + * + *

    + * Execution control. This class includes method to start and + * finish the execution of the application. Being finished means basically that + * no windows will be available from the application anymore. + *

    + * + *

    + * Theme selection. The theme selection process allows a theme + * to be specified at three different levels. When a window's theme needs to be + * found out, the window itself is queried for a preferred theme. If the window + * does not prefer a specific theme, the application containing the window is + * queried. If neither the application prefers a theme, the default theme for + * the {@link com.vaadin.server.Terminal terminal} is used. The terminal always + * defines a default theme. + *

    + * + * @author Vaadin Ltd. + * @since 3.0 + */ +@SuppressWarnings("serial") +public class VaadinSession implements Terminal.ErrorListener, + HttpSessionBindingListener, Serializable { + + /** + * The name of the parameter that is by default used in e.g. web.xml to + * define the name of the default {@link UI} class. + */ + public static final String UI_PARAMETER = "UI"; + + private static final Method BOOTSTRAP_FRAGMENT_METHOD = ReflectTools + .findMethod(BootstrapListener.class, "modifyBootstrapFragment", + BootstrapFragmentResponse.class); + private static final Method BOOTSTRAP_PAGE_METHOD = ReflectTools + .findMethod(BootstrapListener.class, "modifyBootstrapPage", + BootstrapPageResponse.class); + + /** + * An event sent to {@link #start(ApplicationStartEvent)} when a new + * Application is being started. + * + * @since 7.0 + */ + public static class ApplicationStartEvent implements Serializable { + private final URL applicationUrl; + + private final ApplicationConfiguration configuration; + + private final AbstractCommunicationManager communicationManager; + + /** + * @param applicationUrl + * the URL the application should respond to. + * @param configuration + * the application configuration for the application. + * @param communicationManager + * the communication manager for the application. + */ + public ApplicationStartEvent(URL applicationUrl, + ApplicationConfiguration configuration, + AbstractCommunicationManager communicationManager) { + this.applicationUrl = applicationUrl; + this.configuration = configuration; + this.communicationManager = communicationManager; + } + + /** + * Gets the URL the application should respond to. + * + * @return the URL the application should respond to or + * null if the URL is not defined. + * + * @see VaadinSession#getURL() + */ + public URL getApplicationUrl() { + return applicationUrl; + } + + /** + * Returns the application configuration used by this application. + * + * @return the deployment configuration. + */ + public ApplicationConfiguration getConfiguration() { + return configuration; + } + + /** + * Gets the communication manager for this application. + * + * @return the communication manager for this application. + * + * @see VaadinSession#getCommunicationManager + */ + public AbstractCommunicationManager getCommunicationManager() { + return communicationManager; + } + } + + private final static Logger logger = Logger.getLogger(VaadinSession.class + .getName()); + + /** + * Configuration for the application. + */ + private ApplicationConfiguration configuration; + + /** + * The application's URL. + */ + private URL applicationUrl; + + /** + * Application status. + */ + private volatile boolean applicationIsRunning = false; + + /** + * Default locale of the application. + */ + private Locale locale; + + /** + * URL where the user is redirected to on application close, or null if + * application is just closed without redirection. + */ + private String logoutURL = null; + + /** + * Application wide error handler which is used by default if an error is + * left unhandled. + */ + private Terminal.ErrorListener errorHandler = this; + + /** + * The converter factory that is used to provide default converters for the + * application. + */ + private ConverterFactory converterFactory = new DefaultConverterFactory(); + + private LinkedList requestHandlers = new LinkedList(); + + private int nextUIId = 0; + private Map uIs = new HashMap(); + + private final Map retainOnRefreshUIs = new HashMap(); + + private final EventRouter eventRouter = new EventRouter(); + + private List uiProviders = new LinkedList(); + + private GlobalResourceHandler globalResourceHandler; + + protected WebBrowser browser = new WebBrowser(); + + private AbstractCommunicationManager communicationManager; + + private long totalSessionTime = 0; + + private long lastRequestTime = -1; + + private transient WrappedSession session; + + /** + * @see javax.servlet.http.HttpSessionBindingListener#valueBound(HttpSessionBindingEvent) + */ + @Override + public void valueBound(HttpSessionBindingEvent arg0) { + // We are not interested in bindings + } + + /** + * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(HttpSessionBindingEvent) + */ + @Override + public void valueUnbound(HttpSessionBindingEvent event) { + // If we are going to be unbound from the session, the session must be + // closing + close(); + } + + /** + * Get the web browser associated with this application context. + * + * Because application context is related to the http session and server + * maintains one session per browser-instance, each context has exactly one + * web browser associated with it. + * + * @return + */ + public WebBrowser getBrowser() { + return browser; + } + + /** + * @return The total time spent servicing requests in this session. + */ + public long getTotalSessionTime() { + return totalSessionTime; + } + + /** + * Sets the time spent servicing the last request in the session and updates + * the total time spent servicing requests in this session. + * + * @param time + * the time spent in the last request. + */ + public void setLastRequestTime(long time) { + lastRequestTime = time; + totalSessionTime += time; + } + + /** + * @return the time spent servicing the last request in this session. + */ + public long getLastRequestTime() { + return lastRequestTime; + } + + /** + * Gets the session to which this application context is currently + * associated. + * + * @return the wrapped session for this context + */ + public WrappedSession getSession() { + return session; + } + + public AbstractCommunicationManager getApplicationManager() { + return communicationManager; + } + + /** + * Gets the URL of the application. + * + *

    + * This is the URL what can be entered to a browser window to start the + * application. Navigating to the application URL shows the main window ( + * {@link #getMainWindow()}) of the application. Note that the main window + * can also be shown by navigating to the window url ( + * {@link com.vaadin.ui.Window#getURL()}). + *

    + * + * @return the application's URL. + */ + public URL getURL() { + return applicationUrl; + } + + /** + * Ends the Application. + *

    + * In effect this will cause the application stop returning any windows when + * asked. When the application is closed, close events are fired for its + * UIs, its state is removed from the session, and the browser window is + * redirected to the application logout url set with + * {@link #setLogoutURL(String)}. If the logout url has not been set, the + * browser window is reloaded and the application is restarted. + */ + public void close() { + applicationIsRunning = false; + for (UI ui : getUIs()) { + ui.fireCloseEvent(); + } + } + + public static VaadinSession getForSession(WrappedSession session) { + Object attribute = session.getAttribute(VaadinSession.class.getName()); + if (attribute instanceof VaadinSession) { + VaadinSession application = (VaadinSession) attribute; + application.session = session; + return application; + } + + return null; + } + + public void removeFromSession() { + assert (getForSession(session) == this); + + session.setAttribute(VaadinSession.class.getName(), null); + } + + public void storeInSession(WrappedSession session) { + session.setAttribute(VaadinSession.class.getName(), this); + this.session = session; + } + + /** + * Starts the application on the given URL. + * + *

    + * This method is called by Vaadin framework when a user navigates to the + * application. After this call the application corresponds to the given URL + * and it will return windows when asked for them. There is no need to call + * this method directly. + *

    + * + *

    + * Application properties are defined by servlet configuration object + * {@link javax.servlet.ServletConfig} and they are overridden by + * context-wide initialization parameters + * {@link javax.servlet.ServletContext}. + *

    + * + * @param event + * the application start event containing details required for + * starting the application. + * + */ + public void start(ApplicationStartEvent event) { + applicationUrl = event.getApplicationUrl(); + configuration = event.getConfiguration(); + communicationManager = event.getCommunicationManager(); + applicationIsRunning = true; + } + + /** + * Tests if the application is running or if it has been finished. + * + *

    + * Application starts running when its {@link #start(ApplicationStartEvent)} + * method has been called and stops when the {@link #close()} is called. + *

    + * + * @return true if the application is running, + * false if not. + */ + public boolean isRunning() { + return applicationIsRunning; + } + + /** + * Gets the configuration for this application + * + * @return the application configuration + */ + public ApplicationConfiguration getConfiguration() { + return configuration; + } + + /** + * Gets the default locale for this application. + * + * By default this is the preferred locale of the user using the + * application. In most cases it is read from the browser defaults. + * + * @return the locale of this application. + */ + public Locale getLocale() { + if (locale != null) { + return locale; + } + return Locale.getDefault(); + } + + /** + * Sets the default locale for this application. + * + * By default this is the preferred locale of the user using the + * application. In most cases it is read from the browser defaults. + * + * @param locale + * the Locale object. + * + */ + public void setLocale(Locale locale) { + this.locale = locale; + } + + /** + * Window detach event. + * + * This event is sent each time a window is removed from the application + * with {@link com.vaadin.server.VaadinSession#removeWindow(Window)}. + */ + public static class WindowDetachEvent extends EventObject { + + private final Window window; + + /** + * Creates a event. + * + * @param application + * the application to which the detached window belonged. + * @param window + * the Detached window. + */ + public WindowDetachEvent(VaadinSession application, Window window) { + super(application); + this.window = window; + } + + /** + * Gets the detached window. + * + * @return the detached window. + */ + public Window getWindow() { + return window; + } + + /** + * Gets the application from which the window was detached. + * + * @return the Application. + */ + public VaadinSession getApplication() { + return (VaadinSession) getSource(); + } + } + + /** + * Window attach event. + * + * This event is sent each time a window is attached tothe application with + * {@link com.vaadin.server.VaadinSession#addWindow(Window)}. + */ + public static class WindowAttachEvent extends EventObject { + + private final Window window; + + /** + * Creates a event. + * + * @param application + * the application to which the detached window belonged. + * @param window + * the Attached window. + */ + public WindowAttachEvent(VaadinSession application, Window window) { + super(application); + this.window = window; + } + + /** + * Gets the attached window. + * + * @return the attached window. + */ + public Window getWindow() { + return window; + } + + /** + * Gets the application to which the window was attached. + * + * @return the Application. + */ + public VaadinSession getApplication() { + return (VaadinSession) getSource(); + } + } + + /** + * Window attach listener interface. + */ + public interface WindowAttachListener extends Serializable { + + /** + * Window attached + * + * @param event + * the window attach event. + */ + public void windowAttached(WindowAttachEvent event); + } + + /** + * Window detach listener interface. + */ + public interface WindowDetachListener extends Serializable { + + /** + * Window detached. + * + * @param event + * the window detach event. + */ + public void windowDetached(WindowDetachEvent event); + } + + /** + * Returns the URL user is redirected to on application close. If the URL is + * null, the application is closed normally as defined by the + * application running environment. + *

    + * Desktop application just closes the application window and + * web-application redirects the browser to application main URL. + *

    + * + * @return the URL. + */ + public String getLogoutURL() { + return logoutURL; + } + + /** + * Sets the URL user is redirected to on application close. If the URL is + * null, the application is closed normally as defined by the + * application running environment: Desktop application just closes the + * application window and web-application redirects the browser to + * application main URL. + * + * @param logoutURL + * the logoutURL to set. + */ + public void setLogoutURL(String logoutURL) { + this.logoutURL = logoutURL; + } + + /** + *

    + * Invoked by the terminal on any exception that occurs in application and + * is thrown by the setVariable to the terminal. The default + * implementation sets the exceptions as ComponentErrors to the + * component that initiated the exception and prints stack trace to standard + * error stream. + *

    + *

    + * You can safely override this method in your application in order to + * direct the errors to some other destination (for example log). + *

    + * + * @param event + * the change event. + * @see com.vaadin.server.Terminal.ErrorListener#terminalError(com.vaadin.server.Terminal.ErrorEvent) + */ + + @Override + public void terminalError(Terminal.ErrorEvent event) { + final Throwable t = event.getThrowable(); + if (t instanceof SocketException) { + // Most likely client browser closed socket + getLogger().info( + "SocketException in CommunicationManager." + + " Most likely client (browser) closed socket."); + return; + } + + // Finds the original source of the error/exception + Object owner = null; + if (event instanceof VariableOwner.ErrorEvent) { + owner = ((VariableOwner.ErrorEvent) event).getVariableOwner(); + } else if (event instanceof ChangeVariablesErrorEvent) { + owner = ((ChangeVariablesErrorEvent) event).getComponent(); + } + + // Shows the error in AbstractComponent + if (owner instanceof AbstractComponent) { + ((AbstractComponent) owner).setComponentError(AbstractErrorMessage + .getErrorMessageForException(t)); + } + + // also print the error on console + getLogger().log(Level.SEVERE, "Terminal error:", t); + } + + /** + * Gets the application error handler. + * + * The default error handler is the application itself. + * + * @return Application error handler + */ + public Terminal.ErrorListener getErrorHandler() { + return errorHandler; + } + + /** + * Sets the application error handler. + * + * The default error handler is the application itself. By overriding this, + * you can redirect the error messages to your selected target (log for + * example). + * + * @param errorHandler + */ + public void setErrorHandler(Terminal.ErrorListener errorHandler) { + this.errorHandler = errorHandler; + } + + /** + * Gets the {@link ConverterFactory} used to locate a suitable + * {@link Converter} for fields in the application. + * + * See {@link #setConverterFactory(ConverterFactory)} for more details + * + * @return The converter factory used in the application + */ + public ConverterFactory getConverterFactory() { + return converterFactory; + } + + /** + * Sets the {@link ConverterFactory} used to locate a suitable + * {@link Converter} for fields in the application. + *

    + * The {@link ConverterFactory} is used to find a suitable converter when + * binding data to a UI component and the data type does not match the UI + * component type, e.g. binding a Double to a TextField (which is based on a + * String). + *

    + *

    + * The {@link Converter} for an individual field can be overridden using + * {@link AbstractField#setConverter(Converter)} and for individual property + * ids in a {@link Table} using + * {@link Table#setConverter(Object, Converter)}. + *

    + *

    + * The converter factory must never be set to null. + * + * @param converterFactory + * The converter factory used in the application + */ + public void setConverterFactory(ConverterFactory converterFactory) { + this.converterFactory = converterFactory; + } + + /** + * Contains the system messages used to notify the user about various + * critical situations that can occur. + *

    + * Customize by overriding the static + * {@link VaadinSession#getSystemMessages()} and returning + * {@link CustomizedSystemMessages}. + *

    + *

    + * The defaults defined in this class are: + *

      + *
    • sessionExpiredURL = null
    • + *
    • sessionExpiredNotificationEnabled = true
    • + *
    • sessionExpiredCaption = ""
    • + *
    • sessionExpiredMessage = + * "Take note of any unsaved data, and click here to continue."
    • + *
    • communicationErrorURL = null
    • + *
    • communicationErrorNotificationEnabled = true
    • + *
    • communicationErrorCaption = "Communication problem"
    • + *
    • communicationErrorMessage = + * "Take note of any unsaved data, and click here to continue."
    • + *
    • internalErrorURL = null
    • + *
    • internalErrorNotificationEnabled = true
    • + *
    • internalErrorCaption = "Internal error"
    • + *
    • internalErrorMessage = "Please notify the administrator.
      + * Take note of any unsaved data, and click here to continue."
    • + *
    • outOfSyncURL = null
    • + *
    • outOfSyncNotificationEnabled = true
    • + *
    • outOfSyncCaption = "Out of sync"
    • + *
    • outOfSyncMessage = "Something has caused us to be out of sync + * with the server.
      + * Take note of any unsaved data, and click here to re-sync."
    • + *
    • cookiesDisabledURL = null
    • + *
    • cookiesDisabledNotificationEnabled = true
    • + *
    • cookiesDisabledCaption = "Cookies disabled"
    • + *
    • cookiesDisabledMessage = "This application requires cookies to + * function.
      + * Please enable cookies in your browser and click here to try again. + *
    • + *
    + *

    + * + */ + public static class SystemMessages implements Serializable { + protected String sessionExpiredURL = null; + protected boolean sessionExpiredNotificationEnabled = true; + protected String sessionExpiredCaption = "Session Expired"; + protected String sessionExpiredMessage = "Take note of any unsaved data, and click here to continue."; + + protected String communicationErrorURL = null; + protected boolean communicationErrorNotificationEnabled = true; + protected String communicationErrorCaption = "Communication problem"; + protected String communicationErrorMessage = "Take note of any unsaved data, and click here to continue."; + + protected String authenticationErrorURL = null; + protected boolean authenticationErrorNotificationEnabled = true; + protected String authenticationErrorCaption = "Authentication problem"; + protected String authenticationErrorMessage = "Take note of any unsaved data, and click here to continue."; + + protected String internalErrorURL = null; + protected boolean internalErrorNotificationEnabled = true; + protected String internalErrorCaption = "Internal error"; + protected String internalErrorMessage = "Please notify the administrator.
    Take note of any unsaved data, and click here to continue."; + + protected String outOfSyncURL = null; + protected boolean outOfSyncNotificationEnabled = true; + protected String outOfSyncCaption = "Out of sync"; + protected String outOfSyncMessage = "Something has caused us to be out of sync with the server.
    Take note of any unsaved data, and click here to re-sync."; + + protected String cookiesDisabledURL = null; + protected boolean cookiesDisabledNotificationEnabled = true; + protected String cookiesDisabledCaption = "Cookies disabled"; + protected String cookiesDisabledMessage = "This application requires cookies to function.
    Please enable cookies in your browser and click here to try again."; + + /** + * Use {@link CustomizedSystemMessages} to customize + */ + private SystemMessages() { + + } + + /** + * @return null to indicate that the application will be restarted after + * session expired message has been shown. + */ + public String getSessionExpiredURL() { + return sessionExpiredURL; + } + + /** + * @return true to show session expiration message. + */ + public boolean isSessionExpiredNotificationEnabled() { + return sessionExpiredNotificationEnabled; + } + + /** + * @return "" to show no caption. + */ + public String getSessionExpiredCaption() { + return (sessionExpiredNotificationEnabled ? sessionExpiredCaption + : null); + } + + /** + * @return + * "Take note of any unsaved data, and click here to continue." + */ + public String getSessionExpiredMessage() { + return (sessionExpiredNotificationEnabled ? sessionExpiredMessage + : null); + } + + /** + * @return null to reload the application after communication error + * message. + */ + public String getCommunicationErrorURL() { + return communicationErrorURL; + } + + /** + * @return true to show the communication error message. + */ + public boolean isCommunicationErrorNotificationEnabled() { + return communicationErrorNotificationEnabled; + } + + /** + * @return "Communication problem" + */ + public String getCommunicationErrorCaption() { + return (communicationErrorNotificationEnabled ? communicationErrorCaption + : null); + } + + /** + * @return + * "Take note of any unsaved data, and click here to continue." + */ + public String getCommunicationErrorMessage() { + return (communicationErrorNotificationEnabled ? communicationErrorMessage + : null); + } + + /** + * @return null to reload the application after authentication error + * message. + */ + public String getAuthenticationErrorURL() { + return authenticationErrorURL; + } + + /** + * @return true to show the authentication error message. + */ + public boolean isAuthenticationErrorNotificationEnabled() { + return authenticationErrorNotificationEnabled; + } + + /** + * @return "Authentication problem" + */ + public String getAuthenticationErrorCaption() { + return (authenticationErrorNotificationEnabled ? authenticationErrorCaption + : null); + } + + /** + * @return + * "Take note of any unsaved data, and click here to continue." + */ + public String getAuthenticationErrorMessage() { + return (authenticationErrorNotificationEnabled ? authenticationErrorMessage + : null); + } + + /** + * @return null to reload the current URL after internal error message + * has been shown. + */ + public String getInternalErrorURL() { + return internalErrorURL; + } + + /** + * @return true to enable showing of internal error message. + */ + public boolean isInternalErrorNotificationEnabled() { + return internalErrorNotificationEnabled; + } + + /** + * @return "Internal error" + */ + public String getInternalErrorCaption() { + return (internalErrorNotificationEnabled ? internalErrorCaption + : null); + } + + /** + * @return "Please notify the administrator.
    + * Take note of any unsaved data, and click here to + * continue." + */ + public String getInternalErrorMessage() { + return (internalErrorNotificationEnabled ? internalErrorMessage + : null); + } + + /** + * @return null to reload the application after out of sync message. + */ + public String getOutOfSyncURL() { + return outOfSyncURL; + } + + /** + * @return true to enable showing out of sync message + */ + public boolean isOutOfSyncNotificationEnabled() { + return outOfSyncNotificationEnabled; + } + + /** + * @return "Out of sync" + */ + public String getOutOfSyncCaption() { + return (outOfSyncNotificationEnabled ? outOfSyncCaption : null); + } + + /** + * @return "Something has caused us to be out of sync with the server.
    + * Take note of any unsaved data, and click here to + * re-sync." + */ + public String getOutOfSyncMessage() { + return (outOfSyncNotificationEnabled ? outOfSyncMessage : null); + } + + /** + * Returns the URL the user should be redirected to after dismissing the + * "you have to enable your cookies" message. Typically null. + * + * @return A URL the user should be redirected to after dismissing the + * message or null to reload the current URL. + */ + public String getCookiesDisabledURL() { + return cookiesDisabledURL; + } + + /** + * Determines if "cookies disabled" messages should be shown to the end + * user or not. If the notification is disabled the user will be + * immediately redirected to the URL returned by + * {@link #getCookiesDisabledURL()}. + * + * @return true to show "cookies disabled" messages to the end user, + * false to redirect to the given URL directly + */ + public boolean isCookiesDisabledNotificationEnabled() { + return cookiesDisabledNotificationEnabled; + } + + /** + * Returns the caption of the message shown to the user when cookies are + * disabled in the browser. + * + * @return The caption of the "cookies disabled" message + */ + public String getCookiesDisabledCaption() { + return (cookiesDisabledNotificationEnabled ? cookiesDisabledCaption + : null); + } + + /** + * Returns the message shown to the user when cookies are disabled in + * the browser. + * + * @return The "cookies disabled" message + */ + public String getCookiesDisabledMessage() { + return (cookiesDisabledNotificationEnabled ? cookiesDisabledMessage + : null); + } + + } + + /** + * Contains the system messages used to notify the user about various + * critical situations that can occur. + *

    + * Vaadin gets the SystemMessages from your application by calling a static + * getSystemMessages() method. By default the + * Application.getSystemMessages() is used. You can customize this by + * defining a static MyApplication.getSystemMessages() and returning + * CustomizedSystemMessages. Note that getSystemMessages() is static - + * changing the system messages will by default change the message for all + * users of the application. + *

    + *

    + * The default behavior is to show a notification, and restart the + * application the the user clicks the message.
    + * Instead of restarting the application, you can set a specific URL that + * the user is taken to.
    + * Setting both caption and message to null will restart the application (or + * go to the specified URL) without displaying a notification. + * set*NotificationEnabled(false) will achieve the same thing. + *

    + *

    + * The situations are: + *

  • Session expired: the user session has expired, usually due to + * inactivity.
  • + *
  • Communication error: the client failed to contact the server, or the + * server returned and invalid response.
  • + *
  • Internal error: unhandled critical server error (e.g out of memory, + * database crash) + *
  • Out of sync: the client is not in sync with the server. E.g the user + * opens two windows showing the same application, but the application does + * not support this and uses the same Window instance. When the user makes + * changes in one of the windows - the other window is no longer in sync, + * and (for instance) pressing a button that is no longer present in the UI + * will cause a out-of-sync -situation. + *

    + */ + + public static class CustomizedSystemMessages extends SystemMessages + implements Serializable { + + /** + * Sets the URL to go to when the session has expired. + * + * @param sessionExpiredURL + * the URL to go to, or null to reload current + */ + public void setSessionExpiredURL(String sessionExpiredURL) { + this.sessionExpiredURL = sessionExpiredURL; + } + + /** + * Enables or disables the notification. If disabled, the set URL (or + * current) is loaded directly when next transaction between server and + * client happens. + * + * @param sessionExpiredNotificationEnabled + * true = enabled, false = disabled + */ + public void setSessionExpiredNotificationEnabled( + boolean sessionExpiredNotificationEnabled) { + this.sessionExpiredNotificationEnabled = sessionExpiredNotificationEnabled; + } + + /** + * Sets the caption of the notification. Set to null for no caption. If + * both caption and message are null, client automatically forwards to + * sessionExpiredUrl after timeout timer expires. Timer uses value read + * from HTTPSession.getMaxInactiveInterval() + * + * @param sessionExpiredCaption + * the caption + */ + public void setSessionExpiredCaption(String sessionExpiredCaption) { + this.sessionExpiredCaption = sessionExpiredCaption; + } + + /** + * Sets the message of the notification. Set to null for no message. If + * both caption and message are null, client automatically forwards to + * sessionExpiredUrl after timeout timer expires. Timer uses value read + * from HTTPSession.getMaxInactiveInterval() + * + * @param sessionExpiredMessage + * the message + */ + public void setSessionExpiredMessage(String sessionExpiredMessage) { + this.sessionExpiredMessage = sessionExpiredMessage; + } + + /** + * Sets the URL to go to when there is a authentication error. + * + * @param authenticationErrorURL + * the URL to go to, or null to reload current + */ + public void setAuthenticationErrorURL(String authenticationErrorURL) { + this.authenticationErrorURL = authenticationErrorURL; + } + + /** + * Enables or disables the notification. If disabled, the set URL (or + * current) is loaded directly. + * + * @param authenticationErrorNotificationEnabled + * true = enabled, false = disabled + */ + public void setAuthenticationErrorNotificationEnabled( + boolean authenticationErrorNotificationEnabled) { + this.authenticationErrorNotificationEnabled = authenticationErrorNotificationEnabled; + } + + /** + * Sets the caption of the notification. Set to null for no caption. If + * both caption and message is null, the notification is disabled; + * + * @param authenticationErrorCaption + * the caption + */ + public void setAuthenticationErrorCaption( + String authenticationErrorCaption) { + this.authenticationErrorCaption = authenticationErrorCaption; + } + + /** + * Sets the message of the notification. Set to null for no message. If + * both caption and message is null, the notification is disabled; + * + * @param authenticationErrorMessage + * the message + */ + public void setAuthenticationErrorMessage( + String authenticationErrorMessage) { + this.authenticationErrorMessage = authenticationErrorMessage; + } + + /** + * Sets the URL to go to when there is a communication error. + * + * @param communicationErrorURL + * the URL to go to, or null to reload current + */ + public void setCommunicationErrorURL(String communicationErrorURL) { + this.communicationErrorURL = communicationErrorURL; + } + + /** + * Enables or disables the notification. If disabled, the set URL (or + * current) is loaded directly. + * + * @param communicationErrorNotificationEnabled + * true = enabled, false = disabled + */ + public void setCommunicationErrorNotificationEnabled( + boolean communicationErrorNotificationEnabled) { + this.communicationErrorNotificationEnabled = communicationErrorNotificationEnabled; + } + + /** + * Sets the caption of the notification. Set to null for no caption. If + * both caption and message is null, the notification is disabled; + * + * @param communicationErrorCaption + * the caption + */ + public void setCommunicationErrorCaption( + String communicationErrorCaption) { + this.communicationErrorCaption = communicationErrorCaption; + } + + /** + * Sets the message of the notification. Set to null for no message. If + * both caption and message is null, the notification is disabled; + * + * @param communicationErrorMessage + * the message + */ + public void setCommunicationErrorMessage( + String communicationErrorMessage) { + this.communicationErrorMessage = communicationErrorMessage; + } + + /** + * Sets the URL to go to when an internal error occurs. + * + * @param internalErrorURL + * the URL to go to, or null to reload current + */ + public void setInternalErrorURL(String internalErrorURL) { + this.internalErrorURL = internalErrorURL; + } + + /** + * Enables or disables the notification. If disabled, the set URL (or + * current) is loaded directly. + * + * @param internalErrorNotificationEnabled + * true = enabled, false = disabled + */ + public void setInternalErrorNotificationEnabled( + boolean internalErrorNotificationEnabled) { + this.internalErrorNotificationEnabled = internalErrorNotificationEnabled; + } + + /** + * Sets the caption of the notification. Set to null for no caption. If + * both caption and message is null, the notification is disabled; + * + * @param internalErrorCaption + * the caption + */ + public void setInternalErrorCaption(String internalErrorCaption) { + this.internalErrorCaption = internalErrorCaption; + } + + /** + * Sets the message of the notification. Set to null for no message. If + * both caption and message is null, the notification is disabled; + * + * @param internalErrorMessage + * the message + */ + public void setInternalErrorMessage(String internalErrorMessage) { + this.internalErrorMessage = internalErrorMessage; + } + + /** + * Sets the URL to go to when the client is out-of-sync. + * + * @param outOfSyncURL + * the URL to go to, or null to reload current + */ + public void setOutOfSyncURL(String outOfSyncURL) { + this.outOfSyncURL = outOfSyncURL; + } + + /** + * Enables or disables the notification. If disabled, the set URL (or + * current) is loaded directly. + * + * @param outOfSyncNotificationEnabled + * true = enabled, false = disabled + */ + public void setOutOfSyncNotificationEnabled( + boolean outOfSyncNotificationEnabled) { + this.outOfSyncNotificationEnabled = outOfSyncNotificationEnabled; + } + + /** + * Sets the caption of the notification. Set to null for no caption. If + * both caption and message is null, the notification is disabled; + * + * @param outOfSyncCaption + * the caption + */ + public void setOutOfSyncCaption(String outOfSyncCaption) { + this.outOfSyncCaption = outOfSyncCaption; + } + + /** + * Sets the message of the notification. Set to null for no message. If + * both caption and message is null, the notification is disabled; + * + * @param outOfSyncMessage + * the message + */ + public void setOutOfSyncMessage(String outOfSyncMessage) { + this.outOfSyncMessage = outOfSyncMessage; + } + + /** + * Sets the URL to redirect to when the browser has cookies disabled. + * + * @param cookiesDisabledURL + * the URL to redirect to, or null to reload the current URL + */ + public void setCookiesDisabledURL(String cookiesDisabledURL) { + this.cookiesDisabledURL = cookiesDisabledURL; + } + + /** + * Enables or disables the notification for "cookies disabled" messages. + * If disabled, the URL returned by {@link #getCookiesDisabledURL()} is + * loaded directly. + * + * @param cookiesDisabledNotificationEnabled + * true to enable "cookies disabled" messages, false + * otherwise + */ + public void setCookiesDisabledNotificationEnabled( + boolean cookiesDisabledNotificationEnabled) { + this.cookiesDisabledNotificationEnabled = cookiesDisabledNotificationEnabled; + } + + /** + * Sets the caption of the "cookies disabled" notification. Set to null + * for no caption. If both caption and message is null, the notification + * is disabled. + * + * @param cookiesDisabledCaption + * the caption for the "cookies disabled" notification + */ + public void setCookiesDisabledCaption(String cookiesDisabledCaption) { + this.cookiesDisabledCaption = cookiesDisabledCaption; + } + + /** + * Sets the message of the "cookies disabled" notification. Set to null + * for no message. If both caption and message is null, the notification + * is disabled. + * + * @param cookiesDisabledMessage + * the message for the "cookies disabled" notification + */ + public void setCookiesDisabledMessage(String cookiesDisabledMessage) { + this.cookiesDisabledMessage = cookiesDisabledMessage; + } + + } + + /** + * Application error is an error message defined on the application level. + * + * When an error occurs on the application level, this error message type + * should be used. This indicates that the problem is caused by the + * application - not by the user. + */ + public class ApplicationError implements Terminal.ErrorEvent { + private final Throwable throwable; + + public ApplicationError(Throwable throwable) { + this.throwable = throwable; + } + + @Override + public Throwable getThrowable() { + return throwable; + } + + } + + /** + * Gets the UI class for a request for which no UI is already known. This + * method is called when the framework processes a request that does not + * originate from an existing UI instance. This typically happens when a + * host page is requested. + *

    + * Subclasses of Application may override this method to provide custom + * logic for choosing what kind of UI to use. + *

    + * The default implementation in {@link VaadinSession} uses the + * {@value #UI_PARAMETER} parameter from web.xml for finding the name of the + * UI class. If {@link DeploymentConfiguration#getClassLoader()} does not + * return null, the returned {@link ClassLoader} is used for + * loading the UI class. Otherwise the {@link ClassLoader} used to load this + * class is used. + * + *

    + * + * @param request + * the wrapped request for which a UI is needed + * @return a UI instance to use for the request + * + * @see UI + * @see WrappedRequest#getBrowserDetails() + * + * @since 7.0 + */ + public Class getUIClass(WrappedRequest request) { + UIProvider uiProvider = getUiProvider(request, null); + return uiProvider.getUIClass(this, request); + } + + /** + * Creates an UI instance for a request for which no UI is already known. + * This method is called when the framework processes a request that does + * not originate from an existing UI instance. This typically happens when a + * host page is requested. + *

    + * Subclasses of Application may override this method to provide custom + * logic for choosing how to create a suitable UI or for picking an already + * created UI. If an existing UI is picked, care should be taken to avoid + * keeping the same UI open in multiple browser windows, as that will cause + * the states to go out of sync. + *

    + * + * @param request + * @param uiClass + * @return + */ + protected T createUIInstance(WrappedRequest request, + Class uiClass) { + UIProvider uiProvider = getUiProvider(request, uiClass); + return uiClass.cast(uiProvider.createInstance(this, uiClass, request)); + } + + /** + * Gets the {@link UIProvider} that should be used for a request. The + * selection can further be restricted by also requiring the UI provider to + * support a specific UI class. + * + * @see UIProvider + * @see #addUIProvider(UIProvider) + * + * @param request + * the request for which to get an UI provider + * @param uiClass + * the UI class for which a provider is required, or + * null to use the first UI provider supporting the + * request. + * @return an UI provider supporting the request (and the UI class if + * provided). + * + * @since 7.0.0 + */ + public UIProvider getUiProvider(WrappedRequest request, Class uiClass) { + UIProvider provider = (UIProvider) request + .getAttribute(UIProvider.class.getName()); + if (provider != null) { + // Cached provider found, verify that it's a sensible selection + Class providerClass = provider.getUIClass(this, + request); + if (uiClass == null && providerClass != null) { + // Use it if it gives any answer if no specific class is + // required + return provider; + } else if (uiClass == providerClass) { + // Use it if it gives the expected UI class + return provider; + } else { + // Don't keep it cached if it doesn't match the expectations + request.setAttribute(UIProvider.class.getName(), null); + } + } + + // Iterate all current providers if no matching cached provider found + provider = doGetUiProvider(request, uiClass); + + // Cache the found provider + request.setAttribute(UIProvider.class.getName(), provider); + + return provider; + } + + private UIProvider doGetUiProvider(WrappedRequest request, Class uiClass) { + int providersSize = uiProviders.size(); + if (providersSize == 0) { + throw new IllegalStateException("There are no UI providers"); + } + + for (int i = providersSize - 1; i >= 0; i--) { + UIProvider provider = uiProviders.get(i); + + Class providerClass = provider.getUIClass(this, + request); + // If we found something + if (providerClass != null) { + if (uiClass == null) { + // Not looking for anything particular -> anything is ok + return provider; + } else if (providerClass == uiClass) { + // Looking for a specific provider -> only use if matching + return provider; + } else { + getLogger().warning( + "Mismatching UI classes. Expected " + uiClass + + " but got " + providerClass + " from " + + provider); + // Continue looking + } + } + } + + throw new RuntimeException("No UI provider found for request"); + } + + /** + * Handles a request by passing it to each registered {@link RequestHandler} + * in turn until one produces a response. This method is used for requests + * that have not been handled by any specific functionality in the terminal + * implementation (e.g. {@link VaadinServlet}). + *

    + * The request handlers are invoked in the revere order in which they were + * added to the application until a response has been produced. This means + * that the most recently added handler is used first and the first request + * handler that was added to the application is invoked towards the end + * unless any previous handler has already produced a response. + *

    + * + * @param request + * the wrapped request to get information from + * @param response + * the response to which data can be written + * @return returns true if a {@link RequestHandler} has + * produced a response and false if no response has + * been written. + * @throws IOException + * + * @see #addRequestHandler(RequestHandler) + * @see RequestHandler + * + * @since 7.0 + */ + public boolean handleRequest(WrappedRequest request, + WrappedResponse response) throws IOException { + // Use a copy to avoid ConcurrentModificationException + for (RequestHandler handler : new ArrayList( + requestHandlers)) { + if (handler.handleRequest(this, request, response)) { + return true; + } + } + // If not handled + return false; + } + + /** + * Adds a request handler to this application. Request handlers can be added + * to provide responses to requests that are not handled by the default + * functionality of the framework. + *

    + * Handlers are called in reverse order of addition, so the most recently + * added handler will be called first. + *

    + * + * @param handler + * the request handler to add + * + * @see #handleRequest(WrappedRequest, WrappedResponse) + * @see #removeRequestHandler(RequestHandler) + * + * @since 7.0 + */ + public void addRequestHandler(RequestHandler handler) { + requestHandlers.addFirst(handler); + } + + /** + * Removes a request handler from the application. + * + * @param handler + * the request handler to remove + * + * @since 7.0 + */ + public void removeRequestHandler(RequestHandler handler) { + requestHandlers.remove(handler); + } + + /** + * Gets the request handlers that are registered to the application. The + * iteration order of the returned collection is the same as the order in + * which the request handlers will be invoked when a request is handled. + * + * @return a collection of request handlers, with the iteration order + * according to the order they would be invoked + * + * @see #handleRequest(WrappedRequest, WrappedResponse) + * @see #addRequestHandler(RequestHandler) + * @see #removeRequestHandler(RequestHandler) + * + * @since 7.0 + */ + public Collection getRequestHandlers() { + return Collections.unmodifiableCollection(requestHandlers); + } + + /** + * Gets the currently used application. The current application is + * automatically defined when processing requests to the server. In other + * cases, (e.g. from background threads), the current application is not + * automatically defined. + * + * @return the current application instance if available, otherwise + * null + * + * @see #setCurrent(VaadinSession) + * + * @since 7.0 + */ + public static VaadinSession getCurrent() { + return CurrentInstance.get(VaadinSession.class); + } + + /** + * Sets the thread local for the current application. This method is used by + * the framework to set the current application whenever a new request is + * processed and it is cleared when the request has been processed. + *

    + * The application developer can also use this method to define the current + * application outside the normal request handling, e.g. when initiating + * custom background threads. + *

    + * + * @param application + * + * @see #getCurrent() + * @see ThreadLocal + * + * @since 7.0 + */ + public static void setCurrent(VaadinSession application) { + CurrentInstance.setInheritable(VaadinSession.class, application); + } + + /** + * Check whether this application is in production mode. If an application + * is in production mode, certain debugging facilities are not available. + * + * @return the status of the production mode flag + * + * @since 7.0 + */ + public boolean isProductionMode() { + return configuration.isProductionMode(); + } + + public void addUIProvider(UIProvider uIProvider) { + uiProviders.add(uIProvider); + } + + public void removeUIProvider(UIProvider uIProvider) { + uiProviders.remove(uIProvider); + } + + /** + * Finds the {@link UI} to which a particular request belongs. If the + * request originates from an existing UI, that UI is returned. In other + * cases, the method attempts to create and initialize a new UI and might + * throw a {@link UIRequiresMoreInformationException} if all required + * information is not available. + *

    + * Please note that this method can also return a newly created + * UI which has not yet been initialized. You can use + * {@link #isUIInitPending(int)} with the UI's id ( {@link UI#getUIId()} to + * check whether the initialization is still pending. + *

    + * + * @param request + * the request for which a UI is desired + * @return a UI belonging to the request + * + * @see #createUI(WrappedRequest) + * + * @since 7.0 + */ + public UI getUIForRequest(WrappedRequest request) { + UI uI = UI.getCurrent(); + if (uI != null) { + return uI; + } + Integer uiId = getUIId(request); + + synchronized (this) { + uI = uIs.get(uiId); + + if (uI == null) { + uI = findExistingUi(request); + } + + } // end synchronized block + + UI.setCurrent(uI); + + return uI; + } + + private UI findExistingUi(WrappedRequest request) { + // Check if some UI provider has an existing UI available + for (int i = uiProviders.size() - 1; i >= 0; i--) { + UIProvider provider = uiProviders.get(i); + UI existingUi = provider.getExistingUI(request); + if (existingUi != null) { + return existingUi; + } + } + + BrowserDetails browserDetails = request.getBrowserDetails(); + boolean hasBrowserDetails = browserDetails != null + && browserDetails.getUriFragment() != null; + + if (hasBrowserDetails && !retainOnRefreshUIs.isEmpty()) { + // Check for a known UI + + @SuppressWarnings("null") + String windowName = browserDetails.getWindowName(); + Integer retainedUIId = retainOnRefreshUIs.get(windowName); + + if (retainedUIId != null) { + Class expectedUIClass = getUIClass(request); + UI retainedUI = uIs.get(retainedUIId); + // We've had the same UI instance in a window with this + // name, but should we still use it? + if (retainedUI.getClass() == expectedUIClass) { + return retainedUI; + } else { + getLogger().info( + "Not using retained UI in " + windowName + + " because retained UI was of type " + + retainedUIId.getClass() + " but " + + expectedUIClass + + " is expected for the request."); + } + } + } + + return null; + } + + public UI createUI(WrappedRequest request) { + Class uiClass = getUIClass(request); + + UI ui = createUIInstance(request, uiClass); + + // Initialize some fields for a newly created UI + if (ui.getApplication() == null) { + ui.setApplication(this); + } + // Get the next id + Integer uiId = Integer.valueOf(nextUIId++); + + uIs.put(uiId, ui); + + // Set thread local here so it is available in init + UI.setCurrent(ui); + + ui.doInit(request, uiId.intValue()); + + if (getUiProvider(request, uiClass).isUiPreserved(request, uiClass)) { + // Remember this UI + String windowName = request.getBrowserDetails().getWindowName(); + if (windowName == null) { + getLogger().warning( + "There is no window.name available for UI " + uiClass + + " that should be preserved."); + } else { + retainOnRefreshUIs.put(windowName, uiId); + } + } + + return ui; + } + + /** + * Internal helper to finds the UI id for a request. + * + * @param request + * the request to get the UI id for + * @return a UI id, or null if no UI id is defined + * + * @since 7.0 + */ + private static Integer getUIId(WrappedRequest request) { + if (request instanceof CombinedRequest) { + // Combined requests has the uiId parameter in the second request + CombinedRequest combinedRequest = (CombinedRequest) request; + request = combinedRequest.getSecondRequest(); + } + String uiIdString = request.getParameter(UIConstants.UI_ID_PARAMETER); + Integer uiId = uiIdString == null ? null : new Integer(uiIdString); + return uiId; + } + + /** + * Gets all the uIs of this application. This includes uIs that have been + * requested but not yet initialized. Please note, that uIs are not + * automatically removed e.g. if the browser window is closed and that there + * is no way to manually remove a UI. Inactive uIs will thus not be released + * for GC until the entire application is released when the session has + * timed out (unless there are dangling references). Improved support for + * releasing unused uIs is planned for an upcoming alpha release of Vaadin + * 7. + * + * @return a collection of uIs belonging to this application + * + * @since 7.0 + */ + public Collection getUIs() { + return Collections.unmodifiableCollection(uIs.values()); + } + + private int connectorIdSequence = 0; + + /** + * Generate an id for the given Connector. Connectors must not call this + * method more than once, the first time they need an id. + * + * @param connector + * A connector that has not yet been assigned an id. + * @return A new id for the connector + */ + public String createConnectorId(ClientConnector connector) { + return String.valueOf(connectorIdSequence++); + } + + private static final Logger getLogger() { + return Logger.getLogger(VaadinSession.class.getName()); + } + + /** + * Returns a UI with the given id. + *

    + * This is meant for framework internal use. + *

    + * + * @param uiId + * The UI id + * @return The UI with the given id or null if not found + */ + public UI getUIById(int uiId) { + return uIs.get(uiId); + } + + /** + * Adds a listener that will be invoked when the bootstrap HTML is about to + * be generated. This can be used to modify the contents of the HTML that + * loads the Vaadin application in the browser and the HTTP headers that are + * included in the response serving the HTML. + * + * @see BootstrapListener#modifyBootstrapFragment(BootstrapFragmentResponse) + * @see BootstrapListener#modifyBootstrapPage(BootstrapPageResponse) + * + * @param listener + * the bootstrap listener to add + */ + public void addBootstrapListener(BootstrapListener listener) { + eventRouter.addListener(BootstrapFragmentResponse.class, listener, + BOOTSTRAP_FRAGMENT_METHOD); + eventRouter.addListener(BootstrapPageResponse.class, listener, + BOOTSTRAP_PAGE_METHOD); + } + + /** + * Remove a bootstrap listener that was previously added. + * + * @see #addBootstrapListener(BootstrapListener) + * + * @param listener + * the bootstrap listener to remove + */ + public void removeBootstrapListener(BootstrapListener listener) { + eventRouter.removeListener(BootstrapFragmentResponse.class, listener, + BOOTSTRAP_FRAGMENT_METHOD); + eventRouter.removeListener(BootstrapPageResponse.class, listener, + BOOTSTRAP_PAGE_METHOD); + } + + /** + * Fires a bootstrap event to all registered listeners. There are currently + * two supported events, both inheriting from {@link BootstrapResponse}: + * {@link BootstrapFragmentResponse} and {@link BootstrapPageResponse}. + * + * @param response + * the bootstrap response event for which listeners should be + * fired + */ + public void modifyBootstrapResponse(BootstrapResponse response) { + eventRouter.fireEvent(response); + } + + /** + * Removes all those UIs from the application for which {@link #isUIAlive} + * returns false. Close events are fired for the removed UIs. + *

    + * Called by the framework at the end of every request. + * + * @see UI.CloseEvent + * @see UI.CloseListener + * @see #isUIAlive(UI) + * + * @since 7.0.0 + */ + public void closeInactiveUIs() { + for (Iterator i = uIs.values().iterator(); i.hasNext();) { + UI ui = i.next(); + if (!isUIAlive(ui)) { + i.remove(); + retainOnRefreshUIs.values().remove(ui.getUIId()); + ui.fireCloseEvent(); + getLogger().info( + "Closed UI #" + ui.getUIId() + " due to inactivity"); + } + } + } + + /** + * Returns the number of seconds that must pass without a valid heartbeat or + * UIDL request being received from a UI before that UI is removed from the + * application. This is a lower bound; it might take longer to close an + * inactive UI. Returns a negative number if heartbeat is disabled and + * timeout never occurs. + * + * @see #getUidlRequestTimeout() + * @see #closeInactiveUIs() + * @see DeploymentConfiguration#getHeartbeatInterval() + * + * @since 7.0.0 + * + * @return The heartbeat timeout in seconds or a negative number if timeout + * never occurs. + */ + protected int getHeartbeatTimeout() { + // Permit three missed heartbeats before closing the UI + return (int) (configuration.getHeartbeatInterval() * (3.1)); + } + + /** + * Returns the number of seconds that must pass without a valid UIDL request + * being received from a UI before the UI is removed from the application, + * even though heartbeat requests are received. This is a lower bound; it + * might take longer to close an inactive UI. Returns a negative number if + *

    + * This timeout only has effect if cleanup of inactive UIs is enabled; + * otherwise heartbeat requests are enough to extend UI lifetime + * indefinitely. + * + * @see DeploymentConfiguration#isIdleUICleanupEnabled() + * @see #getHeartbeatTimeout() + * @see #closeInactiveUIs() + * + * @since 7.0.0 + * + * @return The UIDL request timeout in seconds, or a negative number if + * timeout never occurs. + */ + protected int getUidlRequestTimeout() { + return configuration.isIdleUICleanupEnabled() ? getSession() + .getMaxInactiveInterval() : -1; + } + + /** + * Returns whether the given UI is alive (the client-side actively + * communicates with the server) or whether it can be removed from the + * application and eventually collected. + * + * @since 7.0.0 + * + * @param ui + * The UI whose status to check + * @return true if the UI is alive, false if it could be removed. + */ + protected boolean isUIAlive(UI ui) { + long now = System.currentTimeMillis(); + if (getHeartbeatTimeout() >= 0 + && now - ui.getLastHeartbeatTime() > 1000 * getHeartbeatTimeout()) { + return false; + } + if (getUidlRequestTimeout() >= 0 + && now - ui.getLastUidlRequestTime() > 1000 * getUidlRequestTimeout()) { + return false; + } + return true; + } + + /** + * Gets this application's global resource handler that takes care of + * serving connector resources that are not served by any single connector + * because e.g. because they are served with strong caching or because of + * legacy reasons. + * + * @param createOnDemand + * true if a resource handler should be initialized + * if there is no handler associated with this application. + * false if null should be returned + * if there is no registered handler. + * @return this application's global resource handler, or null + * if there is no handler and the createOnDemand parameter is + * false. + * + * @since 7.0.0 + */ + public GlobalResourceHandler getGlobalResourceHandler(boolean createOnDemand) { + if (globalResourceHandler == null && createOnDemand) { + globalResourceHandler = new GlobalResourceHandler(); + addRequestHandler(globalResourceHandler); + } + + return globalResourceHandler; + } + + public Collection getUIProviders() { + return Collections.unmodifiableCollection(uiProviders); + } + +} diff --git a/server/src/com/vaadin/server/WrappedHttpServletRequest.java b/server/src/com/vaadin/server/WrappedHttpServletRequest.java index 05d9b13736..4221551601 100644 --- a/server/src/com/vaadin/server/WrappedHttpServletRequest.java +++ b/server/src/com/vaadin/server/WrappedHttpServletRequest.java @@ -19,7 +19,6 @@ package com.vaadin.server; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; -import com.vaadin.Application; /** * Wrapper for {@link HttpServletRequest}. @@ -89,7 +88,7 @@ public class WrappedHttpServletRequest extends HttpServletRequestWrapper @Override public WebBrowser getWebBrowser() { - return Application.getCurrent().getBrowser(); + return VaadinSession.getCurrent().getBrowser(); } }; } diff --git a/server/src/com/vaadin/server/WrappedPortletRequest.java b/server/src/com/vaadin/server/WrappedPortletRequest.java index dffbebb379..65099add76 100644 --- a/server/src/com/vaadin/server/WrappedPortletRequest.java +++ b/server/src/com/vaadin/server/WrappedPortletRequest.java @@ -25,7 +25,6 @@ import javax.portlet.ClientDataRequest; import javax.portlet.PortletRequest; import javax.portlet.ResourceRequest; -import com.vaadin.Application; import com.vaadin.shared.ApplicationConstants; /** @@ -151,7 +150,7 @@ public class WrappedPortletRequest implements WrappedRequest { @Override public WebBrowser getWebBrowser() { - PortletApplicationContext2 context = (PortletApplicationContext2) Application + VaadinPortletSession context = (VaadinPortletSession) VaadinSession .getCurrent(); return context.getBrowser(); } diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java index 37ca9f1a03..e6cc80f1cf 100644 --- a/server/src/com/vaadin/ui/AbstractComponent.java +++ b/server/src/com/vaadin/ui/AbstractComponent.java @@ -27,7 +27,6 @@ import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.vaadin.Application; import com.vaadin.event.ActionManager; import com.vaadin.event.EventRouter; import com.vaadin.event.MethodEventSource; @@ -38,6 +37,7 @@ import com.vaadin.server.ComponentSizeValidator; import com.vaadin.server.ErrorMessage; import com.vaadin.server.Resource; import com.vaadin.server.Terminal; +import com.vaadin.server.VaadinSession; import com.vaadin.shared.ComponentConstants; import com.vaadin.shared.ComponentState; import com.vaadin.shared.ui.ComponentStateUtil; @@ -259,7 +259,7 @@ public abstract class AbstractComponent extends AbstractClientConnector if (parent != null) { return parent.getLocale(); } - final Application app = getApplication(); + final VaadinSession app = getApplication(); if (app != null) { return app.getLocale(); } @@ -616,7 +616,7 @@ public abstract class AbstractComponent extends AbstractClientConnector */ protected void focus() { if (this instanceof Focusable) { - final Application app = getApplication(); + final VaadinSession app = getApplication(); if (app != null) { getUI().setFocusedComponent((Focusable) this); delayedFocus = false; @@ -646,7 +646,7 @@ public abstract class AbstractComponent extends AbstractClientConnector * @see #attach() */ @Override - public Application getApplication() { + public VaadinSession getApplication() { // Just make method inherited from Component interface public return super.getApplication(); } diff --git a/server/src/com/vaadin/ui/Component.java b/server/src/com/vaadin/ui/Component.java index 5bd1d53b86..812edbb8d2 100644 --- a/server/src/com/vaadin/ui/Component.java +++ b/server/src/com/vaadin/ui/Component.java @@ -21,12 +21,12 @@ import java.util.EventListener; import java.util.EventObject; import java.util.Locale; -import com.vaadin.Application; import com.vaadin.event.FieldEvents; import com.vaadin.server.ClientConnector; import com.vaadin.server.ErrorMessage; import com.vaadin.server.Resource; import com.vaadin.server.Sizeable; +import com.vaadin.server.VaadinSession; import com.vaadin.server.VariableOwner; /** @@ -532,7 +532,7 @@ public interface Component extends ClientConnector, Sizeable, Serializable { *

    * Getting a null value is often a problem in constructors of regular * components and in the initializers of custom composite components. A - * standard workaround is to use {@link Application#getCurrent()} to + * standard workaround is to use {@link VaadinSession#getCurrent()} to * retrieve the application instance that the current request relates to. * Another way is to move the problematic initialization to * {@link #attach()}, as described in the documentation of the method. @@ -541,7 +541,7 @@ public interface Component extends ClientConnector, Sizeable, Serializable { * @return the parent application of the component or null. * @see #attach() */ - public Application getApplication(); + public VaadinSession getApplication(); /** * {@inheritDoc} diff --git a/server/src/com/vaadin/ui/LoginForm.java b/server/src/com/vaadin/ui/LoginForm.java index 61846eab4e..1d0c5c41b6 100644 --- a/server/src/com/vaadin/ui/LoginForm.java +++ b/server/src/com/vaadin/ui/LoginForm.java @@ -24,10 +24,10 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import com.vaadin.Application; import com.vaadin.server.ConnectorResource; import com.vaadin.server.DownloadStream; import com.vaadin.server.RequestHandler; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.server.WrappedResponse; import com.vaadin.shared.ApplicationConstants; @@ -83,7 +83,7 @@ public class LoginForm extends CustomComponent { private final RequestHandler requestHandler = new RequestHandler() { @Override - public boolean handleRequest(Application application, + public boolean handleRequest(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException { String requestPathInfo = request.getRequestPathInfo(); diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index 7389a898eb..e2d79454f6 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -27,7 +27,6 @@ import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Map; -import com.vaadin.Application; import com.vaadin.LegacyApplication; import com.vaadin.event.Action; import com.vaadin.event.Action.Handler; @@ -42,6 +41,7 @@ import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.server.Resource; import com.vaadin.server.VaadinServlet; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.server.WrappedRequest.BrowserDetails; import com.vaadin.shared.EventId; @@ -66,9 +66,9 @@ import com.vaadin.util.ReflectTools; *

    * When a new UI instance is needed, typically because the user opens a URL in a * browser window which points to {@link VaadinServlet}, - * {@link Application#getUIForRequest(WrappedRequest)} is invoked to get a UI. + * {@link VaadinSession#getUIForRequest(WrappedRequest)} is invoked to get a UI. * That method does by default create a UI according to the - * {@value Application#UI_PARAMETER} parameter from web.xml. + * {@value VaadinSession#UI_PARAMETER} parameter from web.xml. *

    *

    * After a UI has been created by the application, it is initialized using @@ -80,7 +80,7 @@ import com.vaadin.util.ReflectTools; *

    * * @see #init(WrappedRequest) - * @see Application#createUI(WrappedRequest) + * @see VaadinSession#createUI(WrappedRequest) * * @since 7.0 */ @@ -135,7 +135,7 @@ public abstract class UI extends AbstractComponentContainer implements * The name also determines the URL that can be used for direct access * to a window. All windows can be accessed through * {@code http://host:port/app/win} where {@code http://host:port/app} - * is the application URL (as returned by {@link Application#getURL()} + * is the application URL (as returned by {@link VaadinSession#getURL()} * and {@code win} is the window name. *

    *

    @@ -155,7 +155,7 @@ public abstract class UI extends AbstractComponentContainer implements * The name also determines the URL that can be used for direct access * to a window. All windows can be accessed through * {@code http://host:port/app/win} where {@code http://host:port/app} - * is the application URL (as returned by {@link Application#getURL()} + * is the application URL (as returned by {@link VaadinSession#getURL()} * and {@code win} is the window name. *

    *

    @@ -193,7 +193,7 @@ public abstract class UI extends AbstractComponentContainer implements * to an application */ public URL getURL() { - Application application = getApplication(); + VaadinSession application = getApplication(); if (application == null) { return null; } @@ -424,7 +424,7 @@ public abstract class UI extends AbstractComponentContainer implements /** * The application to which this UI belongs */ - private Application application; + private VaadinSession application; /** * List of windows in this UI. @@ -442,7 +442,7 @@ public abstract class UI extends AbstractComponentContainer implements * which a request originates. A negative value indicates that the UI id has * not yet been assigned by the Application. * - * @see Application#nextUIId + * @see VaadinSession#nextUIId */ private int uiId = -1; @@ -564,7 +564,7 @@ public abstract class UI extends AbstractComponentContainer implements } @Override - public Application getApplication() { + public VaadinSession getApplication() { return application; } @@ -684,7 +684,7 @@ public abstract class UI extends AbstractComponentContainer implements * * @see #getApplication() */ - public void setApplication(Application application) { + public void setApplication(VaadinSession application) { if ((application == null) == (this.application == null)) { throw new IllegalStateException("Application has already been set"); } else { @@ -703,7 +703,7 @@ public abstract class UI extends AbstractComponentContainer implements * Gets the id of the UI, used to identify this UI within its application * when processing requests. The UI id should be present in every request to * the server that originates from this UI. - * {@link Application#getUIForRequest(WrappedRequest)} uses this id to find + * {@link VaadinSession#getUIForRequest(WrappedRequest)} uses this id to find * the route to which the request belongs. * * @return @@ -716,7 +716,7 @@ public abstract class UI extends AbstractComponentContainer implements * Adds a window as a subwindow inside this UI. To open a new browser window * or tab, you should instead use {@link open(Resource)} with an url * pointing to this application and ensure - * {@link Application#createUI(WrappedRequest)} returns an appropriate UI + * {@link VaadinSession#createUI(WrappedRequest)} returns an appropriate UI * for the request. * * @param window @@ -1294,7 +1294,7 @@ public abstract class UI extends AbstractComponentContainer implements * heartbeat for this UI. * * @see #heartbeat() - * @see Application#closeInactiveUIs() + * @see VaadinSession#closeInactiveUIs() * * @return The time the last heartbeat request occurred. */ diff --git a/server/tests/src/com/vaadin/tests/VaadinClasses.java b/server/tests/src/com/vaadin/tests/VaadinClasses.java index 15e1283e47..b30ddcee7e 100644 --- a/server/tests/src/com/vaadin/tests/VaadinClasses.java +++ b/server/tests/src/com/vaadin/tests/VaadinClasses.java @@ -15,7 +15,7 @@ import java.util.Enumeration; import java.util.List; import java.util.jar.JarEntry; -import com.vaadin.Application; +import com.vaadin.server.VaadinSession; import com.vaadin.ui.Component; import com.vaadin.ui.ComponentContainer; import com.vaadin.ui.CustomComponent; @@ -144,7 +144,7 @@ public class VaadinClasses { String basePackage, String[] ignoredPackages) throws IOException { List> classes = new ArrayList>(); String basePackageDirName = "/" + basePackage.replace('.', '/'); - URL location = Application.class.getResource(basePackageDirName); + URL location = VaadinSession.class.getResource(basePackageDirName); if (location.getProtocol().equals("file")) { try { File f = new File(location.toURI()); diff --git a/server/tests/src/com/vaadin/tests/data/converter/ConverterFactory.java b/server/tests/src/com/vaadin/tests/data/converter/ConverterFactory.java index 6393d61981..66160907b2 100644 --- a/server/tests/src/com/vaadin/tests/data/converter/ConverterFactory.java +++ b/server/tests/src/com/vaadin/tests/data/converter/ConverterFactory.java @@ -19,9 +19,9 @@ import java.util.Locale; import junit.framework.TestCase; -import com.vaadin.Application; import com.vaadin.data.util.converter.Converter; import com.vaadin.data.util.converter.DefaultConverterFactory; +import com.vaadin.server.VaadinSession; import com.vaadin.ui.TextField; public class ConverterFactory extends TestCase { @@ -65,14 +65,14 @@ public class ConverterFactory extends TestCase { } public void testApplicationConverterFactoryInBackgroundThread() { - Application.setCurrent(null); - final Application appWithCustomIntegerConverter = new Application(); + VaadinSession.setCurrent(null); + final VaadinSession appWithCustomIntegerConverter = new VaadinSession(); appWithCustomIntegerConverter .setConverterFactory(new ConverterFactory42()); TextField tf = new TextField("", "123") { @Override - public Application getApplication() { + public VaadinSession getApplication() { return appWithCustomIntegerConverter; }; }; @@ -83,10 +83,10 @@ public class ConverterFactory extends TestCase { } public void testApplicationConverterFactoryForDetachedComponent() { - final Application appWithCustomIntegerConverter = new Application(); + final VaadinSession appWithCustomIntegerConverter = new VaadinSession(); appWithCustomIntegerConverter .setConverterFactory(new ConverterFactory42()); - Application.setCurrent(appWithCustomIntegerConverter); + VaadinSession.setCurrent(appWithCustomIntegerConverter); TextField tf = new TextField("", "123"); tf.setConverter(Integer.class); @@ -96,14 +96,14 @@ public class ConverterFactory extends TestCase { } public void testApplicationConverterFactoryForDifferentThanCurrentApplication() { - final Application fieldAppWithCustomIntegerConverter = new Application(); + final VaadinSession fieldAppWithCustomIntegerConverter = new VaadinSession(); fieldAppWithCustomIntegerConverter .setConverterFactory(new ConverterFactory42()); - Application.setCurrent(new Application()); + VaadinSession.setCurrent(new VaadinSession()); TextField tf = new TextField("", "123") { @Override - public Application getApplication() { + public VaadinSession getApplication() { return fieldAppWithCustomIntegerConverter; } }; diff --git a/server/tests/src/com/vaadin/tests/server/TestStreamVariableMapping.java b/server/tests/src/com/vaadin/tests/server/TestStreamVariableMapping.java index 775348fb5c..e286e7231e 100644 --- a/server/tests/src/com/vaadin/tests/server/TestStreamVariableMapping.java +++ b/server/tests/src/com/vaadin/tests/server/TestStreamVariableMapping.java @@ -4,9 +4,9 @@ import junit.framework.TestCase; import org.easymock.EasyMock; -import com.vaadin.Application; import com.vaadin.server.CommunicationManager; import com.vaadin.server.StreamVariable; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.ui.UI; import com.vaadin.ui.Upload; @@ -21,7 +21,7 @@ public class TestStreamVariableMapping extends TestCase { @Override protected void setUp() throws Exception { - final Application application = new Application(); + final VaadinSession application = new VaadinSession(); final UI uI = new UI() { @Override protected void init(WrappedRequest request) { @@ -30,7 +30,7 @@ public class TestStreamVariableMapping extends TestCase { } @Override - public Application getApplication() { + public VaadinSession getApplication() { return application; } }; @@ -66,7 +66,7 @@ public class TestStreamVariableMapping extends TestCase { } private CommunicationManager createCommunicationManager() { - return new CommunicationManager(new Application()); + return new CommunicationManager(new VaadinSession()); } } diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java index 57af748247..d372b96339 100644 --- a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java +++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java @@ -4,10 +4,10 @@ import java.util.Locale; import junit.framework.TestCase; -import com.vaadin.Application; import com.vaadin.data.util.MethodProperty; import com.vaadin.data.util.converter.Converter; import com.vaadin.data.util.converter.StringToIntegerConverter; +import com.vaadin.server.VaadinSession; import com.vaadin.tests.data.bean.Address; import com.vaadin.tests.data.bean.Country; import com.vaadin.tests.data.bean.Person; @@ -186,11 +186,11 @@ public class AbstractFieldValueConversions extends TestCase { } public void testNumberDoubleConverterChange() { - final Application a = new Application(); - Application.setCurrent(a); + final VaadinSession a = new VaadinSession(); + VaadinSession.setCurrent(a); TextField tf = new TextField() { @Override - public Application getApplication() { + public VaadinSession getApplication() { return a; } }; diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactory.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactory.java index 25430fc9a5..a1b6541ee0 100644 --- a/server/tests/src/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactory.java +++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/DefaultConverterFactory.java @@ -5,8 +5,8 @@ import java.util.Locale; import junit.framework.TestCase; -import com.vaadin.Application; import com.vaadin.data.util.MethodProperty; +import com.vaadin.server.VaadinSession; import com.vaadin.tests.data.bean.Address; import com.vaadin.tests.data.bean.Country; import com.vaadin.tests.data.bean.Person; @@ -26,8 +26,8 @@ public class DefaultConverterFactory extends TestCase { } public void testDefaultNumberConversion() { - Application app = new Application(); - Application.setCurrent(app); + VaadinSession app = new VaadinSession(); + VaadinSession.setCurrent(app); TextField tf = new TextField(); tf.setLocale(new Locale("en", "US")); tf.setPropertyDataSource(new MethodProperty(paulaBean, diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java index 18567b62f0..b498bbe73f 100644 --- a/server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java +++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java @@ -4,10 +4,10 @@ import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.vaadin.Application; import com.vaadin.data.Property; import com.vaadin.data.util.AbstractProperty; import com.vaadin.data.util.converter.Converter.ConversionException; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.ui.AbstractField; import com.vaadin.ui.UI; @@ -18,7 +18,7 @@ public class RemoveListenersOnDetach { int numReadOnlyChanges = 0; AbstractField field = new AbstractField() { - final private Application application = new Application() { + final private VaadinSession application = new VaadinSession() { }; private UI uI = new UI() { @@ -29,7 +29,7 @@ public class RemoveListenersOnDetach { } @Override - public Application getApplication() { + public VaadinSession getApplication() { return application; } @@ -59,7 +59,7 @@ public class RemoveListenersOnDetach { }; @Override - public Application getApplication() { + public VaadinSession getApplication() { return application; }; }; diff --git a/server/tests/src/com/vaadin/tests/server/component/label/LabelConverters.java b/server/tests/src/com/vaadin/tests/server/component/label/LabelConverters.java index 48279c7c88..22cd450af7 100644 --- a/server/tests/src/com/vaadin/tests/server/component/label/LabelConverters.java +++ b/server/tests/src/com/vaadin/tests/server/component/label/LabelConverters.java @@ -17,9 +17,9 @@ package com.vaadin.tests.server.component.label; import junit.framework.TestCase; -import com.vaadin.Application; import com.vaadin.data.Property; import com.vaadin.data.util.MethodProperty; +import com.vaadin.server.VaadinSession; import com.vaadin.tests.data.bean.Person; import com.vaadin.ui.Label; @@ -37,7 +37,7 @@ public class LabelConverters extends TestCase { } public void testIntegerDataSource() { - Application.setCurrent(new Application()); + VaadinSession.setCurrent(new VaadinSession()); Label l = new Label("Foo"); Property ds = new MethodProperty(Person.createTestPerson1(), "age"); diff --git a/server/tests/src/com/vaadin/tests/server/component/root/CustomUIClassLoader.java b/server/tests/src/com/vaadin/tests/server/component/root/CustomUIClassLoader.java index aef35084f8..acc2ed3b14 100644 --- a/server/tests/src/com/vaadin/tests/server/component/root/CustomUIClassLoader.java +++ b/server/tests/src/com/vaadin/tests/server/component/root/CustomUIClassLoader.java @@ -8,13 +8,13 @@ import junit.framework.TestCase; import org.easymock.EasyMock; -import com.vaadin.Application; -import com.vaadin.Application.ApplicationStartEvent; import com.vaadin.DefaultApplicationConfiguration; import com.vaadin.server.ApplicationConfiguration; import com.vaadin.server.DefaultUIProvider; import com.vaadin.server.DeploymentConfiguration; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; +import com.vaadin.server.VaadinSession.ApplicationStartEvent; import com.vaadin.ui.UI; public class CustomUIClassLoader extends TestCase { @@ -53,7 +53,7 @@ public class CustomUIClassLoader extends TestCase { * if thrown */ public void testWithNullClassLoader() throws Exception { - Application application = createStubApplication(); + VaadinSession application = createStubApplication(); application.start(new ApplicationStartEvent(null, createConfigurationMock(), null)); @@ -66,7 +66,7 @@ public class CustomUIClassLoader extends TestCase { private static ApplicationConfiguration createConfigurationMock() { Properties properties = new Properties(); - properties.put(Application.UI_PARAMETER, MyUI.class.getName()); + properties.put(VaadinSession.UI_PARAMETER, MyUI.class.getName()); return new DefaultApplicationConfiguration(CustomUIClassLoader.class, properties); } @@ -97,7 +97,7 @@ public class CustomUIClassLoader extends TestCase { public void testWithClassLoader() throws Exception { LoggingClassLoader loggingClassLoader = new LoggingClassLoader(); - Application application = createStubApplication(); + VaadinSession application = createStubApplication(); application.start(new ApplicationStartEvent(null, createConfigurationMock(), null)); @@ -112,8 +112,8 @@ public class CustomUIClassLoader extends TestCase { } - private Application createStubApplication() { - return new Application() { + private VaadinSession createStubApplication() { + return new VaadinSession() { @Override public ApplicationConfiguration getConfiguration() { return createConfigurationMock(); diff --git a/server/tests/src/com/vaadin/tests/server/component/window/AttachDetachWindow.java b/server/tests/src/com/vaadin/tests/server/component/window/AttachDetachWindow.java index 0fb0765c9f..bab7ca2c8c 100644 --- a/server/tests/src/com/vaadin/tests/server/component/window/AttachDetachWindow.java +++ b/server/tests/src/com/vaadin/tests/server/component/window/AttachDetachWindow.java @@ -5,7 +5,7 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -import com.vaadin.Application; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.ui.Label; import com.vaadin.ui.UI; @@ -14,7 +14,7 @@ import com.vaadin.ui.Window; public class AttachDetachWindow { - private Application testApp = new Application(); + private VaadinSession testApp = new VaadinSession(); private interface TestContainer { public boolean attachCalled(); @@ -23,7 +23,7 @@ public class AttachDetachWindow { public TestContent getTestContent(); - public Application getApplication(); + public VaadinSession getApplication(); } private class TestWindow extends Window implements TestContainer { diff --git a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java index 34c1cc1fce..4f37a9b505 100644 --- a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java +++ b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java @@ -29,13 +29,13 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import com.vaadin.Application; import com.vaadin.LegacyApplication; import com.vaadin.server.AbstractUIProvider; import com.vaadin.server.ApplicationConfiguration; import com.vaadin.server.LegacyVaadinServlet; -import com.vaadin.server.ServletApplicationContext; +import com.vaadin.server.VaadinServletSession; import com.vaadin.server.UIProvider; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedHttpServletRequest; import com.vaadin.server.WrappedRequest; import com.vaadin.tests.components.TestBase; @@ -113,17 +113,17 @@ public class ApplicationRunnerServlet extends LegacyVaadinServlet { } @Override - protected ServletApplicationContext createApplication( + protected VaadinServletSession createApplication( HttpServletRequest request) throws ServletException { try { final Class classToRun = getClassToRun(); if (UI.class.isAssignableFrom(classToRun)) { - ServletApplicationContext application = new ServletApplicationContext(); + VaadinServletSession application = new VaadinServletSession(); application.addUIProvider(new AbstractUIProvider() { @Override public Class getUIClass( - Application application, WrappedRequest request) { + VaadinSession application, WrappedRequest request) { return (Class) classToRun; } }); @@ -131,7 +131,7 @@ public class ApplicationRunnerServlet extends LegacyVaadinServlet { } else if (LegacyApplication.class.isAssignableFrom(classToRun)) { return super.createApplication(request); } else if (UIProvider.class.isAssignableFrom(classToRun)) { - ServletApplicationContext application = new ServletApplicationContext(); + VaadinServletSession application = new VaadinServletSession(); application .addUIProvider((UIProvider) classToRun.newInstance()); return application; diff --git a/uitest/src/com/vaadin/tests/ModalWindow.java b/uitest/src/com/vaadin/tests/ModalWindow.java index 558989e069..7c9e60c943 100644 --- a/uitest/src/com/vaadin/tests/ModalWindow.java +++ b/uitest/src/com/vaadin/tests/ModalWindow.java @@ -31,7 +31,7 @@ import com.vaadin.ui.Window; * * @author Vaadin Ltd. * @since 4.0.1 - * @see com.vaadin.Application + * @see com.vaadin.server.VaadinSession * @see com.vaadin.ui.Window * @see com.vaadin.ui.Label */ diff --git a/uitest/src/com/vaadin/tests/Parameters.java b/uitest/src/com/vaadin/tests/Parameters.java index 901b0a6dd7..01270456c8 100644 --- a/uitest/src/com/vaadin/tests/Parameters.java +++ b/uitest/src/com/vaadin/tests/Parameters.java @@ -21,10 +21,10 @@ import java.net.URL; import java.util.Iterator; import java.util.Map; -import com.vaadin.Application; import com.vaadin.LegacyApplication; import com.vaadin.server.ExternalResource; import com.vaadin.server.RequestHandler; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.server.WrappedResponse; import com.vaadin.ui.Label; @@ -57,7 +57,7 @@ public class Parameters extends com.vaadin.LegacyApplication setMainWindow(main); // This class acts both as URI handler and parameter handler - Application.getCurrent().addRequestHandler(this); + VaadinSession.getCurrent().addRequestHandler(this); final VerticalLayout layout = new VerticalLayout(); final Label info = new Label("To test URI and Parameter Handlers, " @@ -107,7 +107,7 @@ public class Parameters extends com.vaadin.LegacyApplication } @Override - public boolean handleRequest(Application application, + public boolean handleRequest(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException { context.setValue("Context not available"); diff --git a/uitest/src/com/vaadin/tests/TestBench.java b/uitest/src/com/vaadin/tests/TestBench.java index d5b603db39..098ce4af29 100644 --- a/uitest/src/com/vaadin/tests/TestBench.java +++ b/uitest/src/com/vaadin/tests/TestBench.java @@ -312,7 +312,7 @@ public class TestBench extends com.vaadin.LegacyApplication final Class c = Class.forName(p); if (c.getSuperclass() != null) { if ((c.getSuperclass() - .equals(com.vaadin.Application.class))) { + .equals(com.vaadin.server.VaadinSession.class))) { classes.add(c); } else if ((c.getSuperclass() .equals(com.vaadin.ui.CustomComponent.class))) { diff --git a/uitest/src/com/vaadin/tests/TreeFilesystem.java b/uitest/src/com/vaadin/tests/TreeFilesystem.java index 096952c74c..3d1705381e 100644 --- a/uitest/src/com/vaadin/tests/TreeFilesystem.java +++ b/uitest/src/com/vaadin/tests/TreeFilesystem.java @@ -18,9 +18,9 @@ package com.vaadin.tests; import java.io.File; -import com.vaadin.Application; import com.vaadin.LegacyApplication; import com.vaadin.data.Item; +import com.vaadin.server.VaadinSession; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.tests.util.SampleDirectory; import com.vaadin.ui.Label; @@ -64,7 +64,7 @@ public class TreeFilesystem extends com.vaadin.LegacyApplication // Get sample directory final File sampleDir = SampleDirectory.getDirectory( - Application.getCurrent(), main); + VaadinSession.getCurrent(), main); // populate tree's root node with example directory if (sampleDir != null) { populateNode(sampleDir.getAbsolutePath(), null); diff --git a/uitest/src/com/vaadin/tests/TreeFilesystemContainer.java b/uitest/src/com/vaadin/tests/TreeFilesystemContainer.java index baf73b4383..b61a7a53a5 100644 --- a/uitest/src/com/vaadin/tests/TreeFilesystemContainer.java +++ b/uitest/src/com/vaadin/tests/TreeFilesystemContainer.java @@ -18,10 +18,10 @@ package com.vaadin.tests; import java.io.File; -import com.vaadin.Application; import com.vaadin.LegacyApplication; import com.vaadin.data.util.FilesystemContainer; import com.vaadin.data.util.FilesystemContainer.FileItem; +import com.vaadin.server.VaadinSession; import com.vaadin.tests.util.SampleDirectory; import com.vaadin.ui.Component.Event; import com.vaadin.ui.Component.Listener; @@ -80,7 +80,7 @@ public class TreeFilesystemContainer extends // Get sample directory final File sampleDir = SampleDirectory.getDirectory( - Application.getCurrent(), w); + VaadinSession.getCurrent(), w); // Populate tree with FilesystemContainer final FilesystemContainer fsc = new FilesystemContainer(sampleDir, true); filesystem.setContainerDataSource(fsc); diff --git a/uitest/src/com/vaadin/tests/application/ThreadLocalInstances.java b/uitest/src/com/vaadin/tests/application/ThreadLocalInstances.java index 1eda9e54fe..3adb284f1b 100644 --- a/uitest/src/com/vaadin/tests/application/ThreadLocalInstances.java +++ b/uitest/src/com/vaadin/tests/application/ThreadLocalInstances.java @@ -1,8 +1,8 @@ package com.vaadin.tests.application; -import com.vaadin.Application; import com.vaadin.server.DownloadStream; import com.vaadin.server.PaintException; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.tests.components.AbstractTestCase; import com.vaadin.tests.integration.FlagSeResource; @@ -14,7 +14,7 @@ import com.vaadin.ui.UI; import com.vaadin.ui.UI.LegacyWindow; public class ThreadLocalInstances extends AbstractTestCase { - private static final Application staticInitApplication = Application + private static final VaadinSession staticInitApplication = VaadinSession .getCurrent(); private static final UI staticInitRoot = UI.getCurrent(); @@ -87,10 +87,10 @@ public class ThreadLocalInstances extends AbstractTestCase { } private void reportCurrentStatus(String phase) { - reportStatus(phase, Application.getCurrent(), UI.getCurrent()); + reportStatus(phase, VaadinSession.getCurrent(), UI.getCurrent()); } - private void reportStatus(String phase, Application application, UI uI) { + private void reportStatus(String phase, VaadinSession application, UI uI) { log.log(getState(application, this) + " app in " + phase); log.log(getState(uI, mainWindow) + " root in " + phase); } diff --git a/uitest/src/com/vaadin/tests/applicationcontext/ChangeSessionId.java b/uitest/src/com/vaadin/tests/applicationcontext/ChangeSessionId.java index 96ebe1345f..72e0a215a7 100644 --- a/uitest/src/com/vaadin/tests/applicationcontext/ChangeSessionId.java +++ b/uitest/src/com/vaadin/tests/applicationcontext/ChangeSessionId.java @@ -1,6 +1,6 @@ package com.vaadin.tests.applicationcontext; -import com.vaadin.server.ServletApplicationContext; +import com.vaadin.server.VaadinServletSession; import com.vaadin.tests.components.AbstractTestCase; import com.vaadin.tests.util.Log; import com.vaadin.ui.Button; @@ -32,7 +32,7 @@ public class ChangeSessionId extends AbstractTestCase { loginButton.addListener(new ClickListener() { @Override public void buttonClick(ClickEvent event) { - ServletApplicationContext context = ((ServletApplicationContext) getContext()); + VaadinServletSession context = ((VaadinServletSession) getContext()); String oldSessionId = context.getHttpSession().getId(); context.reinitializeSession(); @@ -55,7 +55,7 @@ public class ChangeSessionId extends AbstractTestCase { } protected String getSessionId() { - return ((ServletApplicationContext) getContext()).getHttpSession().getId(); + return ((VaadinServletSession) getContext()).getHttpSession().getId(); } @Override diff --git a/uitest/src/com/vaadin/tests/components/AbstractTestCase.java b/uitest/src/com/vaadin/tests/components/AbstractTestCase.java index 5dc5fd7128..356b130433 100644 --- a/uitest/src/com/vaadin/tests/components/AbstractTestCase.java +++ b/uitest/src/com/vaadin/tests/components/AbstractTestCase.java @@ -1,7 +1,7 @@ package com.vaadin.tests.components; -import com.vaadin.Application; import com.vaadin.LegacyApplication; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WebBrowser; public abstract class AbstractTestCase extends LegacyApplication { @@ -11,7 +11,7 @@ public abstract class AbstractTestCase extends LegacyApplication { protected abstract Integer getTicketNumber(); protected WebBrowser getBrowser() { - WebBrowser webBrowser = Application.getCurrent().getBrowser(); + WebBrowser webBrowser = VaadinSession.getCurrent().getBrowser(); return webBrowser; } diff --git a/uitest/src/com/vaadin/tests/components/AbstractTestUIProvider.java b/uitest/src/com/vaadin/tests/components/AbstractTestUIProvider.java index 4311cd6a0f..db388405a8 100644 --- a/uitest/src/com/vaadin/tests/components/AbstractTestUIProvider.java +++ b/uitest/src/com/vaadin/tests/components/AbstractTestUIProvider.java @@ -1,7 +1,7 @@ package com.vaadin.tests.components; -import com.vaadin.Application; import com.vaadin.server.AbstractUIProvider; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WebBrowser; public abstract class AbstractTestUIProvider extends AbstractUIProvider { @@ -10,7 +10,7 @@ public abstract class AbstractTestUIProvider extends AbstractUIProvider { protected abstract Integer getTicketNumber(); protected WebBrowser getBrowser() { - WebBrowser webBrowser = Application.getCurrent().getBrowser(); + WebBrowser webBrowser = VaadinSession.getCurrent().getBrowser(); return webBrowser; } } diff --git a/uitest/src/com/vaadin/tests/components/abstractfield/AbstractComponentDataBindingTest.java b/uitest/src/com/vaadin/tests/components/abstractfield/AbstractComponentDataBindingTest.java index 327ed0f86b..2eef498aff 100644 --- a/uitest/src/com/vaadin/tests/components/abstractfield/AbstractComponentDataBindingTest.java +++ b/uitest/src/com/vaadin/tests/components/abstractfield/AbstractComponentDataBindingTest.java @@ -4,11 +4,11 @@ import java.util.HashSet; import java.util.Locale; import java.util.Set; -import com.vaadin.Application; import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.server.VaadinSession; import com.vaadin.tests.components.TestBase; import com.vaadin.tests.util.Log; import com.vaadin.ui.AbstractField; @@ -55,7 +55,7 @@ public abstract class AbstractComponentDataBindingTest extends TestBase } protected void updateLocale(Locale locale) { - Application.getCurrent().setLocale(locale); + VaadinSession.getCurrent().setLocale(locale); for (Component c : fields) { removeComponent(c); } diff --git a/uitest/src/com/vaadin/tests/components/ui/LazyInitUIs.java b/uitest/src/com/vaadin/tests/components/ui/LazyInitUIs.java index b141dc0990..a3ca2420f7 100644 --- a/uitest/src/com/vaadin/tests/components/ui/LazyInitUIs.java +++ b/uitest/src/com/vaadin/tests/components/ui/LazyInitUIs.java @@ -1,7 +1,7 @@ package com.vaadin.tests.components.ui; -import com.vaadin.Application; import com.vaadin.server.ExternalResource; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.tests.components.AbstractTestUIProvider; @@ -20,13 +20,13 @@ public class LazyInitUIs extends AbstractTestUIProvider { } @Override - public UI createInstance(Application application, Class type, + public UI createInstance(VaadinSession application, Class type, WrappedRequest request) { return getUI(request); } @Override - public Class getUIClass(Application application, + public Class getUIClass(VaadinSession application, WrappedRequest request) { return getUI(request).getClass(); } @@ -52,13 +52,13 @@ public class LazyInitUIs extends AbstractTestUIProvider { addComponent(getRequestInfo("NormalUI", request)); Link lazyCreateLink = new Link("Open lazyCreate UI", - new ExternalResource(Application.getCurrent() + new ExternalResource(VaadinSession.getCurrent() .getURL() + "?lazyCreate#lazyCreate")); lazyCreateLink.setTargetName("_blank"); addComponent(lazyCreateLink); Link lazyInitLink = new Link("Open eagerInit UI", - new ExternalResource(Application.getCurrent() + new ExternalResource(VaadinSession.getCurrent() .getURL() + "?eagerInit#eagerInit")); lazyInitLink.setTargetName("_blank"); addComponent(lazyInitLink); diff --git a/uitest/src/com/vaadin/tests/components/ui/UIsInMultipleTabs.java b/uitest/src/com/vaadin/tests/components/ui/UIsInMultipleTabs.java index 9a66e9ad0a..19c85a729d 100644 --- a/uitest/src/com/vaadin/tests/components/ui/UIsInMultipleTabs.java +++ b/uitest/src/com/vaadin/tests/components/ui/UIsInMultipleTabs.java @@ -3,7 +3,7 @@ package com.vaadin.tests.components.ui; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; -import com.vaadin.Application; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.tests.components.AbstractTestUIProvider; import com.vaadin.ui.Label; @@ -11,12 +11,12 @@ import com.vaadin.ui.UI; public class UIsInMultipleTabs extends AbstractTestUIProvider { // No cleanup -> will leak, but shouldn't matter for tests - private static ConcurrentHashMap numberOfUIsOpened = new ConcurrentHashMap(); + private static ConcurrentHashMap numberOfUIsOpened = new ConcurrentHashMap(); public static class TabUI extends UI { @Override protected void init(WrappedRequest request) { - Application application = Application.getCurrent(); + VaadinSession application = VaadinSession.getCurrent(); AtomicInteger count = numberOfUIsOpened.get(application); if (count == null) { numberOfUIsOpened.putIfAbsent(application, new AtomicInteger()); @@ -32,7 +32,7 @@ public class UIsInMultipleTabs extends AbstractTestUIProvider { } @Override - public Class getUIClass(Application application, + public Class getUIClass(VaadinSession application, WrappedRequest request) { return TabUI.class; } diff --git a/uitest/src/com/vaadin/tests/integration/JSR286PortletApplication.java b/uitest/src/com/vaadin/tests/integration/JSR286PortletApplication.java index a296d912bc..f3c7f009c8 100644 --- a/uitest/src/com/vaadin/tests/integration/JSR286PortletApplication.java +++ b/uitest/src/com/vaadin/tests/integration/JSR286PortletApplication.java @@ -21,8 +21,8 @@ import javax.portlet.WindowState; import com.vaadin.LegacyApplication; import com.vaadin.annotations.StyleSheet; import com.vaadin.server.ExternalResource; -import com.vaadin.server.PortletApplicationContext2; -import com.vaadin.server.PortletApplicationContext2.PortletListener; +import com.vaadin.server.VaadinPortletSession; +import com.vaadin.server.VaadinPortletSession.PortletListener; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Embedded; import com.vaadin.ui.Label; @@ -87,8 +87,8 @@ public class JSR286PortletApplication extends LegacyApplication { }); main.addComponent(upload); - if (getContext() instanceof PortletApplicationContext2) { - PortletApplicationContext2 ctx = (PortletApplicationContext2) getContext(); + if (getContext() instanceof VaadinPortletSession) { + VaadinPortletSession ctx = (VaadinPortletSession) getContext(); ctx.addPortletListener(new DemoPortletListener()); } else { getMainWindow().showNotification("Not inited via Portal!", diff --git a/uitest/src/com/vaadin/tests/minitutorials/v7a1/DifferentFeaturesForDifferentClients.java b/uitest/src/com/vaadin/tests/minitutorials/v7a1/DifferentFeaturesForDifferentClients.java index 05da2506e8..f9309d87b2 100644 --- a/uitest/src/com/vaadin/tests/minitutorials/v7a1/DifferentFeaturesForDifferentClients.java +++ b/uitest/src/com/vaadin/tests/minitutorials/v7a1/DifferentFeaturesForDifferentClients.java @@ -16,8 +16,8 @@ package com.vaadin.tests.minitutorials.v7a1; -import com.vaadin.Application; import com.vaadin.server.AbstractUIProvider; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WebBrowser; import com.vaadin.server.WrappedRequest; import com.vaadin.ui.Label; @@ -34,7 +34,7 @@ import com.vaadin.ui.UI; public class DifferentFeaturesForDifferentClients extends AbstractUIProvider { @Override - public Class getUIClass(Application application, + public Class getUIClass(VaadinSession application, WrappedRequest request) { // could also use browser version etc. if (request.getHeader("user-agent").contains("mobile")) { @@ -47,7 +47,7 @@ public class DifferentFeaturesForDifferentClients extends AbstractUIProvider { // Must override as default implementation isn't allowed to // instantiate our non-public classes @Override - public UI createInstance(Application application, Class type, + public UI createInstance(VaadinSession application, Class type, WrappedRequest request) { try { return type.newInstance(); diff --git a/uitest/src/com/vaadin/tests/minitutorials/v7a1/DynamicImageUI.java b/uitest/src/com/vaadin/tests/minitutorials/v7a1/DynamicImageUI.java index 4fd9c1187b..d78cdd9ad5 100644 --- a/uitest/src/com/vaadin/tests/minitutorials/v7a1/DynamicImageUI.java +++ b/uitest/src/com/vaadin/tests/minitutorials/v7a1/DynamicImageUI.java @@ -7,9 +7,9 @@ import java.net.URL; import javax.imageio.ImageIO; -import com.vaadin.Application; import com.vaadin.server.ExternalResource; import com.vaadin.server.RequestHandler; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.server.WrappedResponse; import com.vaadin.tests.components.AbstractTestUI; @@ -56,7 +56,7 @@ class DynamicImageRequestHandler implements RequestHandler { public static final String IMAGE_URL = "myimage.png"; @Override - public boolean handleRequest(Application application, + public boolean handleRequest(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException { String pathInfo = request.getRequestPathInfo(); diff --git a/uitest/src/com/vaadin/tests/minitutorials/v7a1/FindCurrentUI.java b/uitest/src/com/vaadin/tests/minitutorials/v7a1/FindCurrentUI.java index e0f53935c7..147ea2a919 100644 --- a/uitest/src/com/vaadin/tests/minitutorials/v7a1/FindCurrentUI.java +++ b/uitest/src/com/vaadin/tests/minitutorials/v7a1/FindCurrentUI.java @@ -16,7 +16,7 @@ package com.vaadin.tests.minitutorials.v7a1; -import com.vaadin.Application; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; @@ -41,7 +41,7 @@ public class FindCurrentUI extends UI { @Override public void buttonClick(ClickEvent event) { String msg = "Running in "; - msg += Application.getCurrent().isProductionMode() ? "production" + msg += VaadinSession.getCurrent().isProductionMode() ? "production" : "debug"; Notification.show(msg); } diff --git a/uitest/src/com/vaadin/tests/tickets/Ticket1589.java b/uitest/src/com/vaadin/tests/tickets/Ticket1589.java index 580aa3f7a6..4e90ae0e9e 100644 --- a/uitest/src/com/vaadin/tests/tickets/Ticket1589.java +++ b/uitest/src/com/vaadin/tests/tickets/Ticket1589.java @@ -10,11 +10,11 @@ import java.util.Date; import javax.imageio.ImageIO; -import com.vaadin.Application; import com.vaadin.LegacyApplication; import com.vaadin.server.DownloadStream; import com.vaadin.server.ExternalResource; import com.vaadin.server.RequestHandler; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.server.WrappedResponse; import com.vaadin.ui.Link; @@ -29,7 +29,7 @@ public class Ticket1589 extends LegacyApplication { MyDynamicResource res = new MyDynamicResource(); - Application.getCurrent().addRequestHandler(res); + VaadinSession.getCurrent().addRequestHandler(res); w.addComponent(new Link( "Test (without Content-Disposition, should suggest generatedFile.png when saving, browser default for actual disposition)", @@ -52,7 +52,7 @@ class MyDynamicResource implements RequestHandler { * stream that contains the response from the server. */ @Override - public boolean handleRequest(Application application, + public boolean handleRequest(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException { String relativeUri = request.getRequestPathInfo(); diff --git a/uitest/src/com/vaadin/tests/tickets/Ticket1921.java b/uitest/src/com/vaadin/tests/tickets/Ticket1921.java index 165f4a8d0d..6f525a1bfc 100644 --- a/uitest/src/com/vaadin/tests/tickets/Ticket1921.java +++ b/uitest/src/com/vaadin/tests/tickets/Ticket1921.java @@ -3,9 +3,9 @@ package com.vaadin.tests.tickets; import java.io.IOException; import java.util.Map; -import com.vaadin.Application; import com.vaadin.LegacyApplication; import com.vaadin.server.RequestHandler; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.server.WrappedResponse; import com.vaadin.ui.Button; @@ -43,7 +43,7 @@ public class Ticket1921 extends LegacyApplication implements newState(); - Application.getCurrent().addRequestHandler(this); + VaadinSession.getCurrent().addRequestHandler(this); } public void newState() { @@ -95,7 +95,7 @@ public class Ticket1921 extends LegacyApplication implements } @Override - public boolean handleRequest(Application application, + public boolean handleRequest(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException { Map parameters = request.getParameterMap(); diff --git a/uitest/src/com/vaadin/tests/tickets/Ticket2292.java b/uitest/src/com/vaadin/tests/tickets/Ticket2292.java index 34f24276e5..0f663d78f5 100644 --- a/uitest/src/com/vaadin/tests/tickets/Ticket2292.java +++ b/uitest/src/com/vaadin/tests/tickets/Ticket2292.java @@ -9,11 +9,11 @@ import java.io.IOException; import javax.imageio.ImageIO; -import com.vaadin.Application; import com.vaadin.LegacyApplication; import com.vaadin.server.DownloadStream; import com.vaadin.server.ExternalResource; import com.vaadin.server.RequestHandler; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.server.WrappedResponse; import com.vaadin.ui.Button; @@ -45,11 +45,11 @@ public class Ticket2292 extends com.vaadin.LegacyApplication Link l = new Link("l", icon); main.addComponent(l); - Application.getCurrent().addRequestHandler(this); + VaadinSession.getCurrent().addRequestHandler(this); } @Override - public boolean handleRequest(Application application, + public boolean handleRequest(VaadinSession application, WrappedRequest request, WrappedResponse response) throws IOException { String relativeUri = request.getRequestPathInfo(); diff --git a/uitest/src/com/vaadin/tests/util/SampleDirectory.java b/uitest/src/com/vaadin/tests/util/SampleDirectory.java index 7304f1cab8..be98de67cc 100644 --- a/uitest/src/com/vaadin/tests/util/SampleDirectory.java +++ b/uitest/src/com/vaadin/tests/util/SampleDirectory.java @@ -18,8 +18,8 @@ package com.vaadin.tests.util; import java.io.File; -import com.vaadin.Application; import com.vaadin.server.SystemError; +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedRequest; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Label; @@ -43,7 +43,7 @@ public class SampleDirectory { * @param application * @return file pointing to sample directory */ - public static File getDirectory(Application application, UI uI) { + public static File getDirectory(VaadinSession application, UI uI) { String errorMessage = "Access to application " + "context base directory failed, " + "possible security constraint with Application " -- cgit v1.2.3