]> source.dussan.org Git - vaadin-framework.git/commitdiff
Save rootId in the Root and simplify Root lookup in Application
authorLeif Åstrand <leif@vaadin.com>
Wed, 16 Nov 2011 12:33:14 +0000 (14:33 +0200)
committerLeif Åstrand <leif@vaadin.com>
Wed, 16 Nov 2011 12:33:14 +0000 (14:33 +0200)
src/com/vaadin/Application.java
src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
src/com/vaadin/ui/Root.java

index 76d668bb8b40ecd78b800c8ab5c9f694a200d3d5..3145579db8f6674d3da8e35f24bcbd059ac79053 100644 (file)
@@ -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<String, Root> 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<Integer, Root> entry : roots.entrySet()) {
-            if (entry.getValue() == root) {
-                return entry.getKey().intValue();
-            }
-        }
-        return -1;
+    public Root getRootById(int rootId) {
+        return roots.get(Integer.valueOf(rootId));
     }
 }
index 2823fd0e8f29af4eb5a251af46cbb6cddae6e868..558922f2df888b948b8d8a2d6756164a3fbb4883 100644 (file)
@@ -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;
     }
 
     /**
index 7819ccfa955a387a75d07958e75c2bac1bd3fc8c..0dd6620b20ceef237852dca3bba33cb3faf9b48d 100644 (file)
@@ -76,6 +76,8 @@ public class Root extends AbstractComponentContainer {
      */
     private Component scrollIntoView;
 
+    private int rootId;
+
     private static final ThreadLocal<Root> currentRoot = new ThreadLocal<Root>();
 
     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.
      *