diff options
17 files changed, 1855 insertions, 1894 deletions
diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index b83979acc6..6b40c31d96 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -30,29 +30,29 @@ </servlet>
<!-- For testing GAE - the deployment script changes this to use GAEApplicationServlet -->
- <servlet>
+<!-- <servlet>
<servlet-name>IntegrationTest</servlet-name>
<servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
<init-param>
<param-name>application</param-name>
<param-value>com.vaadin.tests.integration.IntegrationTestApplication</param-value>
</init-param>
- </servlet>
+ </servlet> -->
<servlet-mapping>
<servlet-name>VaadinApplicationRunner</servlet-name>
<url-pattern>/run/*</url-pattern>
</servlet-mapping>
- <servlet-mapping>
+<!-- <servlet-mapping>
<servlet-name>IntegrationTest</servlet-name>
<url-pattern>/integration/*</url-pattern>
- </servlet-mapping>
+ </servlet-mapping> -->
- <servlet-mapping>
+<!-- <servlet-mapping>
<servlet-name>IntegrationTest</servlet-name>
<url-pattern>/VAADIN/*</url-pattern>
- </servlet-mapping>
+ </servlet-mapping> -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
diff --git a/src/com/vaadin/Application.java b/src/com/vaadin/Application.java index 39a70fe27f..4a6968fd66 100644 --- a/src/com/vaadin/Application.java +++ b/src/com/vaadin/Application.java @@ -7,13 +7,10 @@ package com.vaadin; import java.io.Serializable; import java.net.SocketException; import java.net.URL; -import java.util.Collection; -import java.util.Collections; import java.util.Enumeration; import java.util.EventListener; import java.util.EventObject; import java.util.Hashtable; -import java.util.Iterator; import java.util.LinkedList; import java.util.Locale; import java.util.Properties; @@ -33,6 +30,7 @@ import com.vaadin.terminal.gwt.server.ChangeVariablesErrorEvent; import com.vaadin.terminal.gwt.server.PortletApplicationContext; import com.vaadin.terminal.gwt.server.WebApplicationContext; import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.Root; import com.vaadin.ui.Window; /** @@ -95,11 +93,11 @@ public abstract class Application implements URIHandler, private final static Logger logger = Logger.getLogger(Application.class .getName()); - /** - * Id use for the next window that is opened. Access to this must be - * synchronized. - */ - private int nextWindowId = 1; + // /** + // * Id use for the next window that is opened. Access to this must be + // * synchronized. + // */ + // private int nextWindowId = 1; /** * Application context the application is running in. @@ -111,25 +109,26 @@ public abstract class Application implements URIHandler, */ private Object user; - /** - * Mapping from window name to window instance. - */ - private final Hashtable<String, Window> windows = new Hashtable<String, Window>(); + // /** + // * Mapping from window name to window instance. + // */ + // private final Hashtable<String, Window> windows = new Hashtable<String, + // Window>(); - /** - * Main window of the application. - */ - private Window mainWindow = null; + // /** + // * Main window of the application. + // */ + // private Window mainWindow = null; /** * The application's URL. */ private URL applicationUrl; - /** - * Name of the theme currently used by the application. - */ - private String theme = null; + // /** + // * Name of the theme currently used by the application. + // */ + // private String theme = null; /** * Application status. @@ -151,15 +150,15 @@ public abstract class Application implements URIHandler, */ private LinkedList<UserChangeListener> userChangeListeners = null; - /** - * Window attach listeners. - */ - private LinkedList<WindowAttachListener> windowAttachListeners = null; - - /** - * Window detach listeners. - */ - private LinkedList<WindowDetachListener> windowDetachListeners = null; + // /** + // * Window attach listeners. + // */ + // private LinkedList<WindowAttachListener> windowAttachListeners = null; + // + // /** + // * Window detach listeners. + // */ + // private LinkedList<WindowDetachListener> windowDetachListeners = null; /** * Application resource mapping: key <-> resource. @@ -188,238 +187,252 @@ public abstract class Application implements URIHandler, */ private Terminal.ErrorListener errorHandler = this; - /** - * <p> - * Gets a window by name. Returns <code>null</code> if the application is - * not running or it does not contain a window corresponding to the name. - * </p> - * - * <p> - * All windows can be referenced by their names in url - * <code>http://host:port/foo/bar/</code> where - * <code>http://host:port/foo/</code> is the application url as returned by - * getURL() and <code>bar</code> is the name of the window. - * </p> - * - * <p> - * One should note that this method can, as a side effect create new windows - * if needed by the application. This can be achieved by overriding the - * default implementation. - * </p> - * - * <p> - * If for some reason user opens another window with same url that is - * already open, name is modified by adding "_12345678" postfix to the name, - * where 12345678 is a random number. One can decide to create another - * window-object for those windows (recommended) or to discard the postfix. - * If the user has two browser windows pointing to the same window-object on - * server, synchronization errors are likely to occur. - * </p> - * - * <p> - * If no browser-level windowing is used, all defaults are fine and this - * method can be left as is. In case browser-level windows are needed, it is - * recommended to create new window-objects on this method from their names - * if the super.getWindow() does not find existing windows. See below for - * implementation example: <code><pre> - // If we already have the requested window, use it - Window w = super.getWindow(name); - if (w == null) { - // If no window found, create it - w = new Window(name); - // set windows name to the one requested - w.setName(name); - // add it to this application - addWindow(w); - // ensure use of window specific url - w.open(new ExternalResource(w.getURL().toString())); - // add some content - w.addComponent(new Label("Test window")); - } - return w;</pre></code> - * </p> - * - * <p> - * <strong>Note</strong> that all returned Window objects must be added to - * this application instance. - * - * <p> - * The method should return null if the window does not exists (and is not - * created as a side-effect) or if the application is not running anymore. - * </p> - * - * @param name - * the name of the window. - * @return the window associated with the given URI or <code>null</code> - */ - public Window getWindow(String name) { - - // For closed app, do not give any windows - if (!isRunning()) { - return null; - } - - // Gets the window by name - final Window window = windows.get(name); - - return window; - } - - /** - * Adds a new window to the application. - * - * <p> - * This implicitly invokes the - * {@link com.vaadin.ui.Window#setApplication(Application)} method. - * </p> - * - * <p> - * Note that all application-level windows can be accessed by their names in - * url <code>http://host:port/foo/bar/</code> where - * <code>http://host:port/foo/</code> is the application url as returned by - * getURL() and <code>bar</code> is the name of the window. Also note that - * not all windows should be added to application - one can also add windows - * inside other windows - these windows show as smaller windows inside those - * windows. - * </p> - * - * @param window - * the new <code>Window</code> to add. If the name of the window - * is <code>null</code>, an unique name is automatically given - * for the window. - * @throws IllegalArgumentException - * if a window with the same name as the new window already - * exists in the application. - * @throws NullPointerException - * if the given <code>Window</code> is <code>null</code>. - */ - public void addWindow(Window window) throws IllegalArgumentException, - NullPointerException { - - // Nulls can not be added to application - if (window == null) { - return; - } - - // Check that one is not adding a sub-window to application - if (window.getParent() != null) { - throw new IllegalArgumentException( - "Window was already added inside another window" - + " - it can not be added to application also."); - } - - // Gets the naming proposal from window - String name = window.getName(); - - // Checks that the application does not already contain - // window having the same name - if (name != null && windows.containsKey(name)) { - - // If the window is already added - if (window == windows.get(name)) { - return; - } - - // Otherwise complain - throw new IllegalArgumentException("Window with name '" - + window.getName() - + "' is already present in the application"); - } - - // If the name of the window is null, the window is automatically named - if (name == null) { - boolean accepted = false; - while (!accepted) { - - // Try another name - synchronized (this) { - name = String.valueOf(nextWindowId); - nextWindowId++; - } - - if (!windows.containsKey(name)) { - accepted = true; - } - } - window.setName(name); - } - - // Adds the window to application - windows.put(name, window); - window.setApplication(this); - - fireWindowAttachEvent(window); - - // If no main window is set, declare the window to be main window - if (getMainWindow() == null) { - mainWindow = window; - } - } - - /** - * Send information to all listeners about new Windows associated with this - * application. - * - * @param window - */ - private void fireWindowAttachEvent(Window window) { - // Fires the window attach event - if (windowAttachListeners != null) { - final Object[] listeners = windowAttachListeners.toArray(); - final WindowAttachEvent event = new WindowAttachEvent(window); - for (int i = 0; i < listeners.length; i++) { - ((WindowAttachListener) listeners[i]).windowAttached(event); - } - } - } - - /** - * Removes the specified window from the application. - * - * <p> - * Removing the main window of the Application also sets the main window to - * null. One must another window to be the main window after this with - * {@link #setMainWindow(Window)}. - * </p> - * - * <p> - * Note that removing window from the application does not close the browser - * window - the window is only removed from the server-side. - * </p> - * - * @param window - * the window to be removed. - */ - public void removeWindow(Window window) { - if (window != null && windows.contains(window)) { - - // Removes the window from application - windows.remove(window.getName()); - - // If the window was main window, clear it - if (getMainWindow() == window) { - setMainWindow(null); - } - - // Removes the application from window - if (window.getApplication() == this) { - window.setApplication(null); - } - - fireWindowDetachEvent(window); - } - } - - private void fireWindowDetachEvent(Window window) { - // Fires the window detach event - if (windowDetachListeners != null) { - final Object[] listeners = windowDetachListeners.toArray(); - final WindowDetachEvent event = new WindowDetachEvent(window); - for (int i = 0; i < listeners.length; i++) { - ((WindowDetachListener) listeners[i]).windowDetached(event); - } - } - } + // /** + // * <p> + // * Gets a window by name. Returns <code>null</code> if the application is + // * not running or it does not contain a window corresponding to the name. + // * </p> + // * + // * <p> + // * All windows can be referenced by their names in url + // * <code>http://host:port/foo/bar/</code> where + // * <code>http://host:port/foo/</code> is the application url as returned + // by + // * getURL() and <code>bar</code> is the name of the window. + // * </p> + // * + // * <p> + // * One should note that this method can, as a side effect create new + // windows + // * if needed by the application. This can be achieved by overriding the + // * default implementation. + // * </p> + // * + // * <p> + // * If for some reason user opens another window with same url that is + // * already open, name is modified by adding "_12345678" postfix to the + // name, + // * where 12345678 is a random number. One can decide to create another + // * window-object for those windows (recommended) or to discard the + // postfix. + // * If the user has two browser windows pointing to the same window-object + // on + // * server, synchronization errors are likely to occur. + // * </p> + // * + // * <p> + // * If no browser-level windowing is used, all defaults are fine and this + // * method can be left as is. In case browser-level windows are needed, it + // is + // * recommended to create new window-objects on this method from their + // names + // * if the super.getWindow() does not find existing windows. See below for + // * implementation example: <code><pre> + // // If we already have the requested window, use it + // Window w = super.getWindow(name); + // if (w == null) { + // // If no window found, create it + // w = new Window(name); + // // set windows name to the one requested + // w.setName(name); + // // add it to this application + // addWindow(w); + // // ensure use of window specific url + // w.open(new ExternalResource(w.getURL().toString())); + // // add some content + // w.addComponent(new Label("Test window")); + // } + // return w;</pre></code> + // * </p> + // * + // * <p> + // * <strong>Note</strong> that all returned Window objects must be added to + // * this application instance. + // * + // * <p> + // * The method should return null if the window does not exists (and is not + // * created as a side-effect) or if the application is not running anymore. + // * </p> + // * + // * @param name + // * the name of the window. + // * @return the window associated with the given URI or <code>null</code> + // */ + // public Window getWindow(String name) { + // + // // For closed app, do not give any windows + // if (!isRunning()) { + // return null; + // } + // + // // Gets the window by name + // final Window window = windows.get(name); + // + // return window; + // } + + // /** + // * Adds a new window to the application. + // * + // * <p> + // * This implicitly invokes the + // * {@link com.vaadin.ui.Window#setApplication(Application)} method. + // * </p> + // * + // * <p> + // * Note that all application-level windows can be accessed by their names + // in + // * url <code>http://host:port/foo/bar/</code> where + // * <code>http://host:port/foo/</code> is the application url as returned + // by + // * getURL() and <code>bar</code> is the name of the window. Also note that + // * not all windows should be added to application - one can also add + // windows + // * inside other windows - these windows show as smaller windows inside + // those + // * windows. + // * </p> + // * + // * @param window + // * the new <code>Window</code> to add. If the name of the window + // * is <code>null</code>, an unique name is automatically given + // * for the window. + // * @throws IllegalArgumentException + // * if a window with the same name as the new window already + // * exists in the application. + // * @throws NullPointerException + // * if the given <code>Window</code> is <code>null</code>. + // */ + // public void addWindow(Window window) throws IllegalArgumentException, + // NullPointerException { + // + // // Nulls can not be added to application + // if (window == null) { + // return; + // } + // + // // Check that one is not adding a sub-window to application + // if (window.getParent() != null) { + // throw new IllegalArgumentException( + // "Window was already added inside another window" + // + " - it can not be added to application also."); + // } + // + // // Gets the naming proposal from window + // String name = window.getName(); + // + // // Checks that the application does not already contain + // // window having the same name + // if (name != null && windows.containsKey(name)) { + // + // // If the window is already added + // if (window == windows.get(name)) { + // return; + // } + // + // // Otherwise complain + // throw new IllegalArgumentException("Window with name '" + // + window.getName() + // + "' is already present in the application"); + // } + // + // // If the name of the window is null, the window is automatically named + // if (name == null) { + // boolean accepted = false; + // while (!accepted) { + // + // // Try another name + // synchronized (this) { + // name = String.valueOf(nextWindowId); + // nextWindowId++; + // } + // + // if (!windows.containsKey(name)) { + // accepted = true; + // } + // } + // window.setName(name); + // } + // + // // Adds the window to application + // windows.put(name, window); + // window.setApplication(this); + // + // fireWindowAttachEvent(window); + // + // // If no main window is set, declare the window to be main window + // if (getMainWindow() == null) { + // mainWindow = window; + // } + // } + + // /** + // * Send information to all listeners about new Windows associated with + // this + // * application. + // * + // * @param window + // */ + // private void fireWindowAttachEvent(Window window) { + // // Fires the window attach event + // if (windowAttachListeners != null) { + // final Object[] listeners = windowAttachListeners.toArray(); + // final WindowAttachEvent event = new WindowAttachEvent(window); + // for (int i = 0; i < listeners.length; i++) { + // ((WindowAttachListener) listeners[i]).windowAttached(event); + // } + // } + // } + + // /** + // * Removes the specified window from the application. + // * + // * <p> + // * Removing the main window of the Application also sets the main window + // to + // * null. One must another window to be the main window after this with + // * {@link #setMainWindow(Window)}. + // * </p> + // * + // * <p> + // * Note that removing window from the application does not close the + // browser + // * window - the window is only removed from the server-side. + // * </p> + // * + // * @param window + // * the window to be removed. + // */ + // public void removeWindow(Window window) { + // if (window != null && windows.contains(window)) { + // + // // Removes the window from application + // windows.remove(window.getName()); + // + // // If the window was main window, clear it + // if (getMainWindow() == window) { + // setMainWindow(null); + // } + // + // // Removes the application from window + // if (window.getApplication() == this) { + // window.setApplication(null); + // } + // + // fireWindowDetachEvent(window); + // } + // } + + // private void fireWindowDetachEvent(Window window) { + // // Fires the window detach event + // if (windowDetachListeners != null) { + // final Object[] listeners = windowDetachListeners.toArray(); + // final WindowDetachEvent event = new WindowDetachEvent(window); + // for (int i = 0; i < listeners.length; i++) { + // ((WindowDetachListener) listeners[i]).windowDetached(event); + // } + // } + // } /** * Gets the user of the application. @@ -559,18 +572,18 @@ public abstract class Application implements URIHandler, return applicationIsRunning; } - /** - * Gets the set of windows contained by the application. - * - * <p> - * Note that the returned set of windows can not be modified. - * </p> - * - * @return the Unmodifiable collection of windows. - */ - public Collection<Window> getWindows() { - return Collections.unmodifiableCollection(windows.values()); - } + // /** + // * Gets the set of windows contained by the application. + // * + // * <p> + // * Note that the returned set of windows can not be modified. + // * </p> + // * + // * @return the Unmodifiable collection of windows. + // */ + // public Collection<Window> getWindows() { + // return Collections.unmodifiableCollection(windows.values()); + // } /** * <p> @@ -582,85 +595,87 @@ public abstract class Application implements URIHandler, */ public abstract void init(); - /** - * Gets the application's theme. The application's theme is the default - * theme used by all the windows in it that do not explicitly specify a - * theme. If the application theme is not explicitly set, the - * <code>null</code> is returned. - * - * @return the name of the application's theme. - */ - public String getTheme() { - return theme; - } - - /** - * Sets the application's theme. - * <p> - * Note that this theme can be overridden in the the application level - * windows with {@link com.vaadin.ui.Window#setTheme(String)}. Setting theme - * to be <code>null</code> selects the default theme. For the available - * theme names, see the contents of the VAADIN/themes directory. - * </p> - * - * @param theme - * the new theme for this application. - */ - public void setTheme(String theme) { - // Collect list of windows not having the current or future theme - final LinkedList<Window> toBeUpdated = new LinkedList<Window>(); - final String oldAppTheme = getTheme(); - for (final Iterator<Window> i = getWindows().iterator(); i.hasNext();) { - final Window w = i.next(); - final String windowTheme = w.getTheme(); - if ((windowTheme == null) - || (!windowTheme.equals(theme) && windowTheme - .equals(oldAppTheme))) { - toBeUpdated.add(w); - } - } - - // Updates the theme - this.theme = theme; - - // Ask windows to update themselves - for (final Iterator<Window> i = toBeUpdated.iterator(); i.hasNext();) { - i.next().requestRepaint(); - } - } - - /** - * Gets the mainWindow of the application. - * - * <p> - * The main window is the window attached to the application URL ( - * {@link #getURL()}) and thus which is show by default to the user. - * </p> - * <p> - * Note that each application must have at least one main window. - * </p> - * - * @return the main window. - */ - public Window getMainWindow() { - return mainWindow; - } - - /** - * <p> - * Sets the mainWindow. If the main window is not explicitly set, the main - * window defaults to first created window. Setting window as a main window - * of this application also adds the window to this application. - * </p> - * - * @param mainWindow - * the mainWindow to set. - */ - public void setMainWindow(Window mainWindow) { - - addWindow(mainWindow); - this.mainWindow = mainWindow; - } + // /** + // * Gets the application's theme. The application's theme is the default + // * theme used by all the windows in it that do not explicitly specify a + // * theme. If the application theme is not explicitly set, the + // * <code>null</code> is returned. + // * + // * @return the name of the application's theme. + // */ + // public String getTheme() { + // return theme; + // } + + // /** + // * Sets the application's theme. + // * <p> + // * Note that this theme can be overridden in the the application level + // * windows with {@link com.vaadin.ui.Window#setTheme(String)}. Setting + // theme + // * to be <code>null</code> selects the default theme. For the available + // * theme names, see the contents of the VAADIN/themes directory. + // * </p> + // * + // * @param theme + // * the new theme for this application. + // */ + // public void setTheme(String theme) { + // // Collect list of windows not having the current or future theme + // final LinkedList<Window> toBeUpdated = new LinkedList<Window>(); + // final String oldAppTheme = getTheme(); + // for (final Iterator<Window> i = getWindows().iterator(); i.hasNext();) { + // final Window w = i.next(); + // final String windowTheme = w.getTheme(); + // if ((windowTheme == null) + // || (!windowTheme.equals(theme) && windowTheme + // .equals(oldAppTheme))) { + // toBeUpdated.add(w); + // } + // } + // + // // Updates the theme + // this.theme = theme; + // + // // Ask windows to update themselves + // for (final Iterator<Window> i = toBeUpdated.iterator(); i.hasNext();) { + // i.next().requestRepaint(); + // } + // } + + // /** + // * Gets the mainWindow of the application. + // * + // * <p> + // * The main window is the window attached to the application URL ( + // * {@link #getURL()}) and thus which is show by default to the user. + // * </p> + // * <p> + // * Note that each application must have at least one main window. + // * </p> + // * + // * @return the main window. + // */ + // public Window getMainWindow() { + // return mainWindow; + // } + + // /** + // * <p> + // * Sets the mainWindow. If the main window is not explicitly set, the main + // * window defaults to first created window. Setting window as a main + // window + // * of this application also adds the window to this application. + // * </p> + // * + // * @param mainWindow + // * the mainWindow to set. + // */ + // public void setMainWindow(Window mainWindow) { + // + // addWindow(mainWindow); + // this.mainWindow = mainWindow; + // } /** * Returns an enumeration of all the names in this application. @@ -1060,67 +1075,67 @@ public abstract class Application implements URIHandler, public void windowDetached(WindowDetachEvent event); } - /** - * Adds the window attach listener. - * - * Use this to get notifications each time a window is attached to the - * application with {@link #addWindow(Window)}. - * - * @param listener - * the window attach listener to add. - */ - public void addListener(WindowAttachListener listener) { - if (windowAttachListeners == null) { - windowAttachListeners = new LinkedList<WindowAttachListener>(); - } - windowAttachListeners.add(listener); - } - - /** - * Adds the window detach listener. - * - * Use this to get notifications each time a window is remove from the - * application with {@link #removeWindow(Window)}. - * - * @param listener - * the window detach listener to add. - */ - public void addListener(WindowDetachListener listener) { - if (windowDetachListeners == null) { - windowDetachListeners = new LinkedList<WindowDetachListener>(); - } - windowDetachListeners.add(listener); - } - - /** - * Removes the window attach listener. - * - * @param listener - * the window attach listener to remove. - */ - public void removeListener(WindowAttachListener listener) { - if (windowAttachListeners != null) { - windowAttachListeners.remove(listener); - if (windowAttachListeners.isEmpty()) { - windowAttachListeners = null; - } - } - } - - /** - * Removes the window detach listener. - * - * @param listener - * the window detach listener to remove. - */ - public void removeListener(WindowDetachListener listener) { - if (windowDetachListeners != null) { - windowDetachListeners.remove(listener); - if (windowDetachListeners.isEmpty()) { - windowDetachListeners = null; - } - } - } + // /** + // * Adds the window attach listener. + // * + // * Use this to get notifications each time a window is attached to the + // * application with {@link #addWindow(Window)}. + // * + // * @param listener + // * the window attach listener to add. + // */ + // public void addListener(WindowAttachListener listener) { + // if (windowAttachListeners == null) { + // windowAttachListeners = new LinkedList<WindowAttachListener>(); + // } + // windowAttachListeners.add(listener); + // } + + // /** + // * Adds the window detach listener. + // * + // * Use this to get notifications each time a window is remove from the + // * application with {@link #removeWindow(Window)}. + // * + // * @param listener + // * the window detach listener to add. + // */ + // public void addListener(WindowDetachListener listener) { + // if (windowDetachListeners == null) { + // windowDetachListeners = new LinkedList<WindowDetachListener>(); + // } + // windowDetachListeners.add(listener); + // } + + // /** + // * Removes the window attach listener. + // * + // * @param listener + // * the window attach listener to remove. + // */ + // public void removeListener(WindowAttachListener listener) { + // if (windowAttachListeners != null) { + // windowAttachListeners.remove(listener); + // if (windowAttachListeners.isEmpty()) { + // windowAttachListeners = null; + // } + // } + // } + + // /** + // * Removes the window detach listener. + // * + // * @param listener + // * the window detach listener to remove. + // */ + // public void removeListener(WindowDetachListener listener) { + // if (windowDetachListeners != null) { + // windowDetachListeners.remove(listener); + // if (windowDetachListeners.isEmpty()) { + // windowDetachListeners = null; + // } + // } + // } /** * Returns the URL user is redirected to on application close. If the URL is @@ -1906,4 +1921,6 @@ public abstract class Application implements URIHandler, } } + + public abstract Root getRoot(); }
\ No newline at end of file diff --git a/src/com/vaadin/RootTestApplication.java b/src/com/vaadin/RootTestApplication.java new file mode 100644 index 0000000000..bf5ec99b00 --- /dev/null +++ b/src/com/vaadin/RootTestApplication.java @@ -0,0 +1,27 @@ +package com.vaadin; + +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.DefaultRoot; +import com.vaadin.ui.Root; + +public class RootTestApplication extends Application { + private final Root root = new DefaultRoot(new Button("Roots, bloody roots", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + root.executeJavaScript("window.alert(\"Here\");"); + } + })); + + @Override + public void init() { + // TODO Should be done by Application during init + root.setApplication(this); + } + + @Override + public Root getRoot() { + return root; + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java index 6787b36022..0d092ae29f 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java @@ -317,7 +317,7 @@ public class ApplicationConfiguration implements EntryPoint { unknownComponents = new HashMap<String, String>(); } unknownComponents.put("" + value, key); - } else if (key == "com.vaadin.ui.Window") { + } else if (key == "com.vaadin.ui.DefaultRoot") { windowId = "" + value; } } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java index 84cab80a19..e0dc7a0d26 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java @@ -55,7 +55,7 @@ import com.vaadin.terminal.DownloadStream; import com.vaadin.terminal.Terminal; import com.vaadin.terminal.gwt.client.ApplicationConfiguration; import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.ui.Window; +import com.vaadin.ui.Root; /** * Portlet 2.0 base class. This replaces the servlet in servlet/portlet 1.0 @@ -399,7 +399,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet /* Notify listeners */ // Finds the window within the application - Window window = null; + Root root = null; synchronized (application) { if (application.isRunning()) { switch (requestType) { @@ -408,10 +408,10 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet break; case APPLICATION_RESOURCE: // use main window - should not need any window - window = application.getMainWindow(); + root = application.getRoot(); break; default: - window = applicationManager.getApplicationWindow( + root = applicationManager.getApplicationRoot( request, this, application, null); } // if window not found, not a problem - use null @@ -422,19 +422,19 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet // starts? if (request instanceof RenderRequest) { applicationContext.firePortletRenderRequest(application, - window, (RenderRequest) request, + root, (RenderRequest) request, (RenderResponse) response); } else if (request instanceof ActionRequest) { applicationContext.firePortletActionRequest(application, - window, (ActionRequest) request, + root, (ActionRequest) request, (ActionResponse) response); } else if (request instanceof EventRequest) { applicationContext.firePortletEventRequest(application, - window, (EventRequest) request, + root, (EventRequest) request, (EventResponse) response); } else if (request instanceof ResourceRequest) { applicationContext.firePortletResourceRequest(application, - window, (ResourceRequest) request, + root, (ResourceRequest) request, (ResourceResponse) response); } @@ -452,7 +452,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet } applicationManager.handleUidlRequest( (ResourceRequest) request, - (ResourceResponse) response, this, window); + (ResourceResponse) response, this, root); return; } else { /* @@ -464,7 +464,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet } handleOtherRequest(request, response, requestType, - application, window, applicationContext, + application, root, applicationContext, applicationManager); } } catch (final SessionExpiredException e) { @@ -519,35 +519,35 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet */ private void handleOtherRequest(PortletRequest request, PortletResponse response, RequestType requestType, - Application application, Window window, + Application application, Root root, PortletApplicationContext2 applicationContext, PortletCommunicationManager applicationManager) throws PortletException, IOException, MalformedURLException { - if (window == null) { + if (root == null) { throw new PortletException(ERROR_NO_WINDOW_FOUND); } /* * Sets terminal type for the window, if not already set */ - if (window.getTerminal() == null) { - window.setTerminal(applicationContext.getBrowser()); + if (root.getTerminal() == null) { + root.setTerminal(applicationContext.getBrowser()); } /* * Handle parameters */ - final Map<String, String[]> parameters = request.getParameterMap(); - if (window != null && parameters != null) { - window.handleParameters(parameters); - } + // final Map<String, String[]> parameters = request.getParameterMap(); + // if (root != null && parameters != null) { + // root.handleParameters(parameters); + // } if (requestType == RequestType.APPLICATION_RESOURCE) { - handleURI(applicationManager, window, (ResourceRequest) request, + handleURI(applicationManager, root, (ResourceRequest) request, (ResourceResponse) response); } else if (requestType == RequestType.RENDER) { writeAjaxPage((RenderRequest) request, (RenderResponse) response, - window, application); + root, application); } else if (requestType == RequestType.EVENT) { // nothing to do, listeners do all the work } else if (requestType == RequestType.ACTION) { @@ -583,10 +583,10 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet } private boolean handleURI(PortletCommunicationManager applicationManager, - Window window, ResourceRequest request, ResourceResponse response) + Root root, ResourceRequest request, ResourceResponse response) throws IOException { // Handles the URI - DownloadStream download = applicationManager.handleURI(window, request, + DownloadStream download = applicationManager.handleURI(root, request, response, this); // A download request @@ -916,7 +916,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet * the portlet request. * @param response * the portlet response to write to. - * @param window + * @param root * @param application * @throws IOException * if the writing failed due to input/output error. @@ -926,7 +926,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet * @throws PortletException */ protected void writeAjaxPage(RenderRequest request, - RenderResponse response, Window window, Application application) + RenderResponse response, Root root, Application application) throws IOException, MalformedURLException, PortletException { response.setContentType("text/html"); @@ -936,7 +936,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet // TODO Currently, we can only load widgetsets and themes from the // portal - String themeName = getThemeForWindow(request, window); + String themeName = getThemeForRoot(request, root); writeAjaxPageHtmlVaadinScripts(request, response, page, application, themeName); @@ -1276,12 +1276,12 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet * @param window * @return */ - protected String getThemeForWindow(PortletRequest request, Window window) { + protected String getThemeForRoot(PortletRequest request, Root root) { // Finds theme name String themeName; // theme defined for the window? - themeName = window.getTheme(); + themeName = null;// window.getTheme(); if (themeName == null) { // no, is the default theme defined by the portal? diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java index 6af45305e7..35ce753cab 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java @@ -23,7 +23,6 @@ import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Locale; -import java.util.Map; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; @@ -44,7 +43,7 @@ import com.vaadin.terminal.Terminal; import com.vaadin.terminal.ThemeResource; import com.vaadin.terminal.URIHandler; import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.ui.Window; +import com.vaadin.ui.Root; /** * Abstract implementation of the ApplicationServlet which handles all @@ -484,10 +483,10 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements return; } else if (requestType == RequestType.UIDL) { // Handles AJAX UIDL requests - Window window = applicationManager.getApplicationWindow( - request, this, application, null); + Root root = applicationManager.getApplicationRoot(request, + this, application, null); applicationManager.handleUidlRequest(request, response, this, - window); + root); return; } @@ -498,34 +497,35 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements return; } - // Finds the window within the application - Window window = getApplicationWindow(request, applicationManager, + // Finds the root within the application + Root root = getApplicationRoot(request, applicationManager, application); - if (window == null) { + if (root == null) { throw new ServletException(ERROR_NO_WINDOW_FOUND); } - // Sets terminal type for the window, if not already set - if (window.getTerminal() == null) { - window.setTerminal(webApplicationContext.getBrowser()); + // Sets terminal type for the root, if not already set + if (root.getTerminal() == null) { + root.setTerminal(webApplicationContext.getBrowser()); } // Handle parameters - final Map<String, String[]> parameters = request.getParameterMap(); - if (window != null && parameters != null) { - window.handleParameters(parameters); - } + // final Map<String, String[]> parameters = + // request.getParameterMap(); + // if (root != null && parameters != null) { + // root.handleParameters(parameters); + // } /* * Call the URI handlers and if this turns out to be a download * request, send the file to the client */ - if (handleURI(applicationManager, window, request, response)) { - return; - } + // if (handleURI(applicationManager, root, request, response)) { + // return; + // } // Send initial AJAX page that kickstarts a Vaadin application - writeAjaxPage(request, response, window, application); + writeAjaxPage(request, response, root, application); } catch (final SessionExpiredException e) { // Session has expired, notify user @@ -995,24 +995,25 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements } /** - * Returns the theme for given request/window + * Returns the theme for given request/root * * @param request - * @param window + * @param root * @return */ - private String getThemeForWindow(HttpServletRequest request, Window window) { + private String getThemeForRoot(HttpServletRequest request, Root root) { // Finds theme name String themeName; if (request.getParameter(URL_PARAMETER_THEME) != null) { themeName = request.getParameter(URL_PARAMETER_THEME); } else { - themeName = window.getTheme(); + // TODO Should read annotation + themeName = null; } if (themeName == null) { - // no explicit theme for window defined + // no explicit theme for root defined if (request.getAttribute(REQUEST_DEFAULT_THEME) != null) { // the default theme is defined in request (by portal) themeName = (String) request @@ -1063,33 +1064,34 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements return DEFAULT_THEME_NAME; } - /** - * Calls URI handlers for the request. If an URI handler returns a - * DownloadStream the stream is passed to the client for downloading. - * - * @param applicationManager - * @param window - * @param request - * @param response - * @return true if an DownloadStream was sent to the client, false otherwise - * @throws IOException - */ - protected boolean handleURI(CommunicationManager applicationManager, - Window window, HttpServletRequest request, - HttpServletResponse response) throws IOException { - // Handles the URI - DownloadStream download = applicationManager.handleURI(window, request, - response, this); - - // A download request - if (download != null) { - // Client downloads an resource - handleDownload(download, request, response); - return true; - } - - return false; - } + // /** + // * Calls URI handlers for the request. If an URI handler returns a + // * DownloadStream the stream is passed to the client for downloading. + // * + // * @param applicationManager + // * @param window + // * @param request + // * @param response + // * @return true if an DownloadStream was sent to the client, false + // otherwise + // * @throws IOException + // */ + // protected boolean handleURI(CommunicationManager applicationManager, + // Root window, HttpServletRequest request, + // HttpServletResponse response) throws IOException { + // // Handles the URI + // DownloadStream download = applicationManager.handleURI(window, request, + // response, this); + // + // // A download request + // if (download != null) { + // // Client downloads an resource + // handleDownload(download, request, response); + // return true; + // } + // + // return false; + // } void handleServiceSessionExpired(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { @@ -1666,7 +1668,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * <li> * {@link #writeAjaxPageHtmlBodyStart(BufferedWriter, HttpServletRequest)} * <li> - * {@link #writeAjaxPageHtmlVaadinScripts(Window, String, Application, BufferedWriter, String, String, String, HttpServletRequest)} + * {@link #writeAjaxPageHtmlVaadinScripts(Root, String, Application, BufferedWriter, String, String, String, HttpServletRequest)} * <li> * {@link #writeAjaxPageHtmlMainDiv(BufferedWriter, String, String, String, HttpServletRequest)} * <li> {@link #writeAjaxPageHtmlBodyEnd(BufferedWriter)} @@ -1678,7 +1680,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * the HTTP response to write to. * @param out * @param unhandledParameters - * @param window + * @param root * @param terminalType * @param theme * @throws IOException @@ -1688,7 +1690,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * represented by the given URL. */ protected void writeAjaxPage(HttpServletRequest request, - HttpServletResponse response, Window window, Application application) + HttpServletResponse response, Root root, Application application) throws IOException, MalformedURLException, ServletException { // e.g portlets only want a html fragment @@ -1702,7 +1704,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements final BufferedWriter page = new BufferedWriter(new OutputStreamWriter( response.getOutputStream(), "UTF-8")); - String title = ((window.getCaption() == null) ? "Vaadin 6" : window + String title = ((root.getCaption() == null) ? "Vaadin 6" : root .getCaption()); /* Fetch relative url to application */ @@ -1713,7 +1715,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements appUrl = appUrl.substring(0, appUrl.length() - 1); } - String themeName = getThemeForWindow(request, window); + String themeName = getThemeForRoot(request, root); String themeUri = getThemeUri(themeName, request); @@ -1737,8 +1739,8 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements } appId = appId + "-" + hashCode; - writeAjaxPageHtmlVaadinScripts(window, themeName, application, page, - appUrl, themeUri, appId, request); + writeAjaxPageHtmlVaadinScripts(themeName, application, page, appUrl, + themeUri, appId, request); /*- Add classnames; * .v-app @@ -1852,7 +1854,6 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * <p> * Override this method if you want to add some custom html around scripts. * - * @param window * @param themeName * @param application * @param page @@ -1863,7 +1864,8 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * @throws ServletException * @throws IOException */ - protected void writeAjaxPageHtmlVaadinScripts(Window window, + protected void writeAjaxPageHtmlVaadinScripts( + // Window window, String themeName, Application application, final BufferedWriter page, String appUrl, String themeUri, String appId, HttpServletRequest request) throws ServletException, @@ -1925,10 +1927,10 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements page.write("vaadin.vaadinConfigurations[\"" + appId + "\"] = {"); page.write("appUri:'" + appUrl + "', "); - if (window != application.getMainWindow()) { - page.write("windowName: \"" - + JsonPaintTarget.escapeJSON(window.getName()) + "\", "); - } + // if (window != application.getMainWindow()) { + // page.write("windowName: \"" + // + JsonPaintTarget.escapeJSON(window.getName()) + "\", "); + // } if (isStandalone()) { page.write("standalone: true, "); } @@ -2246,49 +2248,50 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements } /** - * Gets the existing application or create a new one. Get a window within an + * Gets the existing application or create a new one. Get a root within an * application based on the requested URI. * * @param request * the HTTP Request. * @param application - * the Application to query for window. - * @return Window matching the given URI or null if not found. + * the Application to query for root. + * @return Root matching the given URI or null if not found. * @throws ServletException * if an exception has occurred that interferes with the * servlet's normal operation. */ - protected Window getApplicationWindow(HttpServletRequest request, + protected Root getApplicationRoot(HttpServletRequest request, CommunicationManager applicationManager, Application application) throws ServletException { - - // Finds the window where the request is handled - Window assumedWindow = null; - String path = getRequestPathInfo(request); - - // Main window as the URI is empty - if (!(path == null || path.length() == 0 || path.equals("/"))) { - if (path.startsWith("/APP/")) { - // Use main window for application resources - return application.getMainWindow(); - } - String windowName = null; - if (path.charAt(0) == '/') { - path = path.substring(1); - } - final int index = path.indexOf('/'); - if (index < 0) { - windowName = path; - path = ""; - } else { - windowName = path.substring(0, index); - } - assumedWindow = application.getWindow(windowName); - - } - - return applicationManager.getApplicationWindow(request, this, - application, assumedWindow); + return application.getRoot(); + // + // // Finds the window where the request is handled + // Window assumedWindow = null; + // String path = getRequestPathInfo(request); + // + // // Main window as the URI is empty + // if (!(path == null || path.length() == 0 || path.equals("/"))) { + // if (path.startsWith("/APP/")) { + // // Use main window for application resources + // return application.getMainWindow(); + // } + // String windowName = null; + // if (path.charAt(0) == '/') { + // path = path.substring(1); + // } + // final int index = path.indexOf('/'); + // if (index < 0) { + // windowName = path; + // path = ""; + // } else { + // windowName = path.substring(0, index); + // } + // assumedWindow = application.getWindow(windowName); + // + // } + // + // return applicationManager.getApplicationWindow(request, this, + // application, assumedWindow); } /** diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java index c952623156..96d586ef71 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java @@ -16,7 +16,6 @@ import java.io.PrintWriter; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.net.URL; import java.security.GeneralSecurityException; import java.text.CharacterIterator; import java.text.DateFormat; @@ -67,6 +66,7 @@ import com.vaadin.terminal.gwt.server.ComponentSizeValidator.InvalidLayout; import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.AbstractField; import com.vaadin.ui.Component; +import com.vaadin.ui.Root; import com.vaadin.ui.Window; /** @@ -690,14 +690,14 @@ public abstract class AbstractCommunicationManager implements * @param request * @param response * @param callback - * @param window + * @param root * target window for the UIDL request, can be null if target not * found * @throws IOException * @throws InvalidUIDLSecurityKeyException */ protected void doHandleUidlRequest(Request request, Response response, - Callback callback, Window window) throws IOException, + Callback callback, Root root) throws IOException, InvalidUIDLSecurityKeyException { requestThemeName = request.getParameter("theme"); @@ -734,7 +734,7 @@ public abstract class AbstractCommunicationManager implements // Finds the window within the application if (application.isRunning()) { // Returns if no window found - if (window == null) { + if (root == null) { // This should not happen, no windows exists but // application is still open. logger.warning("Could not get window for application with request ID " @@ -748,8 +748,7 @@ public abstract class AbstractCommunicationManager implements } // Change all variables based on request parameters - if (!handleVariables(request, response, callback, application, - window)) { + if (!handleVariables(request, response, callback, application, root)) { // var inconsistency; the client is probably out-of-sync SystemMessages ci = null; @@ -780,7 +779,7 @@ public abstract class AbstractCommunicationManager implements } paintAfterVariableChanges(request, response, callback, repaintAll, - outWriter, window, analyzeLayouts); + outWriter, root, analyzeLayouts); if (closingWindowName != null) { currentlyOpenWindowsInClient.remove(closingWindowName); @@ -866,11 +865,11 @@ public abstract class AbstractCommunicationManager implements */ private void paintAfterVariableChanges(Request request, Response response, Callback callback, boolean repaintAll, final PrintWriter outWriter, - Window window, boolean analyzeLayouts) throws PaintException, + Root root, boolean analyzeLayouts) throws PaintException, IOException { if (repaintAll) { - makeAllPaintablesDirty(window); + makeAllPaintablesDirty(root); } // Removes application if it has stopped during variable changes @@ -901,18 +900,18 @@ public abstract class AbstractCommunicationManager implements // If the browser-window has been closed - we do not need to paint it at // all - if (window.getName().equals(closingWindowName)) { + if (root.getName().equals(closingWindowName)) { outWriter.print("\"changes\":[]"); } else { // re-get window - may have been changed - Window newWindow = doGetApplicationWindow(request, callback, - application, window); - if (newWindow != window) { - window = newWindow; + Root newRoot = doGetApplicationWindow(request, callback, + application, root); + if (newRoot != root) { + root = newRoot; repaintAll = true; } - writeUidlResponce(callback, repaintAll, outWriter, window, + writeUidlResponce(callback, repaintAll, outWriter, root, analyzeLayouts); } @@ -923,7 +922,7 @@ public abstract class AbstractCommunicationManager implements } public void writeUidlResponce(Callback callback, boolean repaintAll, - final PrintWriter outWriter, Window window, boolean analyzeLayouts) + final PrintWriter outWriter, Root root, boolean analyzeLayouts) throws PaintException { outWriter.print("\"changes\":["); @@ -933,17 +932,17 @@ public abstract class AbstractCommunicationManager implements JsonPaintTarget paintTarget = new JsonPaintTarget(this, outWriter, !repaintAll); - OpenWindowCache windowCache = currentlyOpenWindowsInClient.get(window + OpenWindowCache windowCache = currentlyOpenWindowsInClient.get(root .getName()); if (windowCache == null) { windowCache = new OpenWindowCache(); - currentlyOpenWindowsInClient.put(window.getName(), windowCache); + currentlyOpenWindowsInClient.put(root.getName(), windowCache); } // Paints components if (repaintAll) { paintables = new ArrayList<Paintable>(); - paintables.add(window); + paintables.add(root); // Reset sent locales locales = null; @@ -967,7 +966,7 @@ public abstract class AbstractCommunicationManager implements dirtyPaintables.remove(p); } } - paintables = getDirtyVisibleComponents(window); + paintables = getDirtyVisibleComponents(root); } if (paintables != null) { @@ -1003,10 +1002,10 @@ public abstract class AbstractCommunicationManager implements final Paintable p = i.next(); // TODO CLEAN - if (p instanceof Window) { - final Window w = (Window) p; - if (w.getTerminal() == null) { - w.setTerminal(application.getMainWindow().getTerminal()); + if (p instanceof Root) { + final Root r = (Root) p; + if (r.getTerminal() == null) { + r.setTerminal(application.getRoot().getTerminal()); } } /* @@ -1037,15 +1036,15 @@ public abstract class AbstractCommunicationManager implements .validateComponentRelativeSizes(w.getContent(), null, null); - // Also check any existing subwindows - if (w.getChildWindows() != null) { - for (Window subWindow : w.getChildWindows()) { - invalidComponentRelativeSizes = ComponentSizeValidator - .validateComponentRelativeSizes( - subWindow.getContent(), - invalidComponentRelativeSizes, null); - } - } + // // Also check any existing subwindows + // if (w.getChildWindows() != null) { + // for (Window subWindow : w.getChildWindows()) { + // invalidComponentRelativeSizes = ComponentSizeValidator + // .validateComponentRelativeSizes( + // subWindow.getContent(), + // invalidComponentRelativeSizes, null); + // } + // } } } } @@ -1134,8 +1133,8 @@ public abstract class AbstractCommunicationManager implements final String resource = (String) i.next(); InputStream is = null; try { - is = callback.getThemeResourceAsStream(getTheme(window), - resource); + is = callback + .getThemeResourceAsStream(getTheme(root), resource); } catch (final Exception e) { // FIXME: Handle exception logger.log(Level.FINER, "Failed to get theme resource stream.", @@ -1205,8 +1204,8 @@ public abstract class AbstractCommunicationManager implements return maxInactiveInterval; } - private String getTheme(Window window) { - String themeName = window.getTheme(); + private String getTheme(Root root) { + String themeName = null;// window.getTheme(); String requestThemeName = getRequestTheme(); if (requestThemeName != null) { @@ -1222,19 +1221,19 @@ public abstract class AbstractCommunicationManager implements return requestThemeName; } - public void makeAllPaintablesDirty(Window window) { + public void makeAllPaintablesDirty(Root root) { // If repaint is requested, clean all ids in this root window for (final Iterator<String> it = idPaintableMap.keySet().iterator(); it .hasNext();) { final Component c = (Component) idPaintableMap.get(it.next()); - if (isChildOf(window, c)) { + if (isChildOf(root, c)) { it.remove(); paintableIdMap.remove(c); } } // clean WindowCache - OpenWindowCache openWindowCache = currentlyOpenWindowsInClient - .get(window.getName()); + OpenWindowCache openWindowCache = currentlyOpenWindowsInClient.get(root + .getName()); if (openWindowCache != null) { openWindowCache.clear(); } @@ -1260,7 +1259,7 @@ public abstract class AbstractCommunicationManager implements * @return true if successful, false if there was an inconsistency */ private boolean handleVariables(Request request, Response response, - Callback callback, Application application2, Window window) + Callback callback, Application application2, Root root) throws IOException, InvalidUIDLSecurityKeyException { boolean success = true; @@ -1313,7 +1312,7 @@ public abstract class AbstractCommunicationManager implements new CharArrayWriter()); paintAfterVariableChanges(request, response, callback, - true, outWriter, window, false); + true, outWriter, root, false); } @@ -1382,11 +1381,10 @@ public abstract class AbstractCommunicationManager implements // Special-case of closing browser-level windows: // track browser-windows currently open in client - if (owner instanceof Window - && ((Window) owner).getParent() == null) { + if (owner instanceof Root) { final Boolean close = (Boolean) m.get("close"); if (close != null && close.booleanValue()) { - closingWindowName = ((Window) owner).getName(); + closingWindowName = ((Root) owner).getName(); } } } catch (Exception e) { @@ -1827,97 +1825,99 @@ public abstract class AbstractCommunicationManager implements * @param assumedWindow * @return */ - protected Window doGetApplicationWindow(Request request, Callback callback, - Application application, Window assumedWindow) { - - 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; + protected Root doGetApplicationWindow(Request request, Callback callback, + Application application, Root assumedRoot) { + return application.getRoot(); + + // 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; } /** @@ -2029,7 +2029,7 @@ public abstract class AbstractCommunicationManager implements * root window for which dirty components is to be fetched * @return */ - private ArrayList<Paintable> getDirtyVisibleComponents(Window w) { + private ArrayList<Paintable> getDirtyVisibleComponents(Root r) { final ArrayList<Paintable> resultset = new ArrayList<Paintable>( dirtyPaintables); @@ -2048,18 +2048,18 @@ public abstract class AbstractCommunicationManager implements resultset.remove(p); i.remove(); } else { - Window componentsRoot = component.getWindow(); + Root componentsRoot = component.getRoot(); if (componentsRoot == null) { // This should not happen unless somebody has overriden // getApplication or getWindow in an illegal way. throw new IllegalStateException( "component.getWindow() returned null for a component attached to the application"); } - if (componentsRoot.getParent() != null) { - // this is a subwindow - componentsRoot = componentsRoot.getParent(); - } - if (componentsRoot != w) { + // if (componentsRoot.getParent() != null) { + // // this is a subwindow + // componentsRoot = componentsRoot.getParent(); + // } + if (componentsRoot != r) { resultset.remove(p); } else if (component.getParent() != null && !component.getParent().isVisible()) { @@ -2223,7 +2223,7 @@ public abstract class AbstractCommunicationManager implements * @see com.vaadin.terminal.URIHandler */ @SuppressWarnings("deprecation") - protected DownloadStream handleURI(Window window, Request request, + protected DownloadStream handleURI(Root root, Request request, Response response, Callback callback) { String uri = callback.getRequestPathInfo(request); @@ -2240,32 +2240,34 @@ public abstract class AbstractCommunicationManager implements // Handles the uri try { - URL context = application.getURL(); - if (window == application.getMainWindow()) { - DownloadStream stream = null; - /* - * Application.handleURI run first. Handles possible - * ApplicationResources. - */ - stream = application.handleURI(context, uri); - if (stream == null) { - stream = window.handleURI(context, uri); - } - return stream; - } else { - // Resolve the prefix end index - final int index = uri.indexOf('/'); - if (index > 0) { - String prefix = uri.substring(0, index); - URL windowContext; - windowContext = new URL(context, prefix + "/"); - final String windowUri = (uri.length() > prefix.length() + 1) ? uri - .substring(prefix.length() + 1) : ""; - return window.handleURI(windowContext, windowUri); - } else { - return null; - } - } + throw new RuntimeException("Not ported to use roots"); + // URL context = application.getURL(); + // if (window == application.getMainWindow()) { + // DownloadStream stream = null; + // /* + // * Application.handleURI run first. Handles possible + // * ApplicationResources. + // */ + // stream = application.handleURI(context, uri); + // if (stream == null) { + // stream = window.handleURI(context, uri); + // } + // return stream; + // } else { + // // Resolve the prefix end index + // final int index = uri.indexOf('/'); + // if (index > 0) { + // String prefix = uri.substring(0, index); + // URL windowContext; + // windowContext = new URL(context, prefix + "/"); + // final String windowUri = (uri.length() > prefix.length() + 1) ? + // uri + // .substring(prefix.length() + 1) : ""; + // return window.handleURI(windowContext, windowUri); + // } else { + // return null; + // } + // } } catch (final Throwable t) { application.getErrorHandler().terminalError( diff --git a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java index 5851621a20..daeb31073f 100644 --- a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java @@ -23,6 +23,7 @@ import com.vaadin.terminal.Paintable; import com.vaadin.terminal.StreamVariable; import com.vaadin.terminal.VariableOwner; import com.vaadin.ui.Component; +import com.vaadin.ui.Root; import com.vaadin.ui.Window; /** @@ -278,13 +279,12 @@ public class CommunicationManager extends AbstractCommunicationManager { */ public void handleUidlRequest(HttpServletRequest request, HttpServletResponse response, - AbstractApplicationServlet applicationServlet, Window window) + AbstractApplicationServlet applicationServlet, Root root) throws IOException, ServletException, InvalidUIDLSecurityKeyException { doHandleUidlRequest(new HttpServletRequestWrapper(request), new HttpServletResponseWrapper(response), - new AbstractApplicationServletWrapper(applicationServlet), - window); + new AbstractApplicationServletWrapper(applicationServlet), root); } /** @@ -295,7 +295,7 @@ public class CommunicationManager extends AbstractCommunicationManager { * the HTTP Request. * @param application * the Application to query for window. - * @param assumedWindow + * @param assumedRoot * if the window has been already resolved once, this parameter * must contain the window. * @return Window matching the given URI or null if not found. @@ -303,13 +303,12 @@ public class CommunicationManager extends AbstractCommunicationManager { * if an exception has occurred that interferes with the * servlet's normal operation. */ - Window getApplicationWindow(HttpServletRequest request, + Root getApplicationRoot(HttpServletRequest request, AbstractApplicationServlet applicationServlet, - Application application, Window assumedWindow) - throws ServletException { + Application application, Root assumedRoot) throws ServletException { return doGetApplicationWindow(new HttpServletRequestWrapper(request), new AbstractApplicationServletWrapper(applicationServlet), - application, assumedWindow); + application, assumedRoot); } /** @@ -324,16 +323,16 @@ public class CommunicationManager extends AbstractCommunicationManager { * @see AbstractCommunicationManager#handleURI(Window, Request, Response, * Callback) * - * @param window + * @param root * @param request * @param response * @param applicationServlet * @return */ - DownloadStream handleURI(Window window, HttpServletRequest request, + DownloadStream handleURI(Root root, HttpServletRequest request, HttpServletResponse response, AbstractApplicationServlet applicationServlet) { - return handleURI(window, new HttpServletRequestWrapper(request), + return handleURI(root, new HttpServletRequestWrapper(request), new HttpServletResponseWrapper(response), new AbstractApplicationServletWrapper(applicationServlet)); } diff --git a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java index aba772a26e..fc281d90f9 100644 --- a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java +++ b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java @@ -35,8 +35,7 @@ import javax.xml.namespace.QName; import com.vaadin.Application; import com.vaadin.terminal.ApplicationResource; -import com.vaadin.terminal.ExternalResource; -import com.vaadin.ui.Window; +import com.vaadin.ui.Root; /** * TODO Write documentation, fix JavaDoc tags. @@ -172,18 +171,18 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { } } - public void firePortletRenderRequest(Application app, Window window, + public void firePortletRenderRequest(Application app, Root root, RenderRequest request, RenderResponse response) { Set<PortletListener> listeners = portletListeners.get(app); if (listeners != null) { for (PortletListener l : listeners) { l.handleRenderRequest(request, new RestrictedRenderResponse( - response), window); + response), root); } } } - public void firePortletActionRequest(Application app, Window window, + public void firePortletActionRequest(Application app, Root root, ActionRequest request, ActionResponse response) { String key = request.getParameter(ActionRequest.ACTION_NAME); if (eventActionDestinationMap.containsKey(key)) { @@ -205,28 +204,28 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { Set<PortletListener> listeners = portletListeners.get(app); if (listeners != null) { for (PortletListener l : listeners) { - l.handleActionRequest(request, response, window); + l.handleActionRequest(request, response, root); } } } } - public void firePortletEventRequest(Application app, Window window, + public void firePortletEventRequest(Application app, Root root, EventRequest request, EventResponse response) { Set<PortletListener> listeners = portletListeners.get(app); if (listeners != null) { for (PortletListener l : listeners) { - l.handleEventRequest(request, response, window); + l.handleEventRequest(request, response, root); } } } - public void firePortletResourceRequest(Application app, Window window, + public void firePortletResourceRequest(Application app, Root root, ResourceRequest request, ResourceResponse response) { Set<PortletListener> listeners = portletListeners.get(app); if (listeners != null) { for (PortletListener l : listeners) { - l.handleResourceRequest(request, response, window); + l.handleResourceRequest(request, response, root); } } } @@ -234,16 +233,16 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { public interface PortletListener extends Serializable { public void handleRenderRequest(RenderRequest request, - RenderResponse response, Window window); + RenderResponse response, Root root); public void handleActionRequest(ActionRequest request, - ActionResponse response, Window window); + ActionResponse response, Root root); public void handleEventRequest(EventRequest request, - EventResponse response, Window window); + EventResponse response, Root root); public void handleResourceRequest(ResourceRequest request, - ResourceResponse response, Window window); + ResourceResponse response, Root root); } /** @@ -308,7 +307,7 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { * Event names for events sent and received by a portlet need to be declared * in portlet.xml . * - * @param window + * @param root * a window in which a temporary action URL can be opened if * necessary * @param name @@ -317,7 +316,7 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { * event value object that is Serializable and, if appropriate, * has a valid JAXB annotation */ - public void sendPortletEvent(Window window, QName name, Serializable value) + public void sendPortletEvent(Root root, QName name, Serializable value) throws IllegalStateException { if (response instanceof MimeResponse) { String actionKey = "" + System.currentTimeMillis(); @@ -328,7 +327,9 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { if (actionUrl != null) { eventActionDestinationMap.put(actionKey, name); eventActionValueMap.put(actionKey, value); - window.open(new ExternalResource(actionUrl.toString())); + throw new RuntimeException( + "Root.open has not yet been implemented"); + // root.open(new ExternalResource(actionUrl.toString())); } else { // this should never happen as we already know the response is a // MimeResponse @@ -355,7 +356,7 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { * Shared parameters set or read by a portlet need to be declared in * portlet.xml . * - * @param window + * @param root * a window in which a temporary action URL can be opened if * necessary * @param name @@ -363,8 +364,8 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { * @param value * parameter value */ - public void setSharedRenderParameter(Window window, String name, - String value) throws IllegalStateException { + public void setSharedRenderParameter(Root root, String name, String value) + throws IllegalStateException { if (response instanceof MimeResponse) { String actionKey = "" + System.currentTimeMillis(); while (sharedParameterActionNameMap.containsKey(actionKey)) { @@ -374,7 +375,9 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { if (actionUrl != null) { sharedParameterActionNameMap.put(actionKey, name); sharedParameterActionValueMap.put(actionKey, value); - window.open(new ExternalResource(actionUrl.toString())); + throw new RuntimeException( + "Root.open has not yet been implemented"); + // root.open(new ExternalResource(actionUrl.toString())); } else { // this should never happen as we already know the response is a // MimeResponse @@ -394,7 +397,7 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { * * Portlet modes used by a portlet need to be declared in portlet.xml . * - * @param window + * @param root * a window in which the render URL can be opened if necessary * @param portletMode * the portlet mode to switch to @@ -402,12 +405,13 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { * if the portlet mode is not allowed for some reason * (configuration, permissions etc.) */ - public void setPortletMode(Window window, PortletMode portletMode) + public void setPortletMode(Root root, PortletMode portletMode) throws IllegalStateException, PortletModeException { if (response instanceof MimeResponse) { PortletURL url = ((MimeResponse) response).createRenderURL(); url.setPortletMode(portletMode); - window.open(new ExternalResource(url.toString())); + throw new RuntimeException("Root.open has not yet been implemented"); + // root.open(new ExternalResource(url.toString())); } else if (response instanceof StateAwareResponse) { ((StateAwareResponse) response).setPortletMode(portletMode); } else { diff --git a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java index d9fa9ecd6c..466769b328 100644 --- a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java @@ -27,7 +27,7 @@ import com.vaadin.terminal.Paintable; import com.vaadin.terminal.StreamVariable; import com.vaadin.terminal.VariableOwner; import com.vaadin.ui.Component; -import com.vaadin.ui.Window; +import com.vaadin.ui.Root; /** * TODO document me! @@ -224,20 +224,19 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { public void handleUidlRequest(ResourceRequest request, ResourceResponse response, - AbstractApplicationPortlet applicationPortlet, Window window) + AbstractApplicationPortlet applicationPortlet, Root root) throws InvalidUIDLSecurityKeyException, IOException { currentUidlResponse = response; doHandleUidlRequest(new PortletRequestWrapper(request), new PortletResponseWrapper(response), - new AbstractApplicationPortletWrapper(applicationPortlet), - window); + new AbstractApplicationPortletWrapper(applicationPortlet), root); currentUidlResponse = null; } - DownloadStream handleURI(Window window, ResourceRequest request, + DownloadStream handleURI(Root root, ResourceRequest request, ResourceResponse response, AbstractApplicationPortlet applicationPortlet) { - return handleURI(window, new PortletRequestWrapper(request), + return handleURI(root, new PortletRequestWrapper(request), new PortletResponseWrapper(response), new AbstractApplicationPortletWrapper(applicationPortlet)); } @@ -251,7 +250,7 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { * @param applicationPortlet * @param application * the Application to query for window. - * @param assumedWindow + * @param assumedRoot * if the window has been already resolved once, this parameter * must contain the window. * @return Window matching the given URI or null if not found. @@ -259,13 +258,13 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { * if an exception has occurred that interferes with the * servlet's normal operation. */ - Window getApplicationWindow(PortletRequest request, + Root getApplicationRoot(PortletRequest request, AbstractApplicationPortlet applicationPortlet, - Application application, Window assumedWindow) { + Application application, Root assumedRoot) { return doGetApplicationWindow(new PortletRequestWrapper(request), new AbstractApplicationPortletWrapper(applicationPortlet), - application, assumedWindow); + application, assumedRoot); } private Map<VariableOwner, Map<String, StreamVariable>> ownerToNameToStreamVariable; diff --git a/src/com/vaadin/ui/AbstractComponent.java b/src/com/vaadin/ui/AbstractComponent.java index eda2fd64ad..9b05bf02f9 100644 --- a/src/com/vaadin/ui/AbstractComponent.java +++ b/src/com/vaadin/ui/AbstractComponent.java @@ -609,11 +609,11 @@ public abstract class AbstractComponent implements Component, MethodEventSource * Gets the parent window of the component. Don't add a JavaDoc comment * here, we use the default documentation from implemented interface. */ - public Window getWindow() { + public Root getRoot() { if (parent == null) { return null; } else { - return parent.getWindow(); + return parent.getRoot(); } } @@ -651,7 +651,7 @@ public abstract class AbstractComponent implements Component, MethodEventSource if (this instanceof Focusable) { final Application app = getApplication(); if (app != null) { - getWindow().setFocusedComponent((Focusable) this); + getRoot().setFocusedComponent((Focusable) this); delayedFocus = false; } else { delayedFocus = true; diff --git a/src/com/vaadin/ui/AbstractField.java b/src/com/vaadin/ui/AbstractField.java index 7899569ea8..5df0ac8fe6 100644 --- a/src/com/vaadin/ui/AbstractField.java +++ b/src/com/vaadin/ui/AbstractField.java @@ -1118,17 +1118,17 @@ public abstract class AbstractField extends AbstractComponent implements Field, @Override public void attach() { super.attach(); - if (actionManager != null) { - actionManager.setViewer(getWindow()); - } + // if (actionManager != null) { + // actionManager.setViewer(getRoot()); + // } } @Override public void detach() { super.detach(); - if (actionManager != null) { - actionManager.setViewer((Window) null); - } + // if (actionManager != null) { + // actionManager.setViewer((Window) null); + // } } /** @@ -1257,9 +1257,9 @@ public abstract class AbstractField extends AbstractComponent implements Field, protected ActionManager getActionManager() { if (actionManager == null) { actionManager = new ActionManager(); - if (getWindow() != null) { - actionManager.setViewer(getWindow()); - } + // if (getRoot() != null) { + // actionManager.setViewer(getRoot()); + // } } return actionManager; } diff --git a/src/com/vaadin/ui/Component.java b/src/com/vaadin/ui/Component.java index 2d794c39b0..e5e1bb473e 100644 --- a/src/com/vaadin/ui/Component.java +++ b/src/com/vaadin/ui/Component.java @@ -573,7 +573,7 @@ public interface Component extends Paintable, VariableOwner, Sizeable, * @return the parent window of the component or <code>null</code> if it is * not attached to a window or is itself a window */ - public Window getWindow(); + public Root getRoot(); /** * Gets the application object to which the component is attached. @@ -606,7 +606,7 @@ public interface Component extends Paintable, VariableOwner, Sizeable, * <p> * Reimplementing the {@code attach()} method is useful for tasks that need * to get a reference to the parent, window, or application object with the - * {@link #getParent()}, {@link #getWindow()}, and {@link #getApplication()} + * {@link #getParent()}, {@link #getRoot()}, and {@link #getApplication()} * methods. A component does not yet know these objects in the constructor, * so in such case, the methods will return {@code null}. For example, the * following is invalid: @@ -661,7 +661,7 @@ public interface Component extends Paintable, VariableOwner, Sizeable, * Notifies the component that it is detached from the application. * * <p> - * The {@link #getApplication()} and {@link #getWindow()} methods might + * The {@link #getApplication()} and {@link #getRoot()} methods might * return <code>null</code> after this method is called. * </p> * diff --git a/src/com/vaadin/ui/DefaultRoot.java b/src/com/vaadin/ui/DefaultRoot.java new file mode 100644 index 0000000000..7adf5a892a --- /dev/null +++ b/src/com/vaadin/ui/DefaultRoot.java @@ -0,0 +1,418 @@ +package com.vaadin.ui; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; + +import com.vaadin.Application; +import com.vaadin.terminal.PaintException; +import com.vaadin.terminal.PaintTarget; +import com.vaadin.terminal.Terminal; +import com.vaadin.terminal.gwt.client.ui.VView; +import com.vaadin.ui.Window.CloseListener; +import com.vaadin.ui.Window.Notification; + +@ClientWidget(VView.class) +public class DefaultRoot extends AbstractComponentContainer implements Root { + private final Component content; + private Terminal terminal; + private Application application; + + /** + * A list of notifications that are waiting to be sent to the client. + * Cleared (set to null) when the notifications have been sent. + */ + private List<Notification> notifications; + + /** + * A list of javascript commands that are waiting to be sent to the client. + * Cleared (set to null) when the commands have been sent. + */ + private List<String> jsExecQueue = null; + + /** + * List of windows in this root. + */ + private final LinkedHashSet<Window> windows = new LinkedHashSet<Window>(); + + public DefaultRoot(Component content) { + this.content = content; + addComponent(content); + } + + @Override + public Root getRoot() { + return this; + } + + public void replaceComponent(Component oldComponent, Component newComponent) { + throw new UnsupportedOperationException(); + } + + @Override + public Application getApplication() { + return application; + } + + @Override + public void paintContent(PaintTarget target) throws PaintException { + content.paint(target); + + // Paint subwindows + for (final Iterator<Window> i = windows.iterator(); i.hasNext();) { + final Window w = i.next(); + w.paint(target); + } + + // Paint notifications + if (notifications != null) { + target.startTag("notifications"); + for (final Iterator<Notification> it = notifications.iterator(); it + .hasNext();) { + final Notification n = it.next(); + target.startTag("notification"); + if (n.getCaption() != null) { + target.addAttribute("caption", n.getCaption()); + } + if (n.getDescription() != null) { + target.addAttribute("message", n.getDescription()); + } + if (n.getIcon() != null) { + target.addAttribute("icon", n.getIcon()); + } + if (!n.isHtmlContentAllowed()) { + target.addAttribute( + VView.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED, true); + } + target.addAttribute("position", n.getPosition()); + target.addAttribute("delay", n.getDelayMsec()); + if (n.getStyleName() != null) { + target.addAttribute("style", n.getStyleName()); + } + target.endTag("notification"); + } + target.endTag("notifications"); + notifications = null; + } + + // Add executable javascripts if needed + if (jsExecQueue != null) { + for (String script : jsExecQueue) { + target.startTag("execJS"); + target.addAttribute("script", script); + target.endTag("execJS"); + } + jsExecQueue = null; + } + + if (pendingFocus != null) { + // ensure focused component is still attached to this main window + if (pendingFocus.getRoot() == this + || (pendingFocus.getRoot() != null && pendingFocus + .getRoot().getParent() == this)) { + target.addAttribute("focused", pendingFocus); + } + pendingFocus = null; + } + } + + public Iterator<Component> getComponentIterator() { + return Collections.singleton(content).iterator(); + } + + public String getName() { + return ""; + } + + public Terminal getTerminal() { + return terminal; + } + + public void setTerminal(Terminal terminal) { + this.terminal = terminal; + } + + public void setApplication(Application application) { + if (application == null) { + throw new NullPointerException("application"); + } else if (this.application != null) { + throw new IllegalStateException("Application has already been set"); + } else { + this.application = application; + } + } + + /** + * Adds a window inside this root. + * + * <p> + * Adding windows inside another window creates "subwindows". These windows + * should not be added to application directly and are not accessible + * directly with any url. Addding windows implicitly sets their parents. + * </p> + * + * <p> + * Only one level of subwindows are supported. Thus you can add windows + * inside such windows whose parent is <code>null</code>. + * </p> + * + * @param window + * @throws IllegalArgumentException + * if a window is added inside non-application level window. + * @throws NullPointerException + * if the given <code>Window</code> is <code>null</code>. + */ + public void addWindow(Window window) throws IllegalArgumentException, + NullPointerException { + + if (window == null) { + throw new NullPointerException("Argument must not be null"); + } + + if (window.getApplication() != null) { + throw new IllegalArgumentException( + "Window is already attached to an application."); + } + + attachWindow(window); + } + + private void attachWindow(Window w) { + windows.add(w); + w.setParent(this); + requestRepaint(); + } + + /** + * Remove the given subwindow from this root. + * + * Since Vaadin 6.5, {@link CloseListener}s are called also when explicitly + * removing a window by calling this method. + * + * Since Vaadin 6.5, returns a boolean indicating if the window was removed + * or not. + * + * @param window + * Window to be removed. + * @return true if the subwindow was removed, false otherwise + */ + public boolean removeWindow(Window window) { + if (!windows.remove(window)) { + // Window window is not a subwindow of this root. + return false; + } + window.setParent(null); + window.fireClose(); + requestRepaint(); + + return true; + } + + public Collection<Window> getWindows() { + return Collections.unmodifiableCollection(windows); + } + + public int getTabIndex() { + throw new IllegalStateException("Tab index not defined for roots"); + } + + public void setTabIndex(int tabIndex) { + throw new IllegalStateException("Tab index not defined for roots"); + } + + @Override + public void focus() { + super.focus(); + } + + /** + * Component that should be focused after the next repaint. Null if no focus + * change should take place. + */ + private Focusable pendingFocus; + + /** + * This method is used by Component.Focusable objects to request focus to + * themselves. Focus renders must be handled at window level (instead of + * Component.Focusable) due we want the last focused component to be focused + * in client too. Not the one that is rendered last (the case we'd get if + * implemented in Focusable only). + * + * To focus component from Vaadin application, use Focusable.focus(). See + * {@link Focusable}. + * + * @param focusable + * to be focused on next paint + */ + public void setFocusedComponent(Focusable focusable) { + pendingFocus = focusable; + requestRepaint(); + } + + /** + * Shows a notification message on the middle of the window. The message + * automatically disappears ("humanized message"). + * + * Care should be taken to to avoid XSS vulnerabilities as the caption is + * rendered as html. + * + * @see #showNotification(com.vaadin.ui.Window.Notification) + * @see Notification + * + * @param caption + * The message + */ + public void showNotification(String caption) { + addNotification(new Notification(caption)); + } + + /** + * Shows a notification message the window. The position and behavior of the + * message depends on the type, which is one of the basic types defined in + * {@link Notification}, for instance Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to to avoid XSS vulnerabilities as the caption is + * rendered as html. + * + * @see #showNotification(com.vaadin.ui.Window.Notification) + * @see Notification + * + * @param caption + * The message + * @param type + * The message type + */ + public void showNotification(String caption, int type) { + addNotification(new Notification(caption, type)); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description on the middle of the window. The message automatically + * disappears ("humanized message"). + * + * Care should be taken to to avoid XSS vulnerabilities as the caption and + * description are rendered as html. + * + * @see #showNotification(com.vaadin.ui.Window.Notification) + * @see Notification + * + * @param caption + * The caption of the message + * @param description + * The message description + * + */ + public void showNotification(String caption, String description) { + addNotification(new Notification(caption, description)); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description. The position and behavior of the message depends on the + * type, which is one of the basic types defined in {@link Notification}, + * for instance Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to to avoid XSS vulnerabilities as the caption and + * description are rendered as html. + * + * @see #showNotification(com.vaadin.ui.Window.Notification) + * @see Notification + * + * @param caption + * The caption of the message + * @param description + * The message description + * @param type + * The message type + */ + public void showNotification(String caption, String description, int type) { + addNotification(new Notification(caption, description, type)); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description. The position and behavior of the message depends on the + * type, which is one of the basic types defined in {@link Notification}, + * for instance Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to avoid XSS vulnerabilities if html content is + * allowed. + * + * @see #showNotification(com.vaadin.ui.Window.Notification) + * @see Notification + * + * @param caption + * The message caption + * @param description + * The message description + * @param type + * The type of message + * @param htmlContentAllowed + * Whether html in the caption and description should be + * displayed as html or as plain text + */ + public void showNotification(String caption, String description, int type, + boolean htmlContentAllowed) { + addNotification(new Notification(caption, description, type, + htmlContentAllowed)); + } + + /** + * Shows a notification message. + * + * @see Notification + * @see #showNotification(String) + * @see #showNotification(String, int) + * @see #showNotification(String, String) + * @see #showNotification(String, String, int) + * + * @param notification + * The notification message to show + */ + public void showNotification(Notification notification) { + addNotification(notification); + } + + private void addNotification(Notification notification) { + if (notifications == null) { + notifications = new LinkedList<Notification>(); + } + notifications.add(notification); + requestRepaint(); + } + + /** + * Executes JavaScript in this root. + * + * <p> + * This method allows one to inject javascript from the server to client. A + * client implementation is not required to implement this functionality, + * but currently all web-based clients do implement this. + * </p> + * + * <p> + * Executing javascript this way often leads to cross-browser compatibility + * issues and regressions that are hard to resolve. Use of this method + * should be avoided and instead it is recommended to create new widgets + * with GWT. For more info on creating own, reusable client-side widgets in + * Java, read the corresponding chapter in Book of Vaadin. + * </p> + * + * @param script + * JavaScript snippet that will be executed. + */ + public void executeJavaScript(String script) { + if (jsExecQueue == null) { + jsExecQueue = new ArrayList<String>(); + } + + jsExecQueue.add(script); + + requestRepaint(); + } +} diff --git a/src/com/vaadin/ui/LoginForm.java b/src/com/vaadin/ui/LoginForm.java index 509a072c27..add2a53ff2 100644 --- a/src/com/vaadin/ui/LoginForm.java +++ b/src/com/vaadin/ui/LoginForm.java @@ -79,7 +79,7 @@ public class LoginForm extends CustomComponent { public void handleParameters(Map<String, String[]> parameters) { if (parameters.containsKey("username")) { - getWindow().addURIHandler(uriHandler); + // getWindow().addURIHandler(uriHandler); HashMap<String, String> params = new HashMap<String, String>(); // expecting single params @@ -102,9 +102,9 @@ public class LoginForm extends CustomComponent { public DownloadStream handleURI(URL context, String relativeUri) { if (relativeUri != null && relativeUri.contains("loginHandler")) { - if (window != null) { - window.removeURIHandler(this); - } + // if (window != null) { + // window.removeURIHandler(this); + // } DownloadStream downloadStream = new DownloadStream( new ByteArrayInputStream(responce.getBytes()), "text/html", "loginSuccesfull"); @@ -116,7 +116,7 @@ public class LoginForm extends CustomComponent { } }; - private Window window; + // private Window window; public LoginForm() { iframe.setType(Embedded.TYPE_BROWSER); @@ -135,7 +135,8 @@ public class LoginForm extends CustomComponent { */ protected byte[] getLoginHTML() { String appUri = getApplication().getURL().toString() - + getWindow().getName() + "/"; + // + getWindow().getName() + + "/"; try { return ("<!DOCTYPE html PUBLIC \"-//W3C//DTD " @@ -190,21 +191,21 @@ public class LoginForm extends CustomComponent { public void attach() { super.attach(); getApplication().addResource(loginPage); - getWindow().addParameterHandler(paramHandler); + // getWindow().addParameterHandler(paramHandler); iframe.setSource(loginPage); } @Override public void detach() { getApplication().removeResource(loginPage); - getWindow().removeParameterHandler(paramHandler); + // getWindow().removeParameterHandler(paramHandler); // store window temporary to properly remove uri handler once // response is handled. (May happen if login handler removes login // form - window = getWindow(); - if (window.getParent() != null) { - window = window.getParent(); - } + // window = getRoot(); + // if (window.getParent() != null) { + // window = window.getParent(); + // } super.detach(); } diff --git a/src/com/vaadin/ui/Root.java b/src/com/vaadin/ui/Root.java new file mode 100644 index 0000000000..30659d98e3 --- /dev/null +++ b/src/com/vaadin/ui/Root.java @@ -0,0 +1,55 @@ +package com.vaadin.ui; + +import java.util.Collection; + +import com.vaadin.Application; +import com.vaadin.terminal.Terminal; +import com.vaadin.ui.Window.Notification; + +public interface Root extends Component, com.vaadin.ui.Component.Focusable { + + /** + * Sets the application this root is attached to. + * + * <p> + * This method is called by the framework and should not be called directly + * from application code. + * </p> + * + * @param application + * the application the root is attached to + */ + public void setApplication(Application application); + + // TODO is this required? + public String getName(); + + public Terminal getTerminal(); + + public void setTerminal(Terminal terminal); + + public void addWindow(Window window); + + public boolean removeWindow(Window window); + + public Collection<Window> getWindows(); + + public void setFocusedComponent(Focusable focusable); + + public void showNotification(Notification notification); + + public void showNotification(String caption, String description, + int type, boolean htmlContentAllowed); + + public void showNotification(String caption, String description, + int type); + + public void showNotification(String caption, String description); + + public void showNotification(String caption, int type); + + public void showNotification(String caption); + + public void executeJavaScript(String script); + +} diff --git a/src/com/vaadin/ui/Window.java b/src/com/vaadin/ui/Window.java index ddd1f6fc3b..4c72ecf844 100644 --- a/src/com/vaadin/ui/Window.java +++ b/src/com/vaadin/ui/Window.java @@ -6,15 +6,7 @@ package com.vaadin.ui; import java.io.Serializable; import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; import java.util.Map; -import java.util.Set; import com.vaadin.Application; import com.vaadin.event.FieldEvents.BlurEvent; @@ -27,14 +19,10 @@ import com.vaadin.event.ShortcutAction; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.event.ShortcutAction.ModifierKey; import com.vaadin.event.ShortcutListener; -import com.vaadin.terminal.DownloadStream; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.ParameterHandler; import com.vaadin.terminal.Resource; import com.vaadin.terminal.Sizeable; -import com.vaadin.terminal.Terminal; -import com.vaadin.terminal.URIHandler; import com.vaadin.terminal.gwt.client.ui.VView; import com.vaadin.terminal.gwt.client.ui.VWindow; @@ -85,8 +73,7 @@ import com.vaadin.terminal.gwt.client.ui.VWindow; */ @SuppressWarnings("serial") @ClientWidget(VWindow.class) -public class Window extends Panel implements URIHandler, ParameterHandler, - FocusNotifier, BlurNotifier { +public class Window extends Panel implements FocusNotifier, BlurNotifier { /** * <b>Application window only</b>. A border style used for opening resources @@ -106,57 +93,36 @@ public class Window extends Panel implements URIHandler, ParameterHandler, */ public static final int BORDER_DEFAULT = 2; - /** - * <b>Application window only</b>. The user terminal for this window. - */ - private Terminal terminal = null; - - /** - * <b>Application window only</b>. The application this window is attached - * to or null. - */ - private Application application = null; - - /** - * <b>Application window only</b>. List of URI handlers for this window. - */ - private LinkedList<URIHandler> uriHandlerList = null; - - /** - * <b>Application window only</b>. List of parameter handlers for this - * window. - */ - private LinkedList<ParameterHandler> parameterHandlerList = null; - - /** - * <b>Application window only</b>. List of sub windows in this window. A sub - * window cannot have other sub windows. - */ - private final LinkedHashSet<Window> subwindows = new LinkedHashSet<Window>(); - - /** - * <b>Application window only</b>. Explicitly specified theme of this window - * or null if the application theme should be used. - */ - private String theme = null; - - /** - * <b>Application window only</b>. Resources to be opened automatically on - * next repaint. The list is automatically cleared when it has been sent to - * the client. - */ - private final LinkedList<OpenResource> openList = new LinkedList<OpenResource>(); - - /** - * <b>Application window only</b>. Unique name of the window used to - * identify it. - */ - private String name = null; - - /** - * <b>Application window only.</b> Border mode of the Window. - */ - private int border = BORDER_DEFAULT; + // /** + // * <b>Application window only</b>. List of URI handlers for this window. + // */ + // private LinkedList<URIHandler> uriHandlerList = null; + // + // /** + // * <b>Application window only</b>. List of parameter handlers for this + // * window. + // */ + // private LinkedList<ParameterHandler> parameterHandlerList = null; + // + // /** + // * <b>Application window only</b>. Resources to be opened automatically on + // * next repaint. The list is automatically cleared when it has been sent + // to + // * the client. + // */ + // private final LinkedList<OpenResource> openList = new + // LinkedList<OpenResource>(); + // + // /** + // * <b>Application window only</b>. Unique name of the window used to + // * identify it. + // */ + // private String name = null; + // + // /** + // * <b>Application window only.</b> Border mode of the Window. + // */ + // private int border = BORDER_DEFAULT; /** * <b>Sub window only</b>. Top offset in pixels for the sub window (relative @@ -171,13 +137,6 @@ public class Window extends Panel implements URIHandler, ParameterHandler, private int positionX = -1; /** - * <b>Application window only</b>. A list of notifications that are waiting - * to be sent to the client. Cleared (set to null) when the notifications - * have been sent. - */ - private LinkedList<Notification> notifications; - - /** * <b>Sub window only</b>. Modality flag for sub window. */ private boolean modal = false; @@ -205,19 +164,6 @@ public class Window extends Panel implements URIHandler, ParameterHandler, private boolean resizeLazy = false; /** - * Component that should be focused after the next repaint. Null if no focus - * change should take place. - */ - private Focusable pendingFocus; - - /** - * <b>Application window only</b>. A list of javascript commands that are - * waiting to be sent to the client. Cleared (set to null) when the commands - * have been sent. - */ - private ArrayList<String> jsExecQueue = null; - - /** * The component that should be scrolled into view after the next repaint. * Null if nothing should be scrolled into view. */ @@ -269,288 +215,183 @@ public class Window extends Panel implements URIHandler, ParameterHandler, super.addComponent(c); } - /** - * <b>Application window only</b>. Gets the user terminal. - * - * @return the user terminal - */ - public Terminal getTerminal() { - return terminal; - } - /* ********************************************************************* */ - /** - * Gets the parent window of the component. - * <p> - * This is always the window itself. - * </p> - * <p> - * <b>This method is not meant to be overridden. Due to CDI requirements we - * cannot declare it as final even though it should be final.</b> - * </p> - * - * @see Component#getWindow() - * @return the window itself - */ - @Override - public Window getWindow() { - return this; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.AbstractComponent#getApplication() - */ - @Override - public Application getApplication() { - if (getParent() == null) { - return application; - } - return getParent().getApplication(); - } - - /** - * Gets the parent component of the window. - * - * <p> - * The parent of an application window is always null. The parent of a sub - * window is the application window the sub window is attached to. - * </p> - * <p> - * <b>This method is not meant to be overridden. Due to CDI requirements we - * cannot declare it as final even though it should be final.</b> - * </p> - * - * - * @return the parent window - * @see Component#getParent() - */ - @Override - public Window getParent() { - return (Window) super.getParent(); - } + // /** + // * <b>Application window only</b>. Adds a new URI handler to this window. + // If + // * this is a sub window the URI handler is attached to the parent + // * application window. + // * + // * @param handler + // * the URI handler to add. + // */ + // public void addURIHandler(URIHandler handler) { + // if (getParent() != null) { + // // this is subwindow, attach to main level instead + // // TODO hold internal list also and remove on detach + // Window mainWindow = getParent(); + // mainWindow.addURIHandler(handler); + // } else { + // if (uriHandlerList == null) { + // uriHandlerList = new LinkedList<URIHandler>(); + // } + // synchronized (uriHandlerList) { + // if (!uriHandlerList.contains(handler)) { + // uriHandlerList.addLast(handler); + // } + // } + // } + // } + + // /** + // * <b>Application window only</b>. Removes the URI handler from this + // window. + // * If this is a sub window the URI handler is removed from the parent + // * application window. + // * + // * @param handler + // * the URI handler to remove. + // */ + // public void removeURIHandler(URIHandler handler) { + // if (getParent() != null) { + // // this is subwindow + // Window mainWindow = getParent(); + // mainWindow.removeURIHandler(handler); + // } else { + // if (handler == null || uriHandlerList == null) { + // return; + // } + // synchronized (uriHandlerList) { + // uriHandlerList.remove(handler); + // if (uriHandlerList.isEmpty()) { + // uriHandlerList = null; + // } + // } + // } + // } + + // /** + // * <b>Application window only</b>. Handles an URI by passing the URI to + // all + // * URI handlers defined using {@link #addURIHandler(URIHandler)}. All URI + // * handlers are called for each URI but no more than one handler may + // return + // * a {@link DownloadStream}. If more than one stream is returned a + // * {@code RuntimeException} is thrown. + // * + // * @param context + // * The URL of the application + // * @param relativeUri + // * The URI relative to {@code context} + // * @return A {@code DownloadStream} that one of the URI handlers returned, + // * null if no {@code DownloadStream} was returned. + // */ + // public DownloadStream handleURI(URL context, String relativeUri) { + // + // DownloadStream result = null; + // if (uriHandlerList != null) { + // Object[] handlers; + // synchronized (uriHandlerList) { + // handlers = uriHandlerList.toArray(); + // } + // for (int i = 0; i < handlers.length; i++) { + // final DownloadStream ds = ((URIHandler) handlers[i]).handleURI( + // context, relativeUri); + // if (ds != null) { + // if (result != null) { + // throw new RuntimeException("handleURI for " + context + // + " uri: '" + relativeUri + // + "' returns ambigious result."); + // } + // result = ds; + // } + // } + // } + // return result; + // } /* ********************************************************************* */ - /** - * <b>Application window only</b>. Adds a new URI handler to this window. If - * this is a sub window the URI handler is attached to the parent - * application window. - * - * @param handler - * the URI handler to add. - */ - public void addURIHandler(URIHandler handler) { - if (getParent() != null) { - // this is subwindow, attach to main level instead - // TODO hold internal list also and remove on detach - Window mainWindow = getParent(); - mainWindow.addURIHandler(handler); - } else { - if (uriHandlerList == null) { - uriHandlerList = new LinkedList<URIHandler>(); - } - synchronized (uriHandlerList) { - if (!uriHandlerList.contains(handler)) { - uriHandlerList.addLast(handler); - } - } - } - } - - /** - * <b>Application window only</b>. Removes the URI handler from this window. - * If this is a sub window the URI handler is removed from the parent - * application window. - * - * @param handler - * the URI handler to remove. - */ - public void removeURIHandler(URIHandler handler) { - if (getParent() != null) { - // this is subwindow - Window mainWindow = getParent(); - mainWindow.removeURIHandler(handler); - } else { - if (handler == null || uriHandlerList == null) { - return; - } - synchronized (uriHandlerList) { - uriHandlerList.remove(handler); - if (uriHandlerList.isEmpty()) { - uriHandlerList = null; - } - } - } - } - - /** - * <b>Application window only</b>. Handles an URI by passing the URI to all - * URI handlers defined using {@link #addURIHandler(URIHandler)}. All URI - * handlers are called for each URI but no more than one handler may return - * a {@link DownloadStream}. If more than one stream is returned a - * {@code RuntimeException} is thrown. - * - * @param context - * The URL of the application - * @param relativeUri - * The URI relative to {@code context} - * @return A {@code DownloadStream} that one of the URI handlers returned, - * null if no {@code DownloadStream} was returned. - */ - public DownloadStream handleURI(URL context, String relativeUri) { - - DownloadStream result = null; - if (uriHandlerList != null) { - Object[] handlers; - synchronized (uriHandlerList) { - handlers = uriHandlerList.toArray(); - } - for (int i = 0; i < handlers.length; i++) { - final DownloadStream ds = ((URIHandler) handlers[i]).handleURI( - context, relativeUri); - if (ds != null) { - if (result != null) { - throw new RuntimeException("handleURI for " + context - + " uri: '" + relativeUri - + "' returns ambigious result."); - } - result = ds; - } - } - } - return result; - } + // /** + // * <b>Application window only</b>. Adds a new parameter handler to this + // * window. If this is a sub window the parameter handler is attached to + // the + // * parent application window. + // * + // * @param handler + // * the parameter handler to add. + // */ + // public void addParameterHandler(ParameterHandler handler) { + // if (getParent() != null) { + // // this is subwindow + // // TODO hold internal list also and remove on detach + // Window mainWindow = getParent(); + // mainWindow.addParameterHandler(handler); + // } else { + // if (parameterHandlerList == null) { + // parameterHandlerList = new LinkedList<ParameterHandler>(); + // } + // synchronized (parameterHandlerList) { + // if (!parameterHandlerList.contains(handler)) { + // parameterHandlerList.addLast(handler); + // } + // } + // } + // + // } + + // /** + // * <b>Application window only</b>. Removes the parameter handler from this + // * window. If this is a sub window the parameter handler is removed from + // the + // * parent application window. + // * + // * @param handler + // * the parameter handler to remove. + // */ + // public void removeParameterHandler(ParameterHandler handler) { + // if (getParent() != null) { + // // this is subwindow + // Window mainWindow = getParent(); + // mainWindow.removeParameterHandler(handler); + // } else { + // if (handler == null || parameterHandlerList == null) { + // return; + // } + // synchronized (parameterHandlerList) { + // parameterHandlerList.remove(handler); + // if (parameterHandlerList.isEmpty()) { + // parameterHandlerList = null; + // } + // } + // } + // } + + // /** + // * <b>Application window only</b>. Handles parameters by passing the + // * parameters to all {@code ParameterHandler}s defined using + // * {@link #addParameterHandler(ParameterHandler)}. All + // * {@code ParameterHandler}s are called for each set of parameters. + // * + // * @param parameters + // * a map containing the parameter names and values + // * @see ParameterHandler#handleParameters(Map) + // */ + // public void handleParameters(Map<String, String[]> parameters) { + // if (parameterHandlerList != null) { + // Object[] handlers; + // synchronized (parameterHandlerList) { + // handlers = parameterHandlerList.toArray(); + // } + // for (int i = 0; i < handlers.length; i++) { + // ((ParameterHandler) handlers[i]).handleParameters(parameters); + // } + // } + // } /* ********************************************************************* */ - /** - * <b>Application window only</b>. Adds a new parameter handler to this - * window. If this is a sub window the parameter handler is attached to the - * parent application window. - * - * @param handler - * the parameter handler to add. - */ - public void addParameterHandler(ParameterHandler handler) { - if (getParent() != null) { - // this is subwindow - // TODO hold internal list also and remove on detach - Window mainWindow = getParent(); - mainWindow.addParameterHandler(handler); - } else { - if (parameterHandlerList == null) { - parameterHandlerList = new LinkedList<ParameterHandler>(); - } - synchronized (parameterHandlerList) { - if (!parameterHandlerList.contains(handler)) { - parameterHandlerList.addLast(handler); - } - } - } - - } - - /** - * <b>Application window only</b>. Removes the parameter handler from this - * window. If this is a sub window the parameter handler is removed from the - * parent application window. - * - * @param handler - * the parameter handler to remove. - */ - public void removeParameterHandler(ParameterHandler handler) { - if (getParent() != null) { - // this is subwindow - Window mainWindow = getParent(); - mainWindow.removeParameterHandler(handler); - } else { - if (handler == null || parameterHandlerList == null) { - return; - } - synchronized (parameterHandlerList) { - parameterHandlerList.remove(handler); - if (parameterHandlerList.isEmpty()) { - parameterHandlerList = null; - } - } - } - } - - /** - * <b>Application window only</b>. Handles parameters by passing the - * parameters to all {@code ParameterHandler}s defined using - * {@link #addParameterHandler(ParameterHandler)}. All - * {@code ParameterHandler}s are called for each set of parameters. - * - * @param parameters - * a map containing the parameter names and values - * @see ParameterHandler#handleParameters(Map) - */ - public void handleParameters(Map<String, String[]> parameters) { - if (parameterHandlerList != null) { - Object[] handlers; - synchronized (parameterHandlerList) { - handlers = parameterHandlerList.toArray(); - } - for (int i = 0; i < handlers.length; i++) { - ((ParameterHandler) handlers[i]).handleParameters(parameters); - } - } - } - - /* ********************************************************************* */ - - /** - * <b>Application window only</b>. Gets the theme for this window. - * <p> - * If the theme for this window is not explicitly set, the application theme - * name is returned. If the window is not attached to an application, the - * terminal default theme name is returned. If the theme name cannot be - * determined, null is returned - * </p> - * <p> - * Subwindows do not support themes and return the theme used by the parent - * window - * </p> - * - * @return the name of the theme used for the window - */ - public String getTheme() { - if (getParent() != null) { - return (getParent()).getTheme(); - } - if (theme != null) { - return theme; - } - if ((application != null) && (application.getTheme() != null)) { - return application.getTheme(); - } - if (terminal != null) { - return terminal.getDefaultTheme(); - } - return null; - } - - /** - * <b>Application window only</b>. Sets the name of the theme to use for - * this window. Changing the theme will cause the page to be reloaded. - * - * @param theme - * the name of the new theme for this window or null to use the - * application theme. - */ - public void setTheme(String theme) { - if (getParent() != null) { - throw new UnsupportedOperationException( - "Setting theme for sub-windows is not supported."); - } - this.theme = theme; - requestRepaint(); - } - /* * (non-Javadoc) * @@ -561,12 +402,8 @@ public class Window extends Panel implements URIHandler, ParameterHandler, throws PaintException { // Sets the window name - final String name = getName(); - target.addAttribute("name", name == null ? "" : name); - - // Sets the window theme - final String theme = getTheme(); - target.addAttribute("theme", theme == null ? "" : theme); + // final String name = getName(); + // target.addAttribute("name", name == null ? "" : name); if (modal) { target.addAttribute("modal", true); @@ -600,10 +437,10 @@ public class Window extends Panel implements URIHandler, ParameterHandler, } // Marks the main window - if (getApplication() != null - && this == getApplication().getMainWindow()) { - target.addAttribute("main", true); - } + // if (getApplication() != null + // && this == getApplication().getMainWindow()) { + // target.addAttribute("main", true); + // } if (getContent() != null) { if (getContent().getHeightUnits() == Sizeable.UNITS_PERCENTAGE) { @@ -615,88 +452,25 @@ public class Window extends Panel implements URIHandler, ParameterHandler, } // Open requested resource - synchronized (openList) { - if (!openList.isEmpty()) { - for (final Iterator<OpenResource> i = openList.iterator(); i - .hasNext();) { - (i.next()).paintContent(target); - } - openList.clear(); - } - } + // synchronized (openList) { + // if (!openList.isEmpty()) { + // for (final Iterator<OpenResource> i = openList.iterator(); i + // .hasNext();) { + // (i.next()).paintContent(target); + // } + // openList.clear(); + // } + // } // Contents of the window panel is painted super.paintContent(target); - // Add executable javascripts if needed - if (jsExecQueue != null) { - for (String script : jsExecQueue) { - target.startTag("execJS"); - target.addAttribute("script", script); - target.endTag("execJS"); - } - jsExecQueue = null; - } - // Window position target.addVariable(this, "positionx", getPositionX()); target.addVariable(this, "positiony", getPositionY()); // Window closing target.addVariable(this, "close", false); - - if (getParent() == null) { - // Paint subwindows - for (final Iterator<Window> i = subwindows.iterator(); i.hasNext();) { - final Window w = i.next(); - w.paint(target); - } - } else { - // mark subwindows - target.addAttribute("sub", true); - } - - // Paint notifications - if (notifications != null) { - target.startTag("notifications"); - for (final Iterator<Notification> it = notifications.iterator(); it - .hasNext();) { - final Notification n = it.next(); - target.startTag("notification"); - if (n.getCaption() != null) { - target.addAttribute("caption", n.getCaption()); - } - if (n.getMessage() != null) { - target.addAttribute("message", n.getMessage()); - } - if (n.getIcon() != null) { - target.addAttribute("icon", n.getIcon()); - } - if (!n.isHtmlContentAllowed()) { - target.addAttribute( - VView.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED, true); - } - target.addAttribute("position", n.getPosition()); - target.addAttribute("delay", n.getDelayMsec()); - if (n.getStyleName() != null) { - target.addAttribute("style", n.getStyleName()); - } - target.endTag("notification"); - } - target.endTag("notifications"); - notifications = null; - } - - if (pendingFocus != null) { - // ensure focused component is still attached to this main window - if (pendingFocus.getWindow() == this - || (pendingFocus.getWindow() != null && pendingFocus - .getWindow().getParent() == this)) { - target.addAttribute("focused", pendingFocus); - } - pendingFocus = null; - } - } /* ********************************************************************* */ @@ -713,7 +487,7 @@ public class Window extends Panel implements URIHandler, ParameterHandler, */ public void scrollIntoView(Component component) throws IllegalArgumentException { - if (component.getWindow() != this) { + if (component.getRoot() != this) { throw new IllegalArgumentException( "The component where to scroll must be inside this window."); } @@ -721,344 +495,307 @@ public class Window extends Panel implements URIHandler, ParameterHandler, requestRepaint(); } - /** - * Opens the given resource in this window. The contents of this Window is - * replaced by the {@code Resource}. - * - * @param resource - * the resource to show in this window - */ - public void open(Resource resource) { - synchronized (openList) { - if (!openList.contains(resource)) { - openList.add(new OpenResource(resource, null, -1, -1, - BORDER_DEFAULT)); - } - } - requestRepaint(); - } + // /** + // * Opens the given resource in this window. The contents of this Window is + // * replaced by the {@code Resource}. + // * + // * @param resource + // * the resource to show in this window + // */ + // public void open(Resource resource) { + // synchronized (openList) { + // if (!openList.contains(resource)) { + // openList.add(new OpenResource(resource, null, -1, -1, + // BORDER_DEFAULT)); + // } + // } + // requestRepaint(); + // } /* ********************************************************************* */ - /** - * Opens the given resource in a window with the given name. - * <p> - * The supplied {@code windowName} is used as the target name in a - * window.open call in the client. This means that special values such as - * "_blank", "_self", "_top", "_parent" have special meaning. An empty or - * <code>null</code> window name is also a special case. - * </p> - * <p> - * "", null and "_self" as {@code windowName} all causes the resource to be - * opened in the current window, replacing any old contents. For - * downloadable content you should avoid "_self" as "_self" causes the - * client to skip rendering of any other changes as it considers them - * irrelevant (the page will be replaced by the resource). This can speed up - * the opening of a resource, but it might also put the client side into an - * inconsistent state if the window content is not completely replaced e.g., - * if the resource is downloaded instead of displayed in the browser. - * </p> - * <p> - * "_blank" as {@code windowName} causes the resource to always be opened in - * a new window or tab (depends on the browser and browser settings). - * </p> - * <p> - * "_top" and "_parent" as {@code windowName} works as specified by the HTML - * standard. - * </p> - * <p> - * Any other {@code windowName} will open the resource in a window with that - * name, either by opening a new window/tab in the browser or by replacing - * the contents of an existing window with that name. - * </p> - * - * @param resource - * the resource. - * @param windowName - * the name of the window. - */ - public void open(Resource resource, String windowName) { - synchronized (openList) { - if (!openList.contains(resource)) { - openList.add(new OpenResource(resource, windowName, -1, -1, - BORDER_DEFAULT)); - } - } - requestRepaint(); - } - - /** - * Opens the given resource in a window with the given size, border and - * name. For more information on the meaning of {@code windowName}, see - * {@link #open(Resource, String)}. - * - * @param resource - * the resource. - * @param windowName - * the name of the window. - * @param width - * the width of the window in pixels - * @param height - * the height of the window in pixels - * @param border - * the border style of the window. See {@link #BORDER_NONE - * Window.BORDER_* constants} - */ - public void open(Resource resource, String windowName, int width, - int height, int border) { - synchronized (openList) { - if (!openList.contains(resource)) { - openList.add(new OpenResource(resource, windowName, width, - height, border)); - } - } - requestRepaint(); - } + // /** + // * Opens the given resource in a window with the given name. + // * <p> + // * The supplied {@code windowName} is used as the target name in a + // * window.open call in the client. This means that special values such as + // * "_blank", "_self", "_top", "_parent" have special meaning. An empty or + // * <code>null</code> window name is also a special case. + // * </p> + // * <p> + // * "", null and "_self" as {@code windowName} all causes the resource to + // be + // * opened in the current window, replacing any old contents. For + // * downloadable content you should avoid "_self" as "_self" causes the + // * client to skip rendering of any other changes as it considers them + // * irrelevant (the page will be replaced by the resource). This can speed + // up + // * the opening of a resource, but it might also put the client side into + // an + // * inconsistent state if the window content is not completely replaced + // e.g., + // * if the resource is downloaded instead of displayed in the browser. + // * </p> + // * <p> + // * "_blank" as {@code windowName} causes the resource to always be opened + // in + // * a new window or tab (depends on the browser and browser settings). + // * </p> + // * <p> + // * "_top" and "_parent" as {@code windowName} works as specified by the + // HTML + // * standard. + // * </p> + // * <p> + // * Any other {@code windowName} will open the resource in a window with + // that + // * name, either by opening a new window/tab in the browser or by replacing + // * the contents of an existing window with that name. + // * </p> + // * + // * @param resource + // * the resource. + // * @param windowName + // * the name of the window. + // */ + // public void open(Resource resource, String windowName) { + // synchronized (openList) { + // if (!openList.contains(resource)) { + // openList.add(new OpenResource(resource, windowName, -1, -1, + // BORDER_DEFAULT)); + // } + // } + // requestRepaint(); + // } + + // /** + // * Opens the given resource in a window with the given size, border and + // * name. For more information on the meaning of {@code windowName}, see + // * {@link #open(Resource, String)}. + // * + // * @param resource + // * the resource. + // * @param windowName + // * the name of the window. + // * @param width + // * the width of the window in pixels + // * @param height + // * the height of the window in pixels + // * @param border + // * the border style of the window. See {@link #BORDER_NONE + // * Window.BORDER_* constants} + // */ + // public void open(Resource resource, String windowName, int width, + // int height, int border) { + // synchronized (openList) { + // if (!openList.contains(resource)) { + // openList.add(new OpenResource(resource, windowName, width, + // height, border)); + // } + // } + // requestRepaint(); + // } /* ********************************************************************* */ - /** - * Gets the full URL of the window. The returned URL is window specific and - * can be used to directly refer to the window. - * <p> - * Note! This method can not be used for portlets. - * </p> - * - * @return the URL of the window or null if the window is not attached to an - * application - */ - public URL getURL() { - - if (application == null) { - return null; - } - - try { - return new URL(application.getURL(), getName() + "/"); - } catch (final MalformedURLException e) { - throw new RuntimeException( - "Internal problem getting window URL, please report"); - } - } - - /** - * <b>Application window only</b>. Gets the unique name of the window. The - * name of the window is used to uniquely identify it. - * <p> - * The name also determines the URL that can be used for direct access to a - * window. All windows can be accessed through - * {@code http://host:port/app/win} where {@code http://host:port/app} is - * the application URL (as returned by {@link Application#getURL()} and - * {@code win} is the window name. - * </p> - * <p> - * Note! Portlets do not support direct window access through URLs. - * </p> - * - * @return the Name of the Window. - */ - public String getName() { - return name; - } - - /** - * Returns the border style of the window. - * - * @see #setBorder(int) - * @return the border style for the window - */ - public int getBorder() { - return border; - } - - /** - * Sets the border style for this window. Valid values are - * {@link Window#BORDER_NONE}, {@link Window#BORDER_MINIMAL}, - * {@link Window#BORDER_DEFAULT}. - * <p> - * <b>Note!</b> Setting this seems to currently have no effect whatsoever on - * the window. - * </p> - * - * @param border - * the border style to set - */ - public void setBorder(int border) { - this.border = border; - } - - /** - * Sets the application this window is attached to. - * - * <p> - * This method is called by the framework and should not be called directly - * from application code. {@link com.vaadin.Application#addWindow(Window)} - * should be used to add the window to an application and - * {@link com.vaadin.Application#removeWindow(Window)} to remove the window - * from the application. - * </p> - * <p> - * This method invokes {@link Component#attach()} and - * {@link Component#detach()} methods when necessary. - * <p> - * - * @param application - * the application the window is attached to - */ - public void setApplication(Application application) { - - // If the application is not changed, dont do nothing - if (application == this.application) { - return; - } - - // Sends detach event if the window is connected to application - if (this.application != null) { - detach(); - } - - // Connects to new parent - this.application = application; - - // Sends the attach event if connected to a window - if (application != null) { - attach(); - } - } - - /** - * <b>Application window only</b>. Sets the unique name of the window. The - * name of the window is used to uniquely identify it inside the - * application. - * <p> - * The name also determines the URL that can be used for direct access to a - * window. All windows can be accessed through - * {@code http://host:port/app/win} where {@code http://host:port/app} is - * the application URL (as returned by {@link Application#getURL()} and - * {@code win} is the window name. - * </p> - * <p> - * This method can only be called before the window is added to an - * application. - * </p> - * <p> - * Note! Portlets do not support direct window access through URLs. - * </p> - * - * @param name - * the new name for the window or null if the application should - * automatically assign a name to it - * @throws IllegalStateException - * if the window is attached to an application - */ - public void setName(String name) throws IllegalStateException { - - // The name can not be changed in application - if (getApplication() != null) { - throw new IllegalStateException( - "Window name can not be changed while " - + "the window is in application"); - } - - this.name = name; - } - - /** - * Sets the user terminal. Used by the terminal adapter, should never be - * called from application code. - * - * @param type - * the terminal to set. - */ - public void setTerminal(Terminal type) { - terminal = type; - } - - /** - * Private class for storing properties related to opening resources. - */ - private class OpenResource implements Serializable { - - /** - * The resource to open - */ - private final Resource resource; - - /** - * The name of the target window - */ - private final String name; - - /** - * The width of the target window - */ - private final int width; - - /** - * The height of the target window - */ - private final int height; - - /** - * The border style of the target window - */ - private final int border; - - /** - * Creates a new open resource. - * - * @param resource - * The resource to open - * @param name - * The name of the target window - * @param width - * The width of the target window - * @param height - * The height of the target window - * @param border - * The border style of the target window - */ - private OpenResource(Resource resource, String name, int width, - int height, int border) { - this.resource = resource; - this.name = name; - this.width = width; - this.height = height; - this.border = border; - } - - /** - * Paints the open request. Should be painted inside the window. - * - * @param target - * the paint target - * @throws PaintException - * if the paint operation fails - */ - private void paintContent(PaintTarget target) throws PaintException { - target.startTag("open"); - target.addAttribute("src", resource); - if (name != null && name.length() > 0) { - target.addAttribute("name", name); - } - if (width >= 0) { - target.addAttribute("width", width); - } - if (height >= 0) { - target.addAttribute("height", height); - } - switch (border) { - case Window.BORDER_MINIMAL: - target.addAttribute("border", "minimal"); - break; - case Window.BORDER_NONE: - target.addAttribute("border", "none"); - break; - } - - target.endTag("open"); - } - } + // /** + // * Gets the full URL of the window. The returned URL is window specific + // and + // * can be used to directly refer to the window. + // * <p> + // * Note! This method can not be used for portlets. + // * </p> + // * + // * @return the URL of the window or null if the window is not attached to + // an + // * application + // */ + // public URL getURL() { + // + // if (application == null) { + // return null; + // } + // + // try { + // return new URL(application.getURL(), getName() + "/"); + // } catch (final MalformedURLException e) { + // throw new RuntimeException( + // "Internal problem getting window URL, please report"); + // } + // } + + // /** + // * <b>Application window only</b>. Gets the unique name of the window. The + // * name of the window is used to uniquely identify it. + // * <p> + // * The name also determines the URL that can be used for direct access to + // a + // * window. All windows can be accessed through + // * {@code http://host:port/app/win} where {@code http://host:port/app} is + // * the application URL (as returned by {@link Application#getURL()} and + // * {@code win} is the window name. + // * </p> + // * <p> + // * Note! Portlets do not support direct window access through URLs. + // * </p> + // * + // * @return the Name of the Window. + // */ + // public String getName() { + // return name; + // } + + // /** + // * Returns the border style of the window. + // * + // * @see #setBorder(int) + // * @return the border style for the window + // */ + // public int getBorder() { + // return border; + // } + + // /** + // * Sets the border style for this window. Valid values are + // * {@link Window#BORDER_NONE}, {@link Window#BORDER_MINIMAL}, + // * {@link Window#BORDER_DEFAULT}. + // * <p> + // * <b>Note!</b> Setting this seems to currently have no effect whatsoever + // on + // * the window. + // * </p> + // * + // * @param border + // * the border style to set + // */ + // public void setBorder(int border) { + // this.border = border; + // } + + // /** + // * <b>Application window only</b>. Sets the unique name of the window. The + // * name of the window is used to uniquely identify it inside the + // * application. + // * <p> + // * The name also determines the URL that can be used for direct access to + // a + // * window. All windows can be accessed through + // * {@code http://host:port/app/win} where {@code http://host:port/app} is + // * the application URL (as returned by {@link Application#getURL()} and + // * {@code win} is the window name. + // * </p> + // * <p> + // * This method can only be called before the window is added to an + // * application. + // * </p> + // * <p> + // * Note! Portlets do not support direct window access through URLs. + // * </p> + // * + // * @param name + // * the new name for the window or null if the application should + // * automatically assign a name to it + // * @throws IllegalStateException + // * if the window is attached to an application + // */ + // public void setName(String name) throws IllegalStateException { + // + // // The name can not be changed in application + // if (getApplication() != null) { + // throw new IllegalStateException( + // "Window name can not be changed while " + // + "the window is in application"); + // } + // + // this.name = name; + // } + + // /** + // * Private class for storing properties related to opening resources. + // */ + // private class OpenResource implements Serializable { + // + // /** + // * The resource to open + // */ + // private final Resource resource; + // + // /** + // * The name of the target window + // */ + // private final String name; + // + // /** + // * The width of the target window + // */ + // private final int width; + // + // /** + // * The height of the target window + // */ + // private final int height; + // + // /** + // * The border style of the target window + // */ + // private final int border; + // + // /** + // * Creates a new open resource. + // * + // * @param resource + // * The resource to open + // * @param name + // * The name of the target window + // * @param width + // * The width of the target window + // * @param height + // * The height of the target window + // * @param border + // * The border style of the target window + // */ + // private OpenResource(Resource resource, String name, int width, + // int height, int border) { + // this.resource = resource; + // this.name = name; + // this.width = width; + // this.height = height; + // this.border = border; + // } + // + // /** + // * Paints the open request. Should be painted inside the window. + // * + // * @param target + // * the paint target + // * @throws PaintException + // * if the paint operation fails + // */ + // private void paintContent(PaintTarget target) throws PaintException { + // target.startTag("open"); + // target.addAttribute("src", resource); + // if (name != null && name.length() > 0) { + // target.addAttribute("name", name); + // } + // if (width >= 0) { + // target.addAttribute("width", width); + // } + // if (height >= 0) { + // target.addAttribute("height", height); + // } + // switch (border) { + // case Window.BORDER_MINIMAL: + // target.addAttribute("border", "minimal"); + // break; + // case Window.BORDER_NONE: + // target.addAttribute("border", "none"); + // break; + // } + // + // target.endTag("open"); + // } + // } + // /* * (non-Javadoc) @@ -1068,6 +805,7 @@ public class Window extends Panel implements URIHandler, ParameterHandler, @Override public void changeVariables(Object source, Map<String, Object> variables) { + // TODO Are these for top level windows or sub windows? boolean sizeHasChanged = false; // size is handled in super class, but resize events only in windows -> // so detect if size change occurs before super.changeVariables() @@ -1138,17 +876,11 @@ public class Window extends Panel implements URIHandler, ParameterHandler, * </p> */ protected void close() { - Window parent = getParent(); - if (parent == null) { - fireClose(); - } else { - - // focus is restored to the parent window - parent.focus(); - - // subwindow is removed from parent - parent.removeWindow(this); - } + Root root = getRoot(); + // focus is restored to the parent window + root.focus(); + // subwindow is removed from the root + root.removeWindow(this); } /** @@ -1411,128 +1143,45 @@ public class Window extends Panel implements URIHandler, ParameterHandler, fireEvent(new ResizeEvent(this)); } - private void attachWindow(Window w) { - subwindows.add(w); - w.setParent(this); - requestRepaint(); - } - /** - * Adds a window inside another window. - * - * <p> - * Adding windows inside another window creates "subwindows". These windows - * should not be added to application directly and are not accessible - * directly with any url. Addding windows implicitly sets their parents. - * </p> - * - * <p> - * Only one level of subwindows are supported. Thus you can add windows - * inside such windows whose parent is <code>null</code>. - * </p> - * - * @param window - * @throws IllegalArgumentException - * if a window is added inside non-application level window. - * @throws NullPointerException - * if the given <code>Window</code> is <code>null</code>. - */ - public void addWindow(Window window) throws IllegalArgumentException, - NullPointerException { - - if (window == null) { - throw new NullPointerException("Argument must not be null"); - } - - if (window.getApplication() != null) { - throw new IllegalArgumentException( - "Window was already added to application" - + " - it can not be added to another window also."); - } else if (getParent() != null) { - throw new IllegalArgumentException( - "You can only add windows inside application-level windows."); - } else if (window.subwindows.size() > 0) { - throw new IllegalArgumentException( - "Only one level of subwindows are supported."); - } - - attachWindow(window); - } - - /** - * Remove the given subwindow from this window. - * - * Since Vaadin 6.5, {@link CloseListener}s are called also when explicitly - * removing a window by calling this method. - * - * Since Vaadin 6.5, returns a boolean indicating if the window was removed - * or not. - * - * @param window - * Window to be removed. - * @return true if the subwindow was removed, false otherwise - */ - public boolean removeWindow(Window window) { - if (!subwindows.remove(window)) { - // Window window is not a subwindow of this window. - return false; - } - window.setParent(null); - window.fireClose(); - requestRepaint(); - - return true; - } - - private Integer bringToFront = null; - - /* - * This sequesnce is used to keep the right order of windows if multiple - * windows are brought to front in a single changeset. Incremented and saved - * by childwindows. If sequence is not used, the order is quite random - * (depends on the order getting to dirty list. e.g. which window got + * Used to keep the right order of windows if multiple windows are brought + * to front in a single changeset. If this is not used, the order is quite + * random (depends on the order getting to dirty list. e.g. which window got * variable changes). */ - private int bringToFrontSequence = 0; + private Integer bringToFront = null; /** - * If there are currently several sub windows visible, calling this method - * makes this window topmost. + * If there are currently several windows visible, calling this method makes + * this window topmost. * <p> - * This method can only be called if this window is a sub window and - * connected a top level window. Else an illegal state exception is thrown. - * Also if there are modal windows and this window is not modal, and illegal - * state exception is thrown. + * This method can only be called if this window connected a root. Else an + * illegal state exception is thrown. Also if there are modal windows and + * this window is not modal, and illegal state exception is thrown. * <p> - * <strong> Note, this API works on sub windows only. Browsers can't reorder - * OS windows.</strong> */ public void bringToFront() { - Window parent = getParent(); - if (parent == null) { + Root root = getRoot(); + if (root == null) { throw new IllegalStateException( "Window must be attached to parent before calling bringToFront method."); } - for (Window w : parent.getChildWindows()) { - if (w.isModal() && !isModal()) { + int maxBringToFront = -1; + for (Window w : root.getWindows()) { + if (!isModal() && w.isModal()) { throw new IllegalStateException( - "There are modal windows currently visible, non-modal window cannot be brought to front."); + "The root contains modal windows, non-modal window cannot be brought to front."); + } + if (w.bringToFront != null) { + maxBringToFront = Math.max(maxBringToFront, + w.bringToFront.intValue()); } } - bringToFront = getParent().bringToFrontSequence++; + bringToFront = Integer.valueOf(maxBringToFront + 1); requestRepaint(); } /** - * Get the set of all child windows. - * - * @return Set of child windows. - */ - public Set<Window> getChildWindows() { - return Collections.unmodifiableSet(subwindows); - } - - /** * Sets sub-window modal, so that widgets behind it cannot be accessed. * <b>Note:</b> affects sub-windows only. * @@ -1607,162 +1256,6 @@ public class Window extends Panel implements URIHandler, ParameterHandler, } /** - * Shows a notification message on the middle of the window. The message - * automatically disappears ("humanized message"). - * - * Care should be taken to to avoid XSS vulnerabilities as the caption is - * rendered as html. - * - * @see #showNotification(com.vaadin.ui.Window.Notification) - * @see Notification - * - * @param caption - * The message - */ - public void showNotification(String caption) { - addNotification(new Notification(caption)); - } - - /** - * Shows a notification message the window. The position and behavior of the - * message depends on the type, which is one of the basic types defined in - * {@link Notification}, for instance Notification.TYPE_WARNING_MESSAGE. - * - * Care should be taken to to avoid XSS vulnerabilities as the caption is - * rendered as html. - * - * @see #showNotification(com.vaadin.ui.Window.Notification) - * @see Notification - * - * @param caption - * The message - * @param type - * The message type - */ - public void showNotification(String caption, int type) { - addNotification(new Notification(caption, type)); - } - - /** - * Shows a notification consisting of a bigger caption and a smaller - * description on the middle of the window. The message automatically - * disappears ("humanized message"). - * - * Care should be taken to to avoid XSS vulnerabilities as the caption and - * description are rendered as html. - * - * @see #showNotification(com.vaadin.ui.Window.Notification) - * @see Notification - * - * @param caption - * The caption of the message - * @param description - * The message description - * - */ - public void showNotification(String caption, String description) { - addNotification(new Notification(caption, description)); - } - - /** - * Shows a notification consisting of a bigger caption and a smaller - * description. The position and behavior of the message depends on the - * type, which is one of the basic types defined in {@link Notification}, - * for instance Notification.TYPE_WARNING_MESSAGE. - * - * Care should be taken to to avoid XSS vulnerabilities as the caption and - * description are rendered as html. - * - * @see #showNotification(com.vaadin.ui.Window.Notification) - * @see Notification - * - * @param caption - * The caption of the message - * @param description - * The message description - * @param type - * The message type - */ - public void showNotification(String caption, String description, int type) { - addNotification(new Notification(caption, description, type)); - } - - /** - * Shows a notification consisting of a bigger caption and a smaller - * description. The position and behavior of the message depends on the - * type, which is one of the basic types defined in {@link Notification}, - * for instance Notification.TYPE_WARNING_MESSAGE. - * - * Care should be taken to avoid XSS vulnerabilities if html content is - * allowed. - * - * @see #showNotification(com.vaadin.ui.Window.Notification) - * @see Notification - * - * @param caption - * The message caption - * @param description - * The message description - * @param type - * The type of message - * @param htmlContentAllowed - * Whether html in the caption and description should be - * displayed as html or as plain text - */ - public void showNotification(String caption, String description, int type, - boolean htmlContentAllowed) { - addNotification(new Notification(caption, description, type, - htmlContentAllowed)); - } - - /** - * Shows a notification message. - * - * @see Notification - * @see #showNotification(String) - * @see #showNotification(String, int) - * @see #showNotification(String, String) - * @see #showNotification(String, String, int) - * - * @param notification - * The notification message to show - */ - public void showNotification(Notification notification) { - addNotification(notification); - } - - private void addNotification(Notification notification) { - if (notifications == null) { - notifications = new LinkedList<Notification>(); - } - notifications.add(notification); - requestRepaint(); - } - - /** - * This method is used by Component.Focusable objects to request focus to - * themselves. Focus renders must be handled at window level (instead of - * Component.Focusable) due we want the last focused component to be focused - * in client too. Not the one that is rendered last (the case we'd get if - * implemented in Focusable only). - * - * To focus component from Vaadin application, use Focusable.focus(). See - * {@link Focusable}. - * - * @param focusable - * to be focused on next paint - */ - void setFocusedComponent(Focusable focusable) { - if (getParent() != null) { - // focus is handled by main windows - (getParent()).setFocusedComponent(focusable); - } else { - pendingFocus = focusable; - requestRepaint(); - } - } - - /** * A notification message, used to display temporary messages to the user - * for example "Document saved", or "Save failed". * <p> @@ -1957,24 +1450,6 @@ public class Window extends Panel implements URIHandler, ParameterHandler, } /** - * @deprecated Use {@link #getDescription()} instead. - * @return - */ - @Deprecated - public String getMessage() { - return description; - } - - /** - * @deprecated Use {@link #setDescription(String)} instead. - * @param description - */ - @Deprecated - public void setMessage(String description) { - this.description = description; - } - - /** * Gets the description part of the notification message. * * @return The message description. @@ -2098,42 +1573,6 @@ public class Window extends Panel implements URIHandler, ParameterHandler, } /** - * Executes JavaScript in this window. - * - * <p> - * This method allows one to inject javascript from the server to client. A - * client implementation is not required to implement this functionality, - * but currently all web-based clients do implement this. - * </p> - * - * <p> - * Executing javascript this way often leads to cross-browser compatibility - * issues and regressions that are hard to resolve. Use of this method - * should be avoided and instead it is recommended to create new widgets - * with GWT. For more info on creating own, reusable client-side widgets in - * Java, read the corresponding chapter in Book of Vaadin. - * </p> - * - * @param script - * JavaScript snippet that will be executed. - */ - public void executeJavaScript(String script) { - - if (getParent() != null) { - throw new UnsupportedOperationException( - "Only application level windows can execute javascript."); - } - - if (jsExecQueue == null) { - jsExecQueue = new ArrayList<String>(); - } - - jsExecQueue.add(script); - - requestRepaint(); - } - - /** * Returns the closable status of the sub window. If a sub window is * closable it typically shows an X in the upper right corner. Clicking on * the X sends a close event to the server. Setting closable to false will @@ -2342,16 +1781,13 @@ public class Window extends Panel implements URIHandler, ParameterHandler, */ @Override public void focus() { - if (getParent() != null) { - /* - * When focusing a sub-window it basically means it should be - * brought to the front. Instead of just moving the keyboard focus - * we focus the window and bring it top-most. - */ - bringToFront(); - } else { - super.focus(); - } + /* + * When focusing a sub-window it basically means it should be brought to + * the front. Instead of just moving the keyboard focus we focus the + * window and bring it top-most. + */ + super.focus(); + bringToFront(); } } |