diff options
author | Johannes Dahlström <johannesd@vaadin.com> | 2012-11-22 13:31:02 +0200 |
---|---|---|
committer | Johannes Dahlström <johannesd@vaadin.com> | 2012-11-23 17:00:30 +0200 |
commit | 3aa137c3aff923b5e9f0b0714a595f29165e423a (patch) | |
tree | d2067b2733e4cbbd8234073a168aaa6ab1abf212 /server/src/com/vaadin/ui/UI.java | |
parent | 2a8435ee61c0f5e70691b2b1a01305f60ef4f67b (diff) | |
download | vaadin-framework-3aa137c3aff923b5e9f0b0714a595f29165e423a.tar.gz vaadin-framework-3aa137c3aff923b5e9f0b0714a595f29165e423a.zip |
Refactor heartbeat handling and inactive UI/session closing (#10252)
* Package-private VaadinService.cleanupSession() handles these, called from VaadinServlet and VaadinPortlet at the end of a request
* UI detach() called when removing from the session (#9755)
* UIs can be explicitly closed; UIs marked as closed are removed at the end of the request (#10249)
* Remove UI cleanup events and listeners in favor of detach events (#10251)
Change-Id: I1f994c43bd2fc5fe7f99f7152c9db35927235291
Diffstat (limited to 'server/src/com/vaadin/ui/UI.java')
-rw-r--r-- | server/src/com/vaadin/ui/UI.java | 148 |
1 files changed, 69 insertions, 79 deletions
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index 2887c71adf..e99846c84b 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -16,7 +16,6 @@ package com.vaadin.ui; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -27,7 +26,6 @@ import java.util.Map; import com.vaadin.event.Action; import com.vaadin.event.Action.Handler; import com.vaadin.event.ActionManager; -import com.vaadin.event.ConnectorEventListener; import com.vaadin.event.MouseEvents.ClickEvent; import com.vaadin.event.MouseEvents.ClickListener; import com.vaadin.navigator.Navigator; @@ -45,7 +43,6 @@ import com.vaadin.shared.ui.ui.UIConstants; import com.vaadin.shared.ui.ui.UIServerRpc; import com.vaadin.shared.ui.ui.UIState; import com.vaadin.util.CurrentInstance; -import com.vaadin.util.ReflectTools; /** * The topmost component in any component hierarchy. There is one UI for every @@ -82,42 +79,6 @@ public abstract class UI extends AbstractSingleComponentContainer implements Action.Container, Action.Notifier, LegacyComponent { /** - * Event fired when a UI is removed from the application. - */ - public static class CleanupEvent extends Event { - - private static final String CLEANUP_EVENT_IDENTIFIER = "uiCleanup"; - - public CleanupEvent(UI source) { - super(source); - } - - public UI getUI() { - return (UI) getSource(); - } - } - - /** - * Interface for listening {@link UI.CleanupEvent UI cleanup events}. - * - */ - public interface CleanupListener extends ConnectorEventListener { - - public static final Method cleanupMethod = ReflectTools.findMethod( - CleanupListener.class, "cleanup", CleanupEvent.class); - - /** - * Called when a CleanupListener is notified of a CleanupEvent. - * {@link UI#getCurrent()} returns <code>event.getUI()</code> within - * this method. - * - * @param event - * The close event that was fired. - */ - public void cleanup(CleanupEvent event); - } - - /** * The application to which this UI belongs */ private VaadinSession session; @@ -174,6 +135,8 @@ public abstract class UI extends AbstractSingleComponentContainer implements */ private long lastHeartbeatTimestamp = System.currentTimeMillis(); + private boolean closing = false; + /** * Creates a new empty UI without a caption. The content of the UI must be * set by calling {@link #setContent(Component)} before using the UI. @@ -286,16 +249,6 @@ public abstract class UI extends AbstractSingleComponentContainer implements fireEvent(new ClickEvent(this, mouseDetails)); } - /** - * For internal use only. - */ - public void fireCleanupEvent() { - UI current = UI.getCurrent(); - UI.setCurrent(this); - fireEvent(new CleanupEvent(this)); - UI.setCurrent(current); - } - @Override @SuppressWarnings("unchecked") public void changeVariables(Object source, Map<String, Object> variables) { @@ -347,18 +300,17 @@ public abstract class UI extends AbstractSingleComponentContainer implements } /** - * Sets the application to which this UI is assigned. It is not legal to - * change the application once it has been set nor to set a - * <code>null</code> application. + * Sets the session to which this UI is assigned. * <p> - * This method is mainly intended for internal use by the framework. + * This method is for internal use by the framework. To explicitly close a + * UI, see {@link #close()}. * </p> * * @param session - * the application to set + * the session to set * * @throws IllegalStateException - * if the application has already been set + * if the session has already been set * * @see #getSession() */ @@ -689,18 +641,6 @@ public abstract class UI extends AbstractSingleComponentContainer implements } /** - * Adds a cleanup listener to the UI. Cleanup listeners are invoked when the - * UI is removed from the session due to UI or session expiration. - * - * @param listener - * The CleanupListener that should be added. - */ - public void addCleanupListener(CleanupListener listener) { - addListener(CleanupEvent.CLEANUP_EVENT_IDENTIFIER, CleanupEvent.class, - listener, CleanupListener.cleanupMethod); - } - - /** * @deprecated As of 7.0, replaced by * {@link #addClickListener(ClickListener)} **/ @@ -722,18 +662,6 @@ public abstract class UI extends AbstractSingleComponentContainer implements } /** - * Removes a cleanup listener from the UI, if previously added with - * {@link #addCleanupListener(CleanupListener)}. - * - * @param listener - * The CleanupListener that should be removed - */ - public void removeCleanupListener(CleanupListener listener) { - removeListener(CleanupEvent.CLEANUP_EVENT_IDENTIFIER, - CleanupEvent.class, listener); - } - - /** * @deprecated As of 7.0, replaced by * {@link #removeClickListener(ClickListener)} **/ @@ -979,4 +907,66 @@ public abstract class UI extends AbstractSingleComponentContainer implements public String getTheme() { return theme; } + + /** + * Marks this UI to be {@link #detach() detached} from the session at the + * end of the current request, or the next request if there is no current + * request (if called from a background thread, for instance.) + * <p> + * The UI is detached after the response is sent, so in the current request + * it can still update the client side normally. However, after the response + * any new requests from the client side to this UI will cause an error, so + * usually the client should be asked, for instance, to reload the page + * (serving a fresh UI instance), to close the page, or to navigate + * somewhere else. + * <p> + * Note that this method is strictly for users to explicitly signal the + * framework that the UI should be detached. Overriding it is not a reliable + * way to catch UIs that are to be detached. Instead, {@code UI.detach()} + * should be overridden or a {@link DetachListener} used. + */ + public void close() { + closing = true; + } + + /** + * Returns whether this UI is marked as closed and is to be detached. + * + * @see #close() + * + * @return whether this UI is closing. + */ + public boolean isClosing() { + return closing; + } + + /** + * Called after the UI is added to the session. A UI instance is attached + * exactly once, before its {@link #init(VaadinRequest) init} method is + * called. + * + * @see Component#attach + */ + @Override + public void attach() { + super.attach(); + } + + /** + * Called before the UI is removed from the session. A UI instance is + * detached exactly once, either: + * <ul> + * <li>after it is explicitly {@link #close() closed}. + * <li>when its session is closed or expires + * <li>after three missed heartbeat requests. + * </ul> + * <p> + * Note that when a UI is detached, any changes made in the {@code detach} + * methods of any children or {@link DetachListener}s that would be + * communicated to the client are silently ignored. + */ + @Override + public void detach() { + super.detach(); + } } |