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;
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;
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;
"mainWindow has already been set");
}
this.mainWindow = mainWindow;
+ registerRoot(mainWindow);
+ mainWindow.init(null);
}
public Root getMainWindow() {
@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;
}
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;
}
}
}
}
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) {
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));
}
}
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
}
// clean WindowCache
OpenWindowCache openWindowCache = currentlyOpenWindowsInClient
- .get(Integer.valueOf(application.getRootId(root)));
+ .get(Integer.valueOf(root.getRootId()));
if (openWindowCache != null) {
openWindowCache.clear();
}
*/
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;
}
/**
*/
private Component scrollIntoView;
+ private int rootId;
+
private static final ThreadLocal<Root> currentRoot = new ThreadLocal<Root>();
public Root() {
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.
*