diff options
author | Leif Åstrand <leif@vaadin.com> | 2011-11-28 13:42:02 +0200 |
---|---|---|
committer | Leif Åstrand <leif@vaadin.com> | 2011-11-28 13:42:02 +0200 |
commit | 6063d00f5ae6f0cb5c5eaf0c3ce2998c5aa88a2b (patch) | |
tree | 218c6fb4f62f20325d25aeed94b38338b7708f33 | |
parent | cb5f080e5337c081f22eea86c0cf170ef88a2257 (diff) | |
download | vaadin-framework-6063d00f5ae6f0cb5c5eaf0c3ce2998c5aa88a2b.tar.gz vaadin-framework-6063d00f5ae6f0cb5c5eaf0c3ce2998c5aa88a2b.zip |
Add support for deferred Root init and early widgetset loading
6 files changed, 79 insertions, 18 deletions
diff --git a/WebContent/VAADIN/vaadinBootstrap.js b/WebContent/VAADIN/vaadinBootstrap.js index cc9829b6e4..61783c448e 100644 --- a/WebContent/VAADIN/vaadinBootstrap.js +++ b/WebContent/VAADIN/vaadinBootstrap.js @@ -12,8 +12,8 @@ } var loadTheme = function(url) { - log("loadTheme", url); if(!themesLoaded[url]) { + log("loadTheme", url); var stylesheet = document.createElement('link'); stylesheet.setAttribute('rel', 'stylesheet'); stylesheet.setAttribute('type', 'text/css'); @@ -86,9 +86,9 @@ var r = new XMLHttpRequest(); r.open('POST', url, true); r.onreadystatechange = function (aEvt) { - if (r.readyState == 4) { + if (r.readyState == 4) { if (r.status == 200){ - log(r.responseText); + log("Got root config response", r.responseText); // TODO Does this work in all supported browsers? var updatedConfig = JSON.parse(r.responseText); @@ -98,6 +98,7 @@ config[property] = updatedConfig[property]; } } + config.initPending = false; // Try bootstrapping again, this time without fetching missing info bootstrapApp(false); @@ -125,19 +126,25 @@ var widgetsetBase = getConfig('widgetsetBase'); var widgetset = getConfig('widgetset'); + var initPending = getConfig('initPending'); if (widgetset && widgetsetBase) { loadWidgetset(widgetsetBase, widgetset); + } + + if (initPending) { + if (mayDefer) { + fetchRootConfig(); + } else { + throw "May not defer bootstrap any more"; + } + } else { if (widgetsets[widgetset].callback) { log("Starting from bootstrap", appId); widgetsets[widgetset].callback(appId); } else { - log("Setting pending startup of ", appId); + log("Setting pending startup", appId); widgetsets[widgetset].pendingApps.push(appId); } - } else if (mayDefer) { - fetchRootConfig(); - } else { - throw "Widgetset not defined: " + widgetsetBase + " -> " + widgetset; } } bootstrapApp(true); diff --git a/src/com/vaadin/Application.java b/src/com/vaadin/Application.java index d284492c1c..874455f3c0 100644 --- a/src/com/vaadin/Application.java +++ b/src/com/vaadin/Application.java @@ -27,6 +27,7 @@ import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.vaadin.annotations.RootInitRequiresBrowserDetals; import com.vaadin.service.ApplicationContext; import com.vaadin.terminal.ApplicationResource; import com.vaadin.terminal.CombinedRequest; @@ -1700,9 +1701,10 @@ public class Application implements Terminal.ErrorListener, Serializable { synchronized (this) { PendingRootRequest pendingRootRequest = pendingRoots.remove(rootId); - if (pendingRootRequest == null && rootId != null) { - root = roots.get(rootId); - } else { + root = roots.get(rootId); + if (root == null) { + // We don't have no root yet + // Throws exception if root can not yet be created root = getRoot(request); if (root.getApplication() == null) { root.setApplication(this); @@ -1712,10 +1714,18 @@ public class Application implements Terminal.ErrorListener, Serializable { root.setRootId(id); roots.put(Integer.valueOf(root.getRootId()), root); - // TODO implement lazy init of root if indicated by - // annotation - root.init(request); + if (pendingRootRequest == null + && root.getClass().isAnnotationPresent( + RootInitRequiresBrowserDetals.class)) { + pendingRoots.put(Integer.valueOf(id), + new PendingRootRequest(request)); + } else { + root.init(request); + } } + } else if (pendingRootRequest != null) { + // We have a root, but the init has been pending + root.init(request); } } @@ -1735,4 +1745,8 @@ public class Application implements Terminal.ErrorListener, Serializable { : new Integer(rootIdString); return rootId; } + + public boolean isRootInitPending(int rootId) { + return pendingRoots.containsKey(Integer.valueOf(rootId)); + } } diff --git a/src/com/vaadin/annotations/RootInitRequiresBrowserDetals.java b/src/com/vaadin/annotations/RootInitRequiresBrowserDetals.java new file mode 100644 index 0000000000..62383eee92 --- /dev/null +++ b/src/com/vaadin/annotations/RootInitRequiresBrowserDetals.java @@ -0,0 +1,12 @@ +package com.vaadin.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface RootInitRequiresBrowserDetals { + // No methods +} diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java index d047ac8170..4dcd10d1a1 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java @@ -1951,6 +1951,8 @@ public abstract class AbstractCommunicationManager implements String themeUri = AJAX_PAGE_HANDLER.getThemeUri(theme, combinedRequest); + // TODO These are not required if it was only the init of the root + // that was delayed JSONObject params = new JSONObject(); params.put("widgetset", widgetset); params.put("themeUri", themeUri); diff --git a/src/com/vaadin/terminal/gwt/server/AjaxPageHandler.java b/src/com/vaadin/terminal/gwt/server/AjaxPageHandler.java index 0ae7d8d884..36ed46ff1c 100644 --- a/src/com/vaadin/terminal/gwt/server/AjaxPageHandler.java +++ b/src/com/vaadin/terminal/gwt/server/AjaxPageHandler.java @@ -288,6 +288,10 @@ public abstract class AjaxPageHandler implements RequestHandler { appConfig.put("widgetset", widgetset); + if (application.isRootInitPending(rootId)) { + appConfig.put("initPending", true); + } + page.write("vaadin.setDefaults("); if (isDebug) { page.write(defaults.toString(4)); diff --git a/tests/testbench/com/vaadin/tests/components/root/LazyInitRoots.java b/tests/testbench/com/vaadin/tests/components/root/LazyInitRoots.java index 96d9a465e2..5ff193f1c9 100644 --- a/tests/testbench/com/vaadin/tests/components/root/LazyInitRoots.java +++ b/tests/testbench/com/vaadin/tests/components/root/LazyInitRoots.java @@ -2,6 +2,7 @@ package com.vaadin.tests.components.root; import com.vaadin.Application; import com.vaadin.RootRequiresMoreInformation; +import com.vaadin.annotations.RootInitRequiresBrowserDetals; import com.vaadin.terminal.ExternalResource; import com.vaadin.terminal.WrappedRequest; import com.vaadin.terminal.WrappedRequest.BrowserDetails; @@ -12,6 +13,17 @@ import com.vaadin.ui.VerticalLayout; public class LazyInitRoots extends Application { + @RootInitRequiresBrowserDetals + private static class LazyInitRoot extends Root { + @Override + public void init(WrappedRequest request) { + BrowserDetails browserDetails = request.getBrowserDetails(); + getContent().addComponent( + new Label("Lazy init root: " + + browserDetails.getUriFragmet())); + } + } + @Override public Root getRoot(WrappedRequest request) throws RootRequiresMoreInformation { @@ -20,16 +32,26 @@ public class LazyInitRoots extends Application { if (browserDetails == null) { throw new RootRequiresMoreInformation(); } else { - VerticalLayout content = new VerticalLayout(); - content.addComponent(new Label(browserDetails.getUriFragmet())); - return new Root(content); + Root root = new Root(); + root.getContent().addComponent( + new Label("Lazy create root: " + + browserDetails.getUriFragmet())); + return root; } + } else if (request.getParameter("lazyInit") != null) { + return new LazyInitRoot(); } else { VerticalLayout content = new VerticalLayout(); Link lazyCreateLink = new Link("Open lazyCreate root", - new ExternalResource(getURL() + "?lazyCreate")); + new ExternalResource(getURL() + "?lazyCreate#lazyCreate")); lazyCreateLink.setTargetName("_blank"); content.addComponent(lazyCreateLink); + + Link lazyInitLink = new Link("Open lazyInit root", + new ExternalResource(getURL() + "?lazyInit#lazyInit")); + lazyInitLink.setTargetName("_blank"); + content.addComponent(lazyInitLink); + return new Root(content); } } |