From 2fdc756fdea5255119fe9717f80876d7a61b82cc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leif=20=C3=85strand?= Date: Wed, 16 Nov 2011 14:33:14 +0200 Subject: [PATCH] Save rootId in the Root and simplify Root lookup in Application --- src/com/vaadin/Application.java | 74 +++++++----- .../server/AbstractCommunicationManager.java | 114 +++--------------- src/com/vaadin/ui/Root.java | 9 +- 3 files changed, 69 insertions(+), 128 deletions(-) diff --git a/src/com/vaadin/Application.java b/src/com/vaadin/Application.java index 76d668bb8b..3145579db8 100644 --- a/src/com/vaadin/Application.java +++ b/src/com/vaadin/Application.java @@ -24,6 +24,8 @@ import java.util.Map.Entry; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.vaadin.service.ApplicationContext; import com.vaadin.terminal.ApplicationResource; @@ -34,7 +36,6 @@ import com.vaadin.terminal.Terminal; import com.vaadin.terminal.VariableOwner; import com.vaadin.terminal.WrappedRequest; import com.vaadin.terminal.WrappedResponse; -import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.server.ChangeVariablesErrorEvent; import com.vaadin.terminal.gwt.server.WebApplicationContext; import com.vaadin.ui.AbstractComponent; @@ -100,6 +101,12 @@ public class Application implements Terminal.ErrorListener, Serializable { public static final String ROOT_PARAMETER = "root"; public static class LegacyApplication extends Application { + /** + * Ignore initial / and then get everything up to the next / + */ + private static final Pattern WINDOW_NAME_PATTERN = Pattern + .compile("^/?([^/]+).*"); + private Root mainWindow; private String theme; @@ -111,6 +118,8 @@ public class Application implements Terminal.ErrorListener, Serializable { "mainWindow has already been set"); } this.mainWindow = mainWindow; + registerRoot(mainWindow); + mainWindow.init(null); } public Root getMainWindow() { @@ -119,6 +128,19 @@ public class Application implements Terminal.ErrorListener, Serializable { @Override public Root getRoot(WrappedRequest request) { + String pathInfo = request.getRequestPathInfo(); + String name = null; + if (pathInfo != null && pathInfo.length() > 0) { + Matcher matcher = WINDOW_NAME_PATTERN.matcher(pathInfo); + if (matcher.matches()) { + // Skip the initial slash + name = matcher.group(1); + } + } + Root window = getWindow(name); + if (window != null) { + return window; + } return mainWindow; } @@ -149,13 +171,14 @@ public class Application implements Terminal.ErrorListener, Serializable { public void addWindow(Root root, String name) { legacyRootNames.put(name, root); + registerRoot(root); + root.init(null); } public void removeWindow(Root root) { for (Entry entry : legacyRootNames.entrySet()) { if (entry.getValue() == root) { legacyRootNames.remove(entry.getKey()); - return; } } } @@ -1544,33 +1567,25 @@ public class Application implements Terminal.ErrorListener, Serializable { } public Root getRoot(WrappedRequest request) { - String rootIdString = request - .getParameter(ApplicationConnection.ROOT_ID_PARAMETER); - Root root; - synchronized (this) { - // getRoot might be called from outside the synchronized UIDL - // handling - if (rootIdString == null) { - // TODO What if getRoot is called again for this request? - - // TODO implement support for throwing exception if more - // information is required to create a root - root = createRoot(request); - root.setApplication(this); - - // TODO implement lazy init of root if indicated by annotation - root.init(request); - roots.put(Integer.valueOf(nextRootId++), root); - } else { - Integer rootId = new Integer(rootIdString); - root = roots.get(rootId); - } - } + // TODO What if getRoot is called again for this request? + + // TODO implement support for throwing exception if more + // information is required to create a root + Root root = createRoot(request); + + registerRoot(root); + + // TODO implement lazy init of root if indicated by annotation + root.init(request); - Root.setCurrentRoot(root); return root; } + protected void registerRoot(Root root) { + root.registerRoot(this, nextRootId++); + roots.put(Integer.valueOf(root.getRootId()), root); + } + protected Root createRoot(WrappedRequest request) { Object rootClassNameObj = properties.get(ROOT_PARAMETER); if (rootClassNameObj instanceof String) { @@ -1638,12 +1653,7 @@ public class Application implements Terminal.ErrorListener, Serializable { currentApplication.set(application); } - public int getRootId(Root root) { - for (Entry entry : roots.entrySet()) { - if (entry.getValue() == root) { - return entry.getKey().intValue(); - } - } - return -1; + public Root getRootById(int rootId) { + return roots.get(Integer.valueOf(rootId)); } } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java index 2823fd0e8f..558922f2df 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java @@ -738,11 +738,11 @@ public abstract class AbstractCommunicationManager implements JsonPaintTarget paintTarget = new JsonPaintTarget(this, outWriter, !repaintAll); OpenWindowCache windowCache = currentlyOpenWindowsInClient.get(Integer - .valueOf(application.getRootId(root))); + .valueOf(root.getRootId())); if (windowCache == null) { windowCache = new OpenWindowCache(); - currentlyOpenWindowsInClient.put( - Integer.valueOf(application.getRootId(root)), windowCache); + currentlyOpenWindowsInClient.put(Integer.valueOf(root.getRootId()), + windowCache); } // Paints components @@ -1039,7 +1039,7 @@ public abstract class AbstractCommunicationManager implements } // clean WindowCache OpenWindowCache openWindowCache = currentlyOpenWindowsInClient - .get(Integer.valueOf(application.getRootId(root))); + .get(Integer.valueOf(root.getRootId())); if (openWindowCache != null) { openWindowCache.clear(); } @@ -1641,97 +1641,21 @@ public abstract class AbstractCommunicationManager implements */ public Root getApplicationRoot(WrappedRequest request, Callback callback, Application application, Root assumedRoot) { - return application.getRoot(request); - - // Window window = null; - // - // // If the client knows which window to use, use it if possible - // String windowClientRequestedName = - // request.getParameter("windowName"); - // - // if (assumedWindow != null - // && application.getWindows().contains(assumedWindow)) { - // windowClientRequestedName = assumedWindow.getName(); - // } - // if (windowClientRequestedName != null) { - // window = application.getWindow(windowClientRequestedName); - // if (window != null) { - // return window; - // } - // } - // - // // If client does not know what window it wants - // if (window == null && !request.isRunningInPortlet()) { - // // This is only supported if the application is running inside a - // // servlet - // - // // Get the path from URL - // String path = callback.getRequestPathInfo(request); - // - // /* - // * If the path is specified, create name from it. - // * - // * An exception is if UIDL request have come this far. This happens - // * if main window is refreshed. In that case we always return main - // * window (infamous hacky support for refreshes if only main window - // * is used). However we are not returning with main window here (we - // * will later if things work right), because the code is so cryptic - // * that nobody really knows what it does. - // */ - // boolean pathMayContainWindowName = path != null - // && path.length() > 0 && !path.equals("/"); - // if (pathMayContainWindowName) { - // boolean uidlRequest = path.startsWith("/UIDL"); - // if (!uidlRequest) { - // String windowUrlName = null; - // if (path.charAt(0) == '/') { - // path = path.substring(1); - // } - // final int index = path.indexOf('/'); - // if (index < 0) { - // windowUrlName = path; - // path = ""; - // } else { - // windowUrlName = path.substring(0, index); - // path = path.substring(index + 1); - // } - // - // window = application.getWindow(windowUrlName); - // } - // } - // - // } - // - // // By default, use mainwindow - // if (window == null) { - // window = application.getMainWindow(); - // // Return null if no main window was found - // if (window == null) { - // return null; - // } - // } - // - // // If the requested window is already open, resolve conflict - // if (currentlyOpenWindowsInClient.containsKey(window.getName())) { - // String newWindowName = window.getName(); - // - // synchronized (AbstractCommunicationManager.class) { - // while (currentlyOpenWindowsInClient.containsKey(newWindowName)) { - // newWindowName = window.getName() + "_" - // + nextUnusedWindowSuffix++; - // } - // } - // - // window = application.getWindow(newWindowName); - // - // // If everything else fails, use main window even in case of - // // conflicts - // if (window == null) { - // window = application.getMainWindow(); - // } - // } - // - // return window; + String rootIdString = request + .getParameter(ApplicationConnection.ROOT_ID_PARAMETER); + Root root = null; + synchronized (application) { + if (rootIdString != null) { + int rootId = Integer.parseInt(rootIdString); + root = application.getRootById(rootId); + } + if (root == null) { + root = application.getRoot(request); + } + } + + Root.setCurrentRoot(root); + return root; } /** diff --git a/src/com/vaadin/ui/Root.java b/src/com/vaadin/ui/Root.java index 7819ccfa95..0dd6620b20 100644 --- a/src/com/vaadin/ui/Root.java +++ b/src/com/vaadin/ui/Root.java @@ -76,6 +76,8 @@ public class Root extends AbstractComponentContainer { */ private Component scrollIntoView; + private int rootId; + private static final ThreadLocal currentRoot = new ThreadLocal(); public Root() { @@ -202,16 +204,21 @@ public class Root extends AbstractComponentContainer { this.terminal = terminal; } - public void setApplication(Application application) { + public void registerRoot(Application application, int rootId) { if (application == null) { throw new NullPointerException("application"); } else if (this.application != null) { throw new IllegalStateException("Application has already been set"); } else { this.application = application; + this.rootId = rootId; } } + public int getRootId() { + return rootId; + } + /** * Adds a window inside this root. * -- 2.39.5