aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/vaadin/Application.java
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2011-12-07 22:32:08 +0200
committerLeif Åstrand <leif@vaadin.com>2011-12-07 22:32:08 +0200
commit221a205a10c1e559bd499229b80a6fce131fe482 (patch)
tree025ccdb0c09b60a1e5ec504031a53efd5b5ed9b3 /src/com/vaadin/Application.java
parent94d133023f8b43e0e185b43d7c329c6eac3be4b8 (diff)
downloadvaadin-framework-221a205a10c1e559bd499229b80a6fce131fe482.tar.gz
vaadin-framework-221a205a10c1e559bd499229b80a6fce131fe482.zip
#8068 Provide an option for preserving Root state on browser refresh
Diffstat (limited to 'src/com/vaadin/Application.java')
-rw-r--r--src/com/vaadin/Application.java95
1 files changed, 77 insertions, 18 deletions
diff --git a/src/com/vaadin/Application.java b/src/com/vaadin/Application.java
index 97afadc653..13c8269469 100644
--- a/src/com/vaadin/Application.java
+++ b/src/com/vaadin/Application.java
@@ -17,12 +17,15 @@ import java.util.Enumeration;
import java.util.EventListener;
import java.util.EventObject;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
+import java.util.Set;
+import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
@@ -523,6 +526,21 @@ 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 WeakHashMap<String, Integer>();
+
+ /**
+ * Keeps track of which roots have been inited.
+ * <p>
+ * TODO Investigate whether this might be derived from the different states
+ * in getRootForRrequest.
+ * </p>
+ */
+ private Set<Integer> initedRoots = new HashSet<Integer>();
+
+ /**
* Gets the user of the application.
*
* <p>
@@ -2230,39 +2248,80 @@ public class Application implements Terminal.ErrorListener, Serializable {
Integer rootId = getRootId(request);
synchronized (this) {
- PendingRootRequest pendingRootRequest = pendingRoots.remove(rootId);
+ boolean preserveRootState = preserverRootStateOnRefresh();
+
+ 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) {
- // We don't have no root yet
+ if (preserveRootState && browserDetails == null
+ && !retainOnRefreshRoots.isEmpty()) {
+ // If there might already be an existing root, request
+ // information to potentially find it
+ throw new RootRequiresMoreInformation();
+ }
+
// Throws exception if root can not yet be created
root = getRoot(request);
+
+ // Initialize some fields for a newly created root
if (root.getApplication() == null) {
root.setApplication(this);
}
if (root.getRootId() < 0) {
- int id = (rootId != null ? rootId.intValue() : nextRootId++);
- root.setRootId(id);
- roots.put(Integer.valueOf(root.getRootId()), root);
-
- if (pendingRootRequest == null
- && root.getClass().isAnnotationPresent(
- RootInitRequiresBrowserDetals.class)) {
- pendingRoots.put(Integer.valueOf(id),
- new PendingRootRequest(request));
- } else {
- root.doInit(request);
+
+ if (rootId == null) {
+ // Get the next id if none defined
+ rootId = Integer.valueOf(nextRootId++);
}
+ root.setRootId(rootId.intValue());
+ roots.put(rootId, root);
}
- } else if (pendingRootRequest != null) {
- // We have a root, but the init has been pending
- root.doInit(request);
}
- }
+
+ if (!initedRoots.contains(rootId)) {
+ boolean initRequiresBrowserDetails = preserveRootState
+ || 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);
+ }
+ root.doInit(request);
+
+ // Remember that this root has been initialized
+ initedRoots.add(rootId);
+ }
+ }
+ } // end synchronized block
Root.setCurrentRoot(root);
return root;
}
+ protected boolean preserverRootStateOnRefresh() {
+ return false;
+ }
+
/**
* Internal helper to finds the root id for a request.
*
@@ -2298,6 +2357,6 @@ public class Application implements Terminal.ErrorListener, Serializable {
* @see #getRootForRequest(WrappedRequest)
*/
public boolean isRootInitPending(int rootId) {
- return pendingRoots.containsKey(Integer.valueOf(rootId));
+ return !initedRoots.contains(Integer.valueOf(rootId));
}
}