]> source.dussan.org Git - vaadin-framework.git/commitdiff
Refactor #8068 to enable support for portlets
authorLeif Åstrand <leif@vaadin.com>
Mon, 19 Dec 2011 12:10:16 +0000 (14:10 +0200)
committerLeif Åstrand <leif@vaadin.com>
Mon, 19 Dec 2011 13:18:58 +0000 (15:18 +0200)
src/com/vaadin/Application.java
tests/testbench/com/vaadin/tests/application/RefreshStatePreserve.java

index dba02ab8457e35d94d7a4efab758643dc2bd1ec3..388258998bea3b207a98919d4704de789c9b39a9 100644 (file)
@@ -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 <code>null</code> 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 <code>true</code> if the browser details are needed,
+         *         <code>false</code> 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<String, Integer> retainOnRefreshRoots = new HashMap<String, Integer>();
+
+        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<Integer, PendingRootRequest> pendingRoots = new HashMap<Integer, PendingRootRequest>();
 
-    /**
-     * Keeps track of the roots that should be remembered when the browser is
-     * refreshed.
-     */
-    private Map<String, Integer> retainOnRefreshRoots = new HashMap<String, Integer>();
+    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 <code>null</code> 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.
index d22c44d7dc6493c96c19007e8ce8fb732528d387..2e0a1d6c6b81c39918232640b52863b765b14b11 100644 (file)
@@ -19,8 +19,9 @@ public class RefreshStatePreserve extends AbstractTestApplication {
     }
 
     @Override
-    protected boolean preserveRootStateOnRefresh() {
-        return true;
+    public void init() {
+        super.init();
+        setRootPreserveStrategy(new WindowNameRootPreserveStrategy());
     }
 
     @Override