summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2011-12-19 14:10:16 +0200
committerLeif Åstrand <leif@vaadin.com>2011-12-19 15:18:58 +0200
commite95377822a44324dc71b070752b7464e78d68e7e (patch)
treeff296afe717485a484c0c1f278f6a528271c0991
parentabdcdf6c3199f0994ae95b1e1d4f7889d711f7e7 (diff)
downloadvaadin-framework-e95377822a44324dc71b070752b7464e78d68e7e.tar.gz
vaadin-framework-e95377822a44324dc71b070752b7464e78d68e7e.zip
Refactor #8068 to enable support for portlets
-rw-r--r--src/com/vaadin/Application.java148
-rw-r--r--tests/testbench/com/vaadin/tests/application/RefreshStatePreserve.java5
2 files changed, 121 insertions, 32 deletions
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
@@ -119,6 +119,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,
* adding additional browser level windows and defining the theme for the
@@ -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.
*
@@ -2389,6 +2452,31 @@ public class Application implements Terminal.ErrorListener, Serializable {
}
/**
+ * 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.
*
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