From: Leif Åstrand Date: Mon, 19 Dec 2011 12:10:16 +0000 (+0200) Subject: Refactor #8068 to enable support for portlets X-Git-Tag: 7.0.0.alpha1~104 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e95377822a44324dc71b070752b7464e78d68e7e;p=vaadin-framework.git Refactor #8068 to enable support for portlets --- diff --git a/src/com/vaadin/Application.java b/src/com/vaadin/Application.java index dba02ab845..388258998b 100644 --- a/src/com/vaadin/Application.java +++ b/src/com/vaadin/Application.java @@ -118,6 +118,83 @@ public class Application implements Terminal.ErrorListener, Serializable { */ public static final String ROOT_PARAMETER = "root"; + /** + * Represents a strategy for retaining root instances when the contents of + * the browser have been reloaded, e.g. if the user presses refresh or + * navigates back to the application from another page. + * + * @since 7.0 + */ + public interface RootPreserveStrategy extends Serializable { + /** + * Finds the id of an existing root that should be used to serve a + * request. + * + * @param request + * the request to get the root for + * @return integer id of the root, or null if no root is + * found + * @throws RootRequiresMoreInformation + * if full details from the browser are required to resolve + * the root + */ + public Integer getPreservedRootForRequest(WrappedRequest request) + throws RootRequiresMoreInformation; + + /** + * Used to tell whether the browser details are required when + * {@link #registerRoot(Root, WrappedRequest)} is called. + * + * @return true if the browser details are needed, + * false if they are not needed + */ + public boolean reqsterRequiresBrowserDetails(); + + /** + * This method is called by the framework when a root has been + * initialized and should possibly be preserved for future lookups. + * + * @param root + * the newly initialized root + * @param request + * the associated request + */ + public void registerRoot(Root root, WrappedRequest request); + } + + public static class WindowNameRootPreserveStrategy implements + RootPreserveStrategy { + /** + * Keeps track of the roots that should be remembered when the browser + * is refreshed. + */ + private final Map retainOnRefreshRoots = new HashMap(); + + public Integer getPreservedRootForRequest(WrappedRequest request) + throws RootRequiresMoreInformation { + if (retainOnRefreshRoots.isEmpty()) { + return null; + } + BrowserDetails browserDetails = request.getBrowserDetails(); + if (browserDetails == null) { + throw new RootRequiresMoreInformation(); + } else { + String windowName = browserDetails.getWindowName(); + return retainOnRefreshRoots.get(windowName); + } + } + + public void registerRoot(Root root, WrappedRequest request) { + String windowName = request.getBrowserDetails().getWindowName(); + Integer rootId = Integer.valueOf(root.getRootId()); + retainOnRefreshRoots.put(windowName, rootId); + } + + public boolean reqsterRequiresBrowserDetails() { + return true; + } + } + /** * A special application designed to help migrating applications from Vaadin * 6 to Vaadin 7. The legacy application supports setting a main window, @@ -534,11 +611,7 @@ public class Application implements Terminal.ErrorListener, Serializable { */ private Map pendingRoots = new HashMap(); - /** - * Keeps track of the roots that should be remembered when the browser is - * refreshed. - */ - private Map retainOnRefreshRoots = new HashMap(); + private RootPreserveStrategy rootPreserveStrategy = null; /** * Keeps track of which roots have been inited. @@ -2292,34 +2365,28 @@ public class Application implements Terminal.ErrorListener, Serializable { Integer rootId = getRootId(request); synchronized (this) { - boolean preserveRootState = preserveRootStateOnRefresh(); + RootPreserveStrategy rootPreserveStrategy = getRootPreserveStrategy(); BrowserDetails browserDetails = request.getBrowserDetails(); if (browserDetails != null) { // Don't wait for a second request any more pendingRoots.remove(rootId); - - if (preserveRootState) { - // Check for a known window.name - Integer retainedRootId = retainOnRefreshRoots - .get(browserDetails.getWindowName()); - if (retainedRootId != null) { - rootId = retainedRootId; - } - } } root = roots.get(rootId); - if (root == null) { - if (preserveRootState && browserDetails == null - && !retainOnRefreshRoots.isEmpty()) { - // If there might already be an existing root, request - // information to potentially find it - throw new RootRequiresMoreInformation(); + if (root == null && rootPreserveStrategy != null) { + // Check for a known root + Integer retainedRootId = rootPreserveStrategy + .getPreservedRootForRequest(request); + if (retainedRootId != null) { + rootId = retainedRootId; + root = roots.get(rootId); } + } + if (root == null) { // Throws exception if root can not yet be created root = getRoot(request); @@ -2339,16 +2406,16 @@ public class Application implements Terminal.ErrorListener, Serializable { } if (!initedRoots.contains(rootId)) { - boolean initRequiresBrowserDetails = preserveRootState + boolean initRequiresBrowserDetails = (rootPreserveStrategy != null && rootPreserveStrategy + .reqsterRequiresBrowserDetails()) || root.getClass().isAnnotationPresent( RootInitRequiresBrowserDetals.class); if (initRequiresBrowserDetails && browserDetails == null) { pendingRoots.put(rootId, new PendingRootRequest(request)); } else { - if (preserveRootState) { - // Remember the window name of this root - retainOnRefreshRoots.put( - browserDetails.getWindowName(), rootId); + if (rootPreserveStrategy != null) { + // Remember this root + rootPreserveStrategy.registerRoot(root, request); } root.doInit(request); @@ -2362,10 +2429,6 @@ public class Application implements Terminal.ErrorListener, Serializable { return root; } - protected boolean preserveRootStateOnRefresh() { - return false; - } - /** * Internal helper to finds the root id for a request. * @@ -2388,6 +2451,31 @@ public class Application implements Terminal.ErrorListener, Serializable { return rootId; } + /** + * Gets the current strategy for preserving Root instances e.g. when the + * browser window is reloaded. + * + * @return the current root preserver strategy, or null if + * roots should not be preserved + * + * @see RootPreserveStrategy + */ + public RootPreserveStrategy getRootPreserveStrategy() { + return rootPreserveStrategy; + } + + /** + * Sets the current strategy for preserving Roots e.g. when the browser + * window is reloaded. + * + * @param rootPreserveStrategy + * the new root preserve strategy + */ + public void setRootPreserveStrategy( + RootPreserveStrategy rootPreserveStrategy) { + this.rootPreserveStrategy = rootPreserveStrategy; + } + /** * Checks whether there's a pending initialization for the root with the * given id. diff --git a/tests/testbench/com/vaadin/tests/application/RefreshStatePreserve.java b/tests/testbench/com/vaadin/tests/application/RefreshStatePreserve.java index d22c44d7dc..2e0a1d6c6b 100644 --- a/tests/testbench/com/vaadin/tests/application/RefreshStatePreserve.java +++ b/tests/testbench/com/vaadin/tests/application/RefreshStatePreserve.java @@ -19,8 +19,9 @@ public class RefreshStatePreserve extends AbstractTestApplication { } @Override - protected boolean preserveRootStateOnRefresh() { - return true; + public void init() { + super.init(); + setRootPreserveStrategy(new WindowNameRootPreserveStrategy()); } @Override