Browse Source

Split Window to Root and Window

Everything related to top level windows disabled in Window, introduced
basic Root for top level windows and disabled everything that isn't
required to get a simple hard coded example to run.
tags/7.0.0.alpha1
Leif Åstrand 12 years ago
parent
commit
be1d3c3365

+ 6
- 6
WebContent/WEB-INF/web.xml View File

@@ -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>

+ 430
- 413
src/com/vaadin/Application.java View File

@@ -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();
}

+ 22
- 0
src/com/vaadin/RootTestApplication.java View File

@@ -0,0 +1,22 @@
package com.vaadin;

import com.vaadin.ui.DefaultRoot;
import com.vaadin.ui.Label;
import com.vaadin.ui.Root;

public class RootTestApplication extends Application {
private final Root root = new DefaultRoot(this, new Label(
"Roots, bloody roots"));

@Override
public void init() {
// TODO Auto-generated method stub

}

@Override
public Root getRoot() {
return root;
}

}

+ 1
- 1
src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java View File

@@ -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;
}
}

+ 1622
- 1622
src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
File diff suppressed because it is too large
View File


+ 99
- 96
src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java View File

@@ -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);
}

/**

+ 171
- 168
src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java View File

@@ -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);

}

@@ -1386,7 +1385,7 @@ public abstract class AbstractCommunicationManager implements
&& ((Window) owner).getParent() == null) {
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 +1826,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 +2030,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 +2049,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()) {
@@ -2240,32 +2241,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(

+ 247
- 247
src/com/vaadin/terminal/gwt/server/ApplicationPortlet.java View File

@@ -1,250 +1,250 @@
/*
@ITMillApache2LicenseForJavaFiles@
*/
package com.vaadin.terminal.gwt.server;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortalContext;
import javax.portlet.Portlet;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import com.liferay.portal.kernel.util.PropsUtil;
import com.vaadin.Application;
/**
* Portlet main class for Portlet 1.0 (JSR-168) portlets which consist of a
* portlet and a servlet. For Portlet 2.0 (JSR-286, no servlet required), use
* {@link ApplicationPortlet2} instead.
*/
@SuppressWarnings("serial")
public class ApplicationPortlet implements Portlet, Serializable {
// portlet configuration parameters
private static final String PORTLET_PARAMETER_APPLICATION = "application";
private static final String PORTLET_PARAMETER_STYLE = "style";
private static final String PORTLET_PARAMETER_WIDGETSET = "widgetset";
// The application to show
protected String app = null;
// some applications might require forced height (and, more seldom, width)
protected String style = null; // e.g "height:500px;"
// force the portlet to use this widgetset - portlet level setting
protected String portletWidgetset = null;
public void destroy() {
}
public void init(PortletConfig config) throws PortletException {
app = config.getInitParameter(PORTLET_PARAMETER_APPLICATION);
if (app == null) {
throw new PortletException(
"No porlet application url defined in portlet.xml. Define the '"
+ PORTLET_PARAMETER_APPLICATION
+ "' init parameter to be the servlet deployment path.");
}
style = config.getInitParameter(PORTLET_PARAMETER_STYLE);
// enable forcing the selection of the widgetset in portlet
// configuration for a single portlet (backwards compatibility)
portletWidgetset = config.getInitParameter(PORTLET_PARAMETER_WIDGETSET);
}
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, IOException {
PortletApplicationContext.dispatchRequest(this, request, response);
}
public void render(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
// display the Vaadin application
writeAjaxWindow(request, response);
}
protected void writeAjaxWindow(RenderRequest request,
RenderResponse response) throws IOException {
response.setContentType("text/html");
if (app != null) {
PortletSession sess = request.getPortletSession();
PortletApplicationContext ctx = PortletApplicationContext
.getApplicationContext(sess);
PortletRequestDispatcher dispatcher = sess.getPortletContext()
.getRequestDispatcher("/" + app);
try {
// portal-wide settings
PortalContext portalCtx = request.getPortalContext();
boolean isLifeRay = portalCtx.getPortalInfo().toLowerCase()
.contains("liferay");
request.setAttribute(ApplicationServlet.REQUEST_FRAGMENT,
"true");
// fixed base theme to use - all portal pages with Vaadin
// applications will load this exactly once
String portalTheme = getPortalProperty(
Constants.PORTAL_PARAMETER_VAADIN_THEME, portalCtx);
String portalWidgetset = getPortalProperty(
Constants.PORTAL_PARAMETER_VAADIN_WIDGETSET, portalCtx);
// location of the widgetset(s) and default theme (to which
// /VAADIN/widgetsets/...
// is appended)
String portalResourcePath = getPortalProperty(
Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH,
portalCtx);
if (portalResourcePath != null) {
// if portalResourcePath is defined, set it as a request
// parameter which will override the default location in
// servlet
request.setAttribute(
ApplicationServlet.REQUEST_VAADIN_STATIC_FILE_PATH,
portalResourcePath);
}
// - if the user has specified a widgetset for this portlet, use
// it from the portlet (not fully supported)
// - otherwise, if specified, use the portal-wide widgetset
// and widgetset path settings (recommended)
// - finally, default to use the default widgetset if nothing
// else is found
if (portletWidgetset != null) {
request.setAttribute(ApplicationServlet.REQUEST_WIDGETSET,
portletWidgetset);
}
if (portalWidgetset != null) {
request.setAttribute(
ApplicationServlet.REQUEST_SHARED_WIDGETSET,
portalWidgetset);
}
if (style != null) {
request.setAttribute(ApplicationServlet.REQUEST_APPSTYLE,
style);
}
// portalTheme is only used if the shared portal resource
// directory is defined
if (portalTheme != null && portalResourcePath != null) {
request.setAttribute(
ApplicationServlet.REQUEST_DEFAULT_THEME,
portalTheme);
String defaultThemeUri = null;
defaultThemeUri = portalResourcePath + "/"
+ AbstractApplicationServlet.THEME_DIRECTORY_PATH
+ portalTheme;
/*
* Make sure portal default Vaadin theme is included in DOM.
* Vaadin portlet themes do not "inherit" base theme, so we
* need to force loading of the common base theme.
*/
OutputStream out = response.getPortletOutputStream();
// Using portal-wide theme
String loadDefaultTheme = ("<script type=\"text/javascript\">\n"
+ "if(!vaadin) { var vaadin = {} } \n"
+ "if(!vaadin.themesLoaded) { vaadin.themesLoaded = {} } \n"
+ "if(!vaadin.themesLoaded['"
+ portalTheme
+ "']) {\n"
+ "var stylesheet = document.createElement('link');\n"
+ "stylesheet.setAttribute('rel', 'stylesheet');\n"
+ "stylesheet.setAttribute('type', 'text/css');\n"
+ "stylesheet.setAttribute('href', '"
+ defaultThemeUri
+ "/styles.css');\n"
+ "document.getElementsByTagName('head')[0].appendChild(stylesheet);\n"
+ "vaadin.themesLoaded['"
+ portalTheme
+ "'] = true;\n}\n" + "</script>\n");
out.write(loadDefaultTheme.getBytes());
}
dispatcher.include(request, response);
if (isLifeRay) {
/*
* Temporary support to heartbeat Liferay session when using
* Vaadin based portlet. We hit an extra xhr to liferay
* servlet to extend the session lifetime after each Vaadin
* request. This hack can be removed when supporting portlet
* 2.0 and resourceRequests.
*
* TODO make this configurable, this is not necessary with
* some custom session configurations.
*/
OutputStream out = response.getPortletOutputStream();
String lifeRaySessionHearbeatHack = ("<script type=\"text/javascript\">"
+ "if(!vaadin.postRequestHooks) {"
+ " vaadin.postRequestHooks = {};"
+ "}"
+ "vaadin.postRequestHooks.liferaySessionHeartBeat = function() {"
+ " if (Liferay && Liferay.Session && Liferay.Session.setCookie) {"
+ " Liferay.Session.setCookie();"
+ " }"
+ "};" + "</script>");
out.write(lifeRaySessionHearbeatHack.getBytes());
}
} catch (PortletException e) {
PrintWriter out = response.getWriter();
out.print("<h1>Servlet include failed!</h1>");
Logger.getLogger(AbstractApplicationPortlet.class.getName())
.log(Level.WARNING, "Servlet include failed", e);
ctx.setPortletApplication(this, null);
return;
}
Application app = (Application) request
.getAttribute(Application.class.getName());
ctx.setPortletApplication(this, app);
ctx.firePortletRenderRequest(this, request, response);
}
}
private String getPortalProperty(String name, PortalContext context) {
boolean isLifeRay = context.getPortalInfo().toLowerCase()
.contains("liferay");
// TODO test on non-LifeRay platforms
String value;
if (isLifeRay) {
value = getLifeRayPortalProperty(name);
} else {
value = context.getProperty(name);
}
return value;
}
private String getLifeRayPortalProperty(String name) {
String value;
try {
value = PropsUtil.get(name);
} catch (Exception e) {
value = null;
}
return value;
}
}
//package com.vaadin.terminal.gwt.server;
//
//import java.io.IOException;
//import java.io.OutputStream;
//import java.io.PrintWriter;
//import java.io.Serializable;
//import java.util.logging.Level;
//import java.util.logging.Logger;
//
//import javax.portlet.ActionRequest;
//import javax.portlet.ActionResponse;
//import javax.portlet.PortalContext;
//import javax.portlet.Portlet;
//import javax.portlet.PortletConfig;
//import javax.portlet.PortletException;
//import javax.portlet.PortletRequestDispatcher;
//import javax.portlet.PortletSession;
//import javax.portlet.RenderRequest;
//import javax.portlet.RenderResponse;
//
//import com.liferay.portal.kernel.util.PropsUtil;
//import com.vaadin.Application;
//
///**
// * Portlet main class for Portlet 1.0 (JSR-168) portlets which consist of a
// * portlet and a servlet. For Portlet 2.0 (JSR-286, no servlet required), use
// * {@link ApplicationPortlet2} instead.
// */
//@SuppressWarnings("serial")
//public class ApplicationPortlet implements Portlet, Serializable {
// // portlet configuration parameters
// private static final String PORTLET_PARAMETER_APPLICATION = "application";
// private static final String PORTLET_PARAMETER_STYLE = "style";
// private static final String PORTLET_PARAMETER_WIDGETSET = "widgetset";
//
// // The application to show
// protected String app = null;
// // some applications might require forced height (and, more seldom, width)
// protected String style = null; // e.g "height:500px;"
// // force the portlet to use this widgetset - portlet level setting
// protected String portletWidgetset = null;
//
// public void destroy() {
//
// }
//
// public void init(PortletConfig config) throws PortletException {
// app = config.getInitParameter(PORTLET_PARAMETER_APPLICATION);
// if (app == null) {
// throw new PortletException(
// "No porlet application url defined in portlet.xml. Define the '"
// + PORTLET_PARAMETER_APPLICATION
// + "' init parameter to be the servlet deployment path.");
// }
// style = config.getInitParameter(PORTLET_PARAMETER_STYLE);
// // enable forcing the selection of the widgetset in portlet
// // configuration for a single portlet (backwards compatibility)
// portletWidgetset = config.getInitParameter(PORTLET_PARAMETER_WIDGETSET);
// }
//
// public void processAction(ActionRequest request, ActionResponse response)
// throws PortletException, IOException {
// PortletApplicationContext.dispatchRequest(this, request, response);
// }
//
// public void render(RenderRequest request, RenderResponse response)
// throws PortletException, IOException {
//
// // display the Vaadin application
// writeAjaxWindow(request, response);
// }
//
// protected void writeAjaxWindow(RenderRequest request,
// RenderResponse response) throws IOException {
//
// response.setContentType("text/html");
// if (app != null) {
// PortletSession sess = request.getPortletSession();
// PortletApplicationContext ctx = PortletApplicationContext
// .getApplicationContext(sess);
//
// PortletRequestDispatcher dispatcher = sess.getPortletContext()
// .getRequestDispatcher("/" + app);
//
// try {
// // portal-wide settings
// PortalContext portalCtx = request.getPortalContext();
//
// boolean isLifeRay = portalCtx.getPortalInfo().toLowerCase()
// .contains("liferay");
//
// request.setAttribute(ApplicationServlet.REQUEST_FRAGMENT,
// "true");
//
// // fixed base theme to use - all portal pages with Vaadin
// // applications will load this exactly once
// String portalTheme = getPortalProperty(
// Constants.PORTAL_PARAMETER_VAADIN_THEME, portalCtx);
//
// String portalWidgetset = getPortalProperty(
// Constants.PORTAL_PARAMETER_VAADIN_WIDGETSET, portalCtx);
//
// // location of the widgetset(s) and default theme (to which
// // /VAADIN/widgetsets/...
// // is appended)
// String portalResourcePath = getPortalProperty(
// Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH,
// portalCtx);
//
// if (portalResourcePath != null) {
// // if portalResourcePath is defined, set it as a request
// // parameter which will override the default location in
// // servlet
// request.setAttribute(
// ApplicationServlet.REQUEST_VAADIN_STATIC_FILE_PATH,
// portalResourcePath);
// }
//
// // - if the user has specified a widgetset for this portlet, use
// // it from the portlet (not fully supported)
// // - otherwise, if specified, use the portal-wide widgetset
// // and widgetset path settings (recommended)
// // - finally, default to use the default widgetset if nothing
// // else is found
// if (portletWidgetset != null) {
// request.setAttribute(ApplicationServlet.REQUEST_WIDGETSET,
// portletWidgetset);
// }
// if (portalWidgetset != null) {
// request.setAttribute(
// ApplicationServlet.REQUEST_SHARED_WIDGETSET,
// portalWidgetset);
// }
//
// if (style != null) {
// request.setAttribute(ApplicationServlet.REQUEST_APPSTYLE,
// style);
// }
//
// // portalTheme is only used if the shared portal resource
// // directory is defined
// if (portalTheme != null && portalResourcePath != null) {
// request.setAttribute(
// ApplicationServlet.REQUEST_DEFAULT_THEME,
// portalTheme);
//
// String defaultThemeUri = null;
// defaultThemeUri = portalResourcePath + "/"
// + AbstractApplicationServlet.THEME_DIRECTORY_PATH
// + portalTheme;
// /*
// * Make sure portal default Vaadin theme is included in DOM.
// * Vaadin portlet themes do not "inherit" base theme, so we
// * need to force loading of the common base theme.
// */
// OutputStream out = response.getPortletOutputStream();
//
// // Using portal-wide theme
// String loadDefaultTheme = ("<script type=\"text/javascript\">\n"
// + "if(!vaadin) { var vaadin = {} } \n"
// + "if(!vaadin.themesLoaded) { vaadin.themesLoaded = {} } \n"
// + "if(!vaadin.themesLoaded['"
// + portalTheme
// + "']) {\n"
// + "var stylesheet = document.createElement('link');\n"
// + "stylesheet.setAttribute('rel', 'stylesheet');\n"
// + "stylesheet.setAttribute('type', 'text/css');\n"
// + "stylesheet.setAttribute('href', '"
// + defaultThemeUri
// + "/styles.css');\n"
// + "document.getElementsByTagName('head')[0].appendChild(stylesheet);\n"
// + "vaadin.themesLoaded['"
// + portalTheme
// + "'] = true;\n}\n" + "</script>\n");
// out.write(loadDefaultTheme.getBytes());
// }
//
// dispatcher.include(request, response);
//
// if (isLifeRay) {
// /*
// * Temporary support to heartbeat Liferay session when using
// * Vaadin based portlet. We hit an extra xhr to liferay
// * servlet to extend the session lifetime after each Vaadin
// * request. This hack can be removed when supporting portlet
// * 2.0 and resourceRequests.
// *
// * TODO make this configurable, this is not necessary with
// * some custom session configurations.
// */
// OutputStream out = response.getPortletOutputStream();
//
// String lifeRaySessionHearbeatHack = ("<script type=\"text/javascript\">"
// + "if(!vaadin.postRequestHooks) {"
// + " vaadin.postRequestHooks = {};"
// + "}"
// + "vaadin.postRequestHooks.liferaySessionHeartBeat = function() {"
// + " if (Liferay && Liferay.Session && Liferay.Session.setCookie) {"
// + " Liferay.Session.setCookie();"
// + " }"
// + "};" + "</script>");
// out.write(lifeRaySessionHearbeatHack.getBytes());
// }
//
// } catch (PortletException e) {
// PrintWriter out = response.getWriter();
// out.print("<h1>Servlet include failed!</h1>");
// Logger.getLogger(AbstractApplicationPortlet.class.getName())
// .log(Level.WARNING, "Servlet include failed", e);
// ctx.setPortletApplication(this, null);
// return;
// }
//
// Application app = (Application) request
// .getAttribute(Application.class.getName());
// ctx.setPortletApplication(this, app);
// ctx.firePortletRenderRequest(this, request, response);
//
// }
// }
//
// private String getPortalProperty(String name, PortalContext context) {
// boolean isLifeRay = context.getPortalInfo().toLowerCase()
// .contains("liferay");
//
// // TODO test on non-LifeRay platforms
//
// String value;
// if (isLifeRay) {
// value = getLifeRayPortalProperty(name);
// } else {
// value = context.getProperty(name);
// }
//
// return value;
// }
//
// private String getLifeRayPortalProperty(String name) {
// String value;
// try {
// value = PropsUtil.get(name);
// } catch (Exception e) {
// value = null;
// }
// return value;
// }
// }

+ 43
- 43
src/com/vaadin/terminal/gwt/server/ApplicationPortlet2.java View File

@@ -1,46 +1,46 @@
/*
@ITMillApache2LicenseForJavaFiles@
*/
package com.vaadin.terminal.gwt.server;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
import com.vaadin.Application;
/**
* TODO Write documentation, fix JavaDoc tags.
*
* @author peholmst
*/
public class ApplicationPortlet2 extends AbstractApplicationPortlet {
private Class<? extends Application> applicationClass;
@SuppressWarnings("unchecked")
@Override
public void init(PortletConfig config) throws PortletException {
super.init(config);
final String applicationClassName = config
.getInitParameter("application");
if (applicationClassName == null) {
throw new PortletException(
"Application not specified in portlet parameters");
}
try {
applicationClass = (Class<? extends Application>) getClassLoader()
.loadClass(applicationClassName);
} catch (final ClassNotFoundException e) {
throw new PortletException("Failed to load application class: "
+ applicationClassName);
}
}
@Override
protected Class<? extends Application> getApplicationClass() {
return applicationClass;
}
}
//
//package com.vaadin.terminal.gwt.server;
//
//import javax.portlet.PortletConfig;
//import javax.portlet.PortletException;
//
//import com.vaadin.Application;
//
///**
// * TODO Write documentation, fix JavaDoc tags.
// *
// * @author peholmst
// */
//public class ApplicationPortlet2 extends AbstractApplicationPortlet {
//
// private Class<? extends Application> applicationClass;
//
// @SuppressWarnings("unchecked")
// @Override
// public void init(PortletConfig config) throws PortletException {
// super.init(config);
// final String applicationClassName = config
// .getInitParameter("application");
// if (applicationClassName == null) {
// throw new PortletException(
// "Application not specified in portlet parameters");
// }
//
// try {
// applicationClass = (Class<? extends Application>) getClassLoader()
// .loadClass(applicationClassName);
// } catch (final ClassNotFoundException e) {
// throw new PortletException("Failed to load application class: "
// + applicationClassName);
// }
// }
//
// @Override
// protected Class<? extends Application> getApplicationClass() {
// return applicationClass;
// }
//
// }

+ 7
- 7
src/com/vaadin/terminal/gwt/server/CommunicationManager.java View File

@@ -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,13 @@ 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);
root);
}

/**
@@ -295,7 +296,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 +304,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);
}

/**

+ 415
- 415
src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java View File

@@ -1,418 +1,418 @@
/*
@ITMillApache2LicenseForJavaFiles@
*/
package com.vaadin.terminal.gwt.server;
import java.io.File;
import java.io.Serializable;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.EventRequest;
import javax.portlet.EventResponse;
import javax.portlet.MimeResponse;
import javax.portlet.PortletConfig;
import javax.portlet.PortletMode;
import javax.portlet.PortletModeException;
import javax.portlet.PortletResponse;
import javax.portlet.PortletSession;
import javax.portlet.PortletURL;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.ResourceURL;
import javax.portlet.StateAwareResponse;
import javax.servlet.http.HttpSessionBindingListener;
import javax.xml.namespace.QName;
import com.vaadin.Application;
import com.vaadin.terminal.ApplicationResource;
import com.vaadin.terminal.ExternalResource;
import com.vaadin.ui.Window;
/**
* TODO Write documentation, fix JavaDoc tags.
*
* This is automatically registered as a {@link HttpSessionBindingListener} when
* {@link PortletSession#setAttribute()} is called with the context as value.
*
* @author peholmst
*/
@SuppressWarnings("serial")
public class PortletApplicationContext2 extends AbstractWebApplicationContext {
private static final Logger logger = Logger
.getLogger(PortletApplicationContext2.class.getName());
protected Map<Application, Set<PortletListener>> portletListeners = new HashMap<Application, Set<PortletListener>>();
protected transient PortletSession session;
protected transient PortletConfig portletConfig;
protected HashMap<String, Application> portletWindowIdToApplicationMap = new HashMap<String, Application>();
private transient PortletResponse response;
private final Map<String, QName> eventActionDestinationMap = new HashMap<String, QName>();
private final Map<String, Serializable> eventActionValueMap = new HashMap<String, Serializable>();
private final Map<String, String> sharedParameterActionNameMap = new HashMap<String, String>();
private final Map<String, String> sharedParameterActionValueMap = new HashMap<String, String>();
public File getBaseDirectory() {
String resultPath = session.getPortletContext().getRealPath("/");
if (resultPath != null) {
return new File(resultPath);
} else {
try {
final URL url = session.getPortletContext().getResource("/");
return new File(url.getFile());
} catch (final Exception e) {
// FIXME: Handle exception
logger.log(
Level.INFO,
"Cannot access base directory, possible security issue "
+ "with Application Server or Servlet Container",
e);
}
}
return null;
}
protected PortletCommunicationManager getApplicationManager(
Application application) {
PortletCommunicationManager mgr = (PortletCommunicationManager) applicationToAjaxAppMgrMap
.get(application);
if (mgr == null) {
// Creates a new manager
mgr = createPortletCommunicationManager(application);
applicationToAjaxAppMgrMap.put(application, mgr);
}
return mgr;
}
protected PortletCommunicationManager createPortletCommunicationManager(
Application application) {
return new PortletCommunicationManager(application);
}
public static PortletApplicationContext2 getApplicationContext(
PortletSession session) {
Object cxattr = session.getAttribute(PortletApplicationContext2.class
.getName());
PortletApplicationContext2 cx = null;
// can be false also e.g. if old context comes from another
// classloader when using
// <private-session-attributes>false</private-session-attributes>
// and redeploying the portlet - see #7461
if (cxattr instanceof PortletApplicationContext2) {
cx = (PortletApplicationContext2) cxattr;
}
if (cx == null) {
cx = new PortletApplicationContext2();
session.setAttribute(PortletApplicationContext2.class.getName(), cx);
}
if (cx.session == null) {
cx.session = session;
}
return cx;
}
@Override
protected void removeApplication(Application application) {
super.removeApplication(application);
// values() is backed by map, removes the key-value pair from the map
portletWindowIdToApplicationMap.values().remove(application);
}
protected void addApplication(Application application,
String portletWindowId) {
applications.add(application);
portletWindowIdToApplicationMap.put(portletWindowId, application);
}
public Application getApplicationForWindowId(String portletWindowId) {
return portletWindowIdToApplicationMap.get(portletWindowId);
}
public PortletSession getPortletSession() {
return session;
}
public PortletConfig getPortletConfig() {
return portletConfig;
}
public void setPortletConfig(PortletConfig config) {
portletConfig = config;
}
public void addPortletListener(Application app, PortletListener listener) {
Set<PortletListener> l = portletListeners.get(app);
if (l == null) {
l = new LinkedHashSet<PortletListener>();
portletListeners.put(app, l);
}
l.add(listener);
}
public void removePortletListener(Application app, PortletListener listener) {
Set<PortletListener> l = portletListeners.get(app);
if (l != null) {
l.remove(listener);
}
}
public void firePortletRenderRequest(Application app, Window window,
RenderRequest request, RenderResponse response) {
Set<PortletListener> listeners = portletListeners.get(app);
if (listeners != null) {
for (PortletListener l : listeners) {
l.handleRenderRequest(request, new RestrictedRenderResponse(
response), window);
}
}
}
public void firePortletActionRequest(Application app, Window window,
ActionRequest request, ActionResponse response) {
String key = request.getParameter(ActionRequest.ACTION_NAME);
if (eventActionDestinationMap.containsKey(key)) {
// this action request is only to send queued portlet events
response.setEvent(eventActionDestinationMap.get(key),
eventActionValueMap.get(key));
// cleanup
eventActionDestinationMap.remove(key);
eventActionValueMap.remove(key);
} else if (sharedParameterActionNameMap.containsKey(key)) {
// this action request is only to set shared render parameters
response.setRenderParameter(sharedParameterActionNameMap.get(key),
sharedParameterActionValueMap.get(key));
// cleanup
sharedParameterActionNameMap.remove(key);
sharedParameterActionValueMap.remove(key);
} else {
// normal action request, notify listeners
Set<PortletListener> listeners = portletListeners.get(app);
if (listeners != null) {
for (PortletListener l : listeners) {
l.handleActionRequest(request, response, window);
}
}
}
}
public void firePortletEventRequest(Application app, Window window,
EventRequest request, EventResponse response) {
Set<PortletListener> listeners = portletListeners.get(app);
if (listeners != null) {
for (PortletListener l : listeners) {
l.handleEventRequest(request, response, window);
}
}
}
public void firePortletResourceRequest(Application app, Window window,
ResourceRequest request, ResourceResponse response) {
Set<PortletListener> listeners = portletListeners.get(app);
if (listeners != null) {
for (PortletListener l : listeners) {
l.handleResourceRequest(request, response, window);
}
}
}
public interface PortletListener extends Serializable {
public void handleRenderRequest(RenderRequest request,
RenderResponse response, Window window);
public void handleActionRequest(ActionRequest request,
ActionResponse response, Window window);
public void handleEventRequest(EventRequest request,
EventResponse response, Window window);
public void handleResourceRequest(ResourceRequest request,
ResourceResponse response, Window window);
}
/**
* This is for use by {@link AbstractApplicationPortlet} only.
*
* TODO cleaner implementation, now "semi-static"!
*
* @param mimeResponse
*/
void setResponse(PortletResponse response) {
this.response = response;
}
@Override
public String generateApplicationResourceURL(ApplicationResource resource,
String mapKey) {
if (response instanceof MimeResponse) {
ResourceURL resourceURL = ((MimeResponse) response)
.createResourceURL();
final String filename = resource.getFilename();
if (filename == null) {
resourceURL.setResourceID("APP/" + mapKey + "/");
} else {
resourceURL.setResourceID("APP/" + mapKey + "/"
+ urlEncode(filename));
}
return resourceURL.toString();
} else {
// in a background thread or otherwise outside a request
// TODO exception ??
return null;
}
}
/**
* Creates a new action URL.
*
* @param action
* @return action URL or null if called outside a MimeRequest (outside a
* UIDL request or similar)
*/
public PortletURL generateActionURL(String action) {
PortletURL url = null;
if (response instanceof MimeResponse) {
url = ((MimeResponse) response).createActionURL();
url.setParameter("javax.portlet.action", action);
} else {
return null;
}
return url;
}
/**
* Sends a portlet event to the indicated destination.
*
* Internally, an action may be created and opened, as an event cannot be
* sent directly from all types of requests.
*
* The event destinations and values need to be kept in the context until
* sent. Any memory leaks if the action fails are limited to the session.
*
* Event names for events sent and received by a portlet need to be declared
* in portlet.xml .
*
* @param window
* a window in which a temporary action URL can be opened if
* necessary
* @param name
* event name
* @param value
* event value object that is Serializable and, if appropriate,
* has a valid JAXB annotation
*/
public void sendPortletEvent(Window window, QName name, Serializable value)
throws IllegalStateException {
if (response instanceof MimeResponse) {
String actionKey = "" + System.currentTimeMillis();
while (eventActionDestinationMap.containsKey(actionKey)) {
actionKey = actionKey + ".";
}
PortletURL actionUrl = generateActionURL(actionKey);
if (actionUrl != null) {
eventActionDestinationMap.put(actionKey, name);
eventActionValueMap.put(actionKey, value);
window.open(new ExternalResource(actionUrl.toString()));
} else {
// this should never happen as we already know the response is a
// MimeResponse
throw new IllegalStateException(
"Portlet events can only be sent from a portlet request");
}
} else if (response instanceof StateAwareResponse) {
((StateAwareResponse) response).setEvent(name, value);
} else {
throw new IllegalStateException(
"Portlet events can only be sent from a portlet request");
}
}
/**
* Sets a shared portlet parameter.
*
* Internally, an action may be created and opened, as shared parameters
* cannot be set directly from all types of requests.
*
* The parameters and values need to be kept in the context until sent. Any
* memory leaks if the action fails are limited to the session.
*
* Shared parameters set or read by a portlet need to be declared in
* portlet.xml .
*
* @param window
* a window in which a temporary action URL can be opened if
* necessary
* @param name
* parameter identifier
* @param value
* parameter value
*/
public void setSharedRenderParameter(Window window, String name,
String value) throws IllegalStateException {
if (response instanceof MimeResponse) {
String actionKey = "" + System.currentTimeMillis();
while (sharedParameterActionNameMap.containsKey(actionKey)) {
actionKey = actionKey + ".";
}
PortletURL actionUrl = generateActionURL(actionKey);
if (actionUrl != null) {
sharedParameterActionNameMap.put(actionKey, name);
sharedParameterActionValueMap.put(actionKey, value);
window.open(new ExternalResource(actionUrl.toString()));
} else {
// this should never happen as we already know the response is a
// MimeResponse
throw new IllegalStateException(
"Shared parameters can only be set from a portlet request");
}
} else if (response instanceof StateAwareResponse) {
((StateAwareResponse) response).setRenderParameter(name, value);
} else {
throw new IllegalStateException(
"Shared parameters can only be set from a portlet request");
}
}
/**
* Sets the portlet mode. This may trigger a new render request.
*
* Portlet modes used by a portlet need to be declared in portlet.xml .
*
* @param window
* a window in which the render URL can be opened if necessary
* @param portletMode
* the portlet mode to switch to
* @throws PortletModeException
* if the portlet mode is not allowed for some reason
* (configuration, permissions etc.)
*/
public void setPortletMode(Window window, PortletMode portletMode)
throws IllegalStateException, PortletModeException {
if (response instanceof MimeResponse) {
PortletURL url = ((MimeResponse) response).createRenderURL();
url.setPortletMode(portletMode);
window.open(new ExternalResource(url.toString()));
} else if (response instanceof StateAwareResponse) {
((StateAwareResponse) response).setPortletMode(portletMode);
} else {
throw new IllegalStateException(
"Portlet mode can only be changed from a portlet request");
}
}
}
//package com.vaadin.terminal.gwt.server;
//
//import java.io.File;
//import java.io.Serializable;
//import java.net.URL;
//import java.util.HashMap;
//import java.util.LinkedHashSet;
//import java.util.Map;
//import java.util.Set;
//import java.util.logging.Level;
//import java.util.logging.Logger;
//
//import javax.portlet.ActionRequest;
//import javax.portlet.ActionResponse;
//import javax.portlet.EventRequest;
//import javax.portlet.EventResponse;
//import javax.portlet.MimeResponse;
//import javax.portlet.PortletConfig;
//import javax.portlet.PortletMode;
//import javax.portlet.PortletModeException;
//import javax.portlet.PortletResponse;
//import javax.portlet.PortletSession;
//import javax.portlet.PortletURL;
//import javax.portlet.RenderRequest;
//import javax.portlet.RenderResponse;
//import javax.portlet.ResourceRequest;
//import javax.portlet.ResourceResponse;
//import javax.portlet.ResourceURL;
//import javax.portlet.StateAwareResponse;
//import javax.servlet.http.HttpSessionBindingListener;
//import javax.xml.namespace.QName;
//
//import com.vaadin.Application;
//import com.vaadin.terminal.ApplicationResource;
//import com.vaadin.terminal.ExternalResource;
//import com.vaadin.ui.Window;
//
///**
// * TODO Write documentation, fix JavaDoc tags.
// *
// * This is automatically registered as a {@link HttpSessionBindingListener} when
// * {@link PortletSession#setAttribute()} is called with the context as value.
// *
// * @author peholmst
// */
//@SuppressWarnings("serial")
//public class PortletApplicationContext2 extends AbstractWebApplicationContext {
//
// private static final Logger logger = Logger
// .getLogger(PortletApplicationContext2.class.getName());
//
// protected Map<Application, Set<PortletListener>> portletListeners = new HashMap<Application, Set<PortletListener>>();
//
// protected transient PortletSession session;
// protected transient PortletConfig portletConfig;
//
// protected HashMap<String, Application> portletWindowIdToApplicationMap = new HashMap<String, Application>();
//
// private transient PortletResponse response;
//
// private final Map<String, QName> eventActionDestinationMap = new HashMap<String, QName>();
// private final Map<String, Serializable> eventActionValueMap = new HashMap<String, Serializable>();
//
// private final Map<String, String> sharedParameterActionNameMap = new HashMap<String, String>();
// private final Map<String, String> sharedParameterActionValueMap = new HashMap<String, String>();
//
// public File getBaseDirectory() {
// String resultPath = session.getPortletContext().getRealPath("/");
// if (resultPath != null) {
// return new File(resultPath);
// } else {
// try {
// final URL url = session.getPortletContext().getResource("/");
// return new File(url.getFile());
// } catch (final Exception e) {
// // FIXME: Handle exception
// logger.log(
// Level.INFO,
// "Cannot access base directory, possible security issue "
// + "with Application Server or Servlet Container",
// e);
// }
// }
// return null;
// }
//
// protected PortletCommunicationManager getApplicationManager(
// Application application) {
// PortletCommunicationManager mgr = (PortletCommunicationManager) applicationToAjaxAppMgrMap
// .get(application);
//
// if (mgr == null) {
// // Creates a new manager
// mgr = createPortletCommunicationManager(application);
// applicationToAjaxAppMgrMap.put(application, mgr);
// }
// return mgr;
// }
//
// protected PortletCommunicationManager createPortletCommunicationManager(
// Application application) {
// return new PortletCommunicationManager(application);
// }
//
// public static PortletApplicationContext2 getApplicationContext(
// PortletSession session) {
// Object cxattr = session.getAttribute(PortletApplicationContext2.class
// .getName());
// PortletApplicationContext2 cx = null;
// // can be false also e.g. if old context comes from another
// // classloader when using
// // <private-session-attributes>false</private-session-attributes>
// // and redeploying the portlet - see #7461
// if (cxattr instanceof PortletApplicationContext2) {
// cx = (PortletApplicationContext2) cxattr;
// }
// if (cx == null) {
// cx = new PortletApplicationContext2();
// session.setAttribute(PortletApplicationContext2.class.getName(), cx);
// }
// if (cx.session == null) {
// cx.session = session;
// }
// return cx;
// }
//
// @Override
// protected void removeApplication(Application application) {
// super.removeApplication(application);
// // values() is backed by map, removes the key-value pair from the map
// portletWindowIdToApplicationMap.values().remove(application);
// }
//
// protected void addApplication(Application application,
// String portletWindowId) {
// applications.add(application);
// portletWindowIdToApplicationMap.put(portletWindowId, application);
// }
//
// public Application getApplicationForWindowId(String portletWindowId) {
// return portletWindowIdToApplicationMap.get(portletWindowId);
// }
//
// public PortletSession getPortletSession() {
// return session;
// }
//
// public PortletConfig getPortletConfig() {
// return portletConfig;
// }
//
// public void setPortletConfig(PortletConfig config) {
// portletConfig = config;
// }
//
// public void addPortletListener(Application app, PortletListener listener) {
// Set<PortletListener> l = portletListeners.get(app);
// if (l == null) {
// l = new LinkedHashSet<PortletListener>();
// portletListeners.put(app, l);
// }
// l.add(listener);
// }
//
// public void removePortletListener(Application app, PortletListener listener) {
// Set<PortletListener> l = portletListeners.get(app);
// if (l != null) {
// l.remove(listener);
// }
// }
//
// public void firePortletRenderRequest(Application app, Window window,
// RenderRequest request, RenderResponse response) {
// Set<PortletListener> listeners = portletListeners.get(app);
// if (listeners != null) {
// for (PortletListener l : listeners) {
// l.handleRenderRequest(request, new RestrictedRenderResponse(
// response), window);
// }
// }
// }
//
// public void firePortletActionRequest(Application app, Window window,
// ActionRequest request, ActionResponse response) {
// String key = request.getParameter(ActionRequest.ACTION_NAME);
// if (eventActionDestinationMap.containsKey(key)) {
// // this action request is only to send queued portlet events
// response.setEvent(eventActionDestinationMap.get(key),
// eventActionValueMap.get(key));
// // cleanup
// eventActionDestinationMap.remove(key);
// eventActionValueMap.remove(key);
// } else if (sharedParameterActionNameMap.containsKey(key)) {
// // this action request is only to set shared render parameters
// response.setRenderParameter(sharedParameterActionNameMap.get(key),
// sharedParameterActionValueMap.get(key));
// // cleanup
// sharedParameterActionNameMap.remove(key);
// sharedParameterActionValueMap.remove(key);
// } else {
// // normal action request, notify listeners
// Set<PortletListener> listeners = portletListeners.get(app);
// if (listeners != null) {
// for (PortletListener l : listeners) {
// l.handleActionRequest(request, response, window);
// }
// }
// }
// }
//
// public void firePortletEventRequest(Application app, Window window,
// EventRequest request, EventResponse response) {
// Set<PortletListener> listeners = portletListeners.get(app);
// if (listeners != null) {
// for (PortletListener l : listeners) {
// l.handleEventRequest(request, response, window);
// }
// }
// }
//
// public void firePortletResourceRequest(Application app, Window window,
// ResourceRequest request, ResourceResponse response) {
// Set<PortletListener> listeners = portletListeners.get(app);
// if (listeners != null) {
// for (PortletListener l : listeners) {
// l.handleResourceRequest(request, response, window);
// }
// }
// }
//
// public interface PortletListener extends Serializable {
//
// public void handleRenderRequest(RenderRequest request,
// RenderResponse response, Window window);
//
// public void handleActionRequest(ActionRequest request,
// ActionResponse response, Window window);
//
// public void handleEventRequest(EventRequest request,
// EventResponse response, Window window);
//
// public void handleResourceRequest(ResourceRequest request,
// ResourceResponse response, Window window);
// }
//
// /**
// * This is for use by {@link AbstractApplicationPortlet} only.
// *
// * TODO cleaner implementation, now "semi-static"!
// *
// * @param mimeResponse
// */
// void setResponse(PortletResponse response) {
// this.response = response;
// }
//
// @Override
// public String generateApplicationResourceURL(ApplicationResource resource,
// String mapKey) {
// if (response instanceof MimeResponse) {
// ResourceURL resourceURL = ((MimeResponse) response)
// .createResourceURL();
// final String filename = resource.getFilename();
// if (filename == null) {
// resourceURL.setResourceID("APP/" + mapKey + "/");
// } else {
// resourceURL.setResourceID("APP/" + mapKey + "/"
// + urlEncode(filename));
// }
// return resourceURL.toString();
// } else {
// // in a background thread or otherwise outside a request
// // TODO exception ??
// return null;
// }
// }
//
// /**
// * Creates a new action URL.
// *
// * @param action
// * @return action URL or null if called outside a MimeRequest (outside a
// * UIDL request or similar)
// */
// public PortletURL generateActionURL(String action) {
// PortletURL url = null;
// if (response instanceof MimeResponse) {
// url = ((MimeResponse) response).createActionURL();
// url.setParameter("javax.portlet.action", action);
// } else {
// return null;
// }
// return url;
// }
//
// /**
// * Sends a portlet event to the indicated destination.
// *
// * Internally, an action may be created and opened, as an event cannot be
// * sent directly from all types of requests.
// *
// * The event destinations and values need to be kept in the context until
// * sent. Any memory leaks if the action fails are limited to the session.
// *
// * Event names for events sent and received by a portlet need to be declared
// * in portlet.xml .
// *
// * @param window
// * a window in which a temporary action URL can be opened if
// * necessary
// * @param name
// * event name
// * @param value
// * event value object that is Serializable and, if appropriate,
// * has a valid JAXB annotation
// */
// public void sendPortletEvent(Window window, QName name, Serializable value)
// throws IllegalStateException {
// if (response instanceof MimeResponse) {
// String actionKey = "" + System.currentTimeMillis();
// while (eventActionDestinationMap.containsKey(actionKey)) {
// actionKey = actionKey + ".";
// }
// PortletURL actionUrl = generateActionURL(actionKey);
// if (actionUrl != null) {
// eventActionDestinationMap.put(actionKey, name);
// eventActionValueMap.put(actionKey, value);
// window.open(new ExternalResource(actionUrl.toString()));
// } else {
// // this should never happen as we already know the response is a
// // MimeResponse
// throw new IllegalStateException(
// "Portlet events can only be sent from a portlet request");
// }
// } else if (response instanceof StateAwareResponse) {
// ((StateAwareResponse) response).setEvent(name, value);
// } else {
// throw new IllegalStateException(
// "Portlet events can only be sent from a portlet request");
// }
// }
//
// /**
// * Sets a shared portlet parameter.
// *
// * Internally, an action may be created and opened, as shared parameters
// * cannot be set directly from all types of requests.
// *
// * The parameters and values need to be kept in the context until sent. Any
// * memory leaks if the action fails are limited to the session.
// *
// * Shared parameters set or read by a portlet need to be declared in
// * portlet.xml .
// *
// * @param window
// * a window in which a temporary action URL can be opened if
// * necessary
// * @param name
// * parameter identifier
// * @param value
// * parameter value
// */
// public void setSharedRenderParameter(Window window, String name,
// String value) throws IllegalStateException {
// if (response instanceof MimeResponse) {
// String actionKey = "" + System.currentTimeMillis();
// while (sharedParameterActionNameMap.containsKey(actionKey)) {
// actionKey = actionKey + ".";
// }
// PortletURL actionUrl = generateActionURL(actionKey);
// if (actionUrl != null) {
// sharedParameterActionNameMap.put(actionKey, name);
// sharedParameterActionValueMap.put(actionKey, value);
// window.open(new ExternalResource(actionUrl.toString()));
// } else {
// // this should never happen as we already know the response is a
// // MimeResponse
// throw new IllegalStateException(
// "Shared parameters can only be set from a portlet request");
// }
// } else if (response instanceof StateAwareResponse) {
// ((StateAwareResponse) response).setRenderParameter(name, value);
// } else {
// throw new IllegalStateException(
// "Shared parameters can only be set from a portlet request");
// }
// }
//
// /**
// * Sets the portlet mode. This may trigger a new render request.
// *
// * Portlet modes used by a portlet need to be declared in portlet.xml .
// *
// * @param window
// * a window in which the render URL can be opened if necessary
// * @param portletMode
// * the portlet mode to switch to
// * @throws PortletModeException
// * if the portlet mode is not allowed for some reason
// * (configuration, permissions etc.)
// */
// public void setPortletMode(Window window, PortletMode portletMode)
// throws IllegalStateException, PortletModeException {
// if (response instanceof MimeResponse) {
// PortletURL url = ((MimeResponse) response).createRenderURL();
// url.setPortletMode(portletMode);
// window.open(new ExternalResource(url.toString()));
// } else if (response instanceof StateAwareResponse) {
// ((StateAwareResponse) response).setPortletMode(portletMode);
// } else {
// throw new IllegalStateException(
// "Portlet mode can only be changed from a portlet request");
// }
// }
// }

+ 302
- 302
src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java View File

@@ -1,305 +1,305 @@
/*
@ITMillApache2LicenseForJavaFiles@
*/
package com.vaadin.terminal.gwt.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.portlet.ClientDataRequest;
import javax.portlet.MimeResponse;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.PortletSession;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.ResourceURL;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequestWrapper;
import com.vaadin.Application;
import com.vaadin.terminal.DownloadStream;
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;
/**
* TODO document me!
*
* @author peholmst
*
*/
@SuppressWarnings("serial")
public class PortletCommunicationManager extends AbstractCommunicationManager {
private transient ResourceResponse currentUidlResponse;
private static class PortletRequestWrapper implements Request {
private final PortletRequest request;
public PortletRequestWrapper(PortletRequest request) {
this.request = request;
}
public Object getAttribute(String name) {
return request.getAttribute(name);
}
public int getContentLength() {
return ((ClientDataRequest) request).getContentLength();
}
public InputStream getInputStream() throws IOException {
return ((ClientDataRequest) request).getPortletInputStream();
}
public String getParameter(String name) {
String value = request.getParameter(name);
if (value == null) {
// for GateIn portlet container simple-portal
try {
Method getRealReq = request.getClass().getMethod(
"getRealRequest");
HttpServletRequestWrapper origRequest = (HttpServletRequestWrapper) getRealReq
.invoke(request);
value = origRequest.getParameter(name);
} catch (Exception e) {
// do nothing - not on GateIn simple-portal
}
}
return value;
}
public String getRequestID() {
return "WindowID:" + request.getWindowID();
}
public Session getSession() {
return new PortletSessionWrapper(request.getPortletSession());
}
public Object getWrappedRequest() {
return request;
}
public boolean isRunningInPortlet() {
return true;
}
public void setAttribute(String name, Object o) {
request.setAttribute(name, o);
}
}
private static class PortletResponseWrapper implements Response {
private final PortletResponse response;
public PortletResponseWrapper(PortletResponse response) {
this.response = response;
}
public OutputStream getOutputStream() throws IOException {
return ((MimeResponse) response).getPortletOutputStream();
}
public Object getWrappedResponse() {
return response;
}
public void setContentType(String type) {
((MimeResponse) response).setContentType(type);
}
}
private static class PortletSessionWrapper implements Session {
private final PortletSession session;
public PortletSessionWrapper(PortletSession session) {
this.session = session;
}
public Object getAttribute(String name) {
return session.getAttribute(name);
}
public int getMaxInactiveInterval() {
return session.getMaxInactiveInterval();
}
public Object getWrappedSession() {
return session;
}
public boolean isNew() {
return session.isNew();
}
public void setAttribute(String name, Object o) {
session.setAttribute(name, o);
}
}
private static class AbstractApplicationPortletWrapper implements Callback {
private final AbstractApplicationPortlet portlet;
public AbstractApplicationPortletWrapper(
AbstractApplicationPortlet portlet) {
this.portlet = portlet;
}
public void criticalNotification(Request request, Response response,
String cap, String msg, String details, String outOfSyncURL)
throws IOException {
portlet.criticalNotification(
(PortletRequest) request.getWrappedRequest(),
(MimeResponse) response.getWrappedResponse(), cap, msg,
details, outOfSyncURL);
}
public String getRequestPathInfo(Request request) {
if (request.getWrappedRequest() instanceof ResourceRequest) {
return ((ResourceRequest) request.getWrappedRequest())
.getResourceID();
} else {
// We do not use paths in portlet mode
throw new UnsupportedOperationException(
"PathInfo only available when using ResourceRequests");
}
}
public InputStream getThemeResourceAsStream(String themeName,
String resource) throws IOException {
return portlet.getPortletContext().getResourceAsStream(
"/" + AbstractApplicationPortlet.THEME_DIRECTORY_PATH
+ themeName + "/" + resource);
}
}
public PortletCommunicationManager(Application application) {
super(application);
}
public void handleFileUpload(ResourceRequest request,
ResourceResponse response) throws IOException {
String contentType = request.getContentType();
String name = request.getParameter("name");
String ownerId = request.getParameter("rec-owner");
VariableOwner variableOwner = getVariableOwner(ownerId);
StreamVariable streamVariable = ownerToNameToStreamVariable.get(
variableOwner).get(name);
if (contentType.contains("boundary")) {
doHandleSimpleMultipartFileUpload(
new PortletRequestWrapper(request),
new PortletResponseWrapper(response), streamVariable, name,
variableOwner, contentType.split("boundary=")[1]);
} else {
doHandleXhrFilePost(new PortletRequestWrapper(request),
new PortletResponseWrapper(response), streamVariable, name,
variableOwner, request.getContentLength());
}
}
@Override
protected void unregisterPaintable(Component p) {
super.unregisterPaintable(p);
if (ownerToNameToStreamVariable != null) {
ownerToNameToStreamVariable.remove(p);
}
}
public void handleUidlRequest(ResourceRequest request,
ResourceResponse response,
AbstractApplicationPortlet applicationPortlet, Window window)
throws InvalidUIDLSecurityKeyException, IOException {
currentUidlResponse = response;
doHandleUidlRequest(new PortletRequestWrapper(request),
new PortletResponseWrapper(response),
new AbstractApplicationPortletWrapper(applicationPortlet),
window);
currentUidlResponse = null;
}
DownloadStream handleURI(Window window, ResourceRequest request,
ResourceResponse response,
AbstractApplicationPortlet applicationPortlet) {
return handleURI(window, new PortletRequestWrapper(request),
new PortletResponseWrapper(response),
new AbstractApplicationPortletWrapper(applicationPortlet));
}
/**
* Gets the existing application or creates a new one. Get a window within
* an application based on the requested URI.
*
* @param request
* the portlet Request.
* @param applicationPortlet
* @param application
* the Application to query for window.
* @param assumedWindow
* 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.
* @throws ServletException
* if an exception has occurred that interferes with the
* servlet's normal operation.
*/
Window getApplicationWindow(PortletRequest request,
AbstractApplicationPortlet applicationPortlet,
Application application, Window assumedWindow) {
return doGetApplicationWindow(new PortletRequestWrapper(request),
new AbstractApplicationPortletWrapper(applicationPortlet),
application, assumedWindow);
}
private Map<VariableOwner, Map<String, StreamVariable>> ownerToNameToStreamVariable;
@Override
String getStreamVariableTargetUrl(VariableOwner owner, String name,
StreamVariable value) {
if (ownerToNameToStreamVariable == null) {
ownerToNameToStreamVariable = new HashMap<VariableOwner, Map<String, StreamVariable>>();
}
Map<String, StreamVariable> nameToReceiver = ownerToNameToStreamVariable
.get(owner);
if (nameToReceiver == null) {
nameToReceiver = new HashMap<String, StreamVariable>();
ownerToNameToStreamVariable.put(owner, nameToReceiver);
}
nameToReceiver.put(name, value);
ResourceURL resurl = currentUidlResponse.createResourceURL();
resurl.setResourceID("UPLOAD");
resurl.setParameter("name", name);
resurl.setParameter("rec-owner", getPaintableId((Paintable) owner));
resurl.setProperty("name", name);
resurl.setProperty("rec-owner", getPaintableId((Paintable) owner));
return resurl.toString();
}
@Override
protected void cleanStreamVariable(VariableOwner owner, String name) {
Map<String, StreamVariable> map = ownerToNameToStreamVariable
.get(owner);
map.remove(name);
if (map.isEmpty()) {
ownerToNameToStreamVariable.remove(owner);
}
}
}
//package com.vaadin.terminal.gwt.server;
//
//import java.io.IOException;
//import java.io.InputStream;
//import java.io.OutputStream;
//import java.lang.reflect.Method;
//import java.util.HashMap;
//import java.util.Map;
//
//import javax.portlet.ClientDataRequest;
//import javax.portlet.MimeResponse;
//import javax.portlet.PortletRequest;
//import javax.portlet.PortletResponse;
//import javax.portlet.PortletSession;
//import javax.portlet.ResourceRequest;
//import javax.portlet.ResourceResponse;
//import javax.portlet.ResourceURL;
//import javax.servlet.ServletException;
//import javax.servlet.http.HttpServletRequestWrapper;
//
//import com.vaadin.Application;
//import com.vaadin.terminal.DownloadStream;
//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;
//
///**
// * TODO document me!
// *
// * @author peholmst
// *
// */
//@SuppressWarnings("serial")
//public class PortletCommunicationManager extends AbstractCommunicationManager {
//
// private transient ResourceResponse currentUidlResponse;
//
// private static class PortletRequestWrapper implements Request {
//
// private final PortletRequest request;
//
// public PortletRequestWrapper(PortletRequest request) {
// this.request = request;
// }
//
// public Object getAttribute(String name) {
// return request.getAttribute(name);
// }
//
// public int getContentLength() {
// return ((ClientDataRequest) request).getContentLength();
// }
//
// public InputStream getInputStream() throws IOException {
// return ((ClientDataRequest) request).getPortletInputStream();
// }
//
// public String getParameter(String name) {
// String value = request.getParameter(name);
// if (value == null) {
// // for GateIn portlet container simple-portal
// try {
// Method getRealReq = request.getClass().getMethod(
// "getRealRequest");
// HttpServletRequestWrapper origRequest = (HttpServletRequestWrapper) getRealReq
// .invoke(request);
// value = origRequest.getParameter(name);
// } catch (Exception e) {
// // do nothing - not on GateIn simple-portal
// }
// }
// return value;
// }
//
// public String getRequestID() {
// return "WindowID:" + request.getWindowID();
// }
//
// public Session getSession() {
// return new PortletSessionWrapper(request.getPortletSession());
// }
//
// public Object getWrappedRequest() {
// return request;
// }
//
// public boolean isRunningInPortlet() {
// return true;
// }
//
// public void setAttribute(String name, Object o) {
// request.setAttribute(name, o);
// }
//
// }
//
// private static class PortletResponseWrapper implements Response {
//
// private final PortletResponse response;
//
// public PortletResponseWrapper(PortletResponse response) {
// this.response = response;
// }
//
// public OutputStream getOutputStream() throws IOException {
// return ((MimeResponse) response).getPortletOutputStream();
// }
//
// public Object getWrappedResponse() {
// return response;
// }
//
// public void setContentType(String type) {
// ((MimeResponse) response).setContentType(type);
// }
// }
//
// private static class PortletSessionWrapper implements Session {
//
// private final PortletSession session;
//
// public PortletSessionWrapper(PortletSession session) {
// this.session = session;
// }
//
// public Object getAttribute(String name) {
// return session.getAttribute(name);
// }
//
// public int getMaxInactiveInterval() {
// return session.getMaxInactiveInterval();
// }
//
// public Object getWrappedSession() {
// return session;
// }
//
// public boolean isNew() {
// return session.isNew();
// }
//
// public void setAttribute(String name, Object o) {
// session.setAttribute(name, o);
// }
//
// }
//
// private static class AbstractApplicationPortletWrapper implements Callback {
//
// private final AbstractApplicationPortlet portlet;
//
// public AbstractApplicationPortletWrapper(
// AbstractApplicationPortlet portlet) {
// this.portlet = portlet;
// }
//
// public void criticalNotification(Request request, Response response,
// String cap, String msg, String details, String outOfSyncURL)
// throws IOException {
// portlet.criticalNotification(
// (PortletRequest) request.getWrappedRequest(),
// (MimeResponse) response.getWrappedResponse(), cap, msg,
// details, outOfSyncURL);
// }
//
// public String getRequestPathInfo(Request request) {
// if (request.getWrappedRequest() instanceof ResourceRequest) {
// return ((ResourceRequest) request.getWrappedRequest())
// .getResourceID();
// } else {
// // We do not use paths in portlet mode
// throw new UnsupportedOperationException(
// "PathInfo only available when using ResourceRequests");
// }
// }
//
// public InputStream getThemeResourceAsStream(String themeName,
// String resource) throws IOException {
// return portlet.getPortletContext().getResourceAsStream(
// "/" + AbstractApplicationPortlet.THEME_DIRECTORY_PATH
// + themeName + "/" + resource);
// }
//
// }
//
// public PortletCommunicationManager(Application application) {
// super(application);
// }
//
// public void handleFileUpload(ResourceRequest request,
// ResourceResponse response) throws IOException {
// String contentType = request.getContentType();
// String name = request.getParameter("name");
// String ownerId = request.getParameter("rec-owner");
// VariableOwner variableOwner = getVariableOwner(ownerId);
// StreamVariable streamVariable = ownerToNameToStreamVariable.get(
// variableOwner).get(name);
//
// if (contentType.contains("boundary")) {
// doHandleSimpleMultipartFileUpload(
// new PortletRequestWrapper(request),
// new PortletResponseWrapper(response), streamVariable, name,
// variableOwner, contentType.split("boundary=")[1]);
// } else {
// doHandleXhrFilePost(new PortletRequestWrapper(request),
// new PortletResponseWrapper(response), streamVariable, name,
// variableOwner, request.getContentLength());
// }
//
// }
//
// @Override
// protected void unregisterPaintable(Component p) {
// super.unregisterPaintable(p);
// if (ownerToNameToStreamVariable != null) {
// ownerToNameToStreamVariable.remove(p);
// }
// }
//
// public void handleUidlRequest(ResourceRequest request,
// ResourceResponse response,
// AbstractApplicationPortlet applicationPortlet, Window window)
// throws InvalidUIDLSecurityKeyException, IOException {
// currentUidlResponse = response;
// doHandleUidlRequest(new PortletRequestWrapper(request),
// new PortletResponseWrapper(response),
// new AbstractApplicationPortletWrapper(applicationPortlet),
// window);
// currentUidlResponse = null;
// }
//
// DownloadStream handleURI(Window window, ResourceRequest request,
// ResourceResponse response,
// AbstractApplicationPortlet applicationPortlet) {
// return handleURI(window, new PortletRequestWrapper(request),
// new PortletResponseWrapper(response),
// new AbstractApplicationPortletWrapper(applicationPortlet));
// }
//
// /**
// * Gets the existing application or creates a new one. Get a window within
// * an application based on the requested URI.
// *
// * @param request
// * the portlet Request.
// * @param applicationPortlet
// * @param application
// * the Application to query for window.
// * @param assumedWindow
// * 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.
// * @throws ServletException
// * if an exception has occurred that interferes with the
// * servlet's normal operation.
// */
// Window getApplicationWindow(PortletRequest request,
// AbstractApplicationPortlet applicationPortlet,
// Application application, Window assumedWindow) {
//
// return doGetApplicationWindow(new PortletRequestWrapper(request),
// new AbstractApplicationPortletWrapper(applicationPortlet),
// application, assumedWindow);
// }
//
// private Map<VariableOwner, Map<String, StreamVariable>> ownerToNameToStreamVariable;
//
// @Override
// String getStreamVariableTargetUrl(VariableOwner owner, String name,
// StreamVariable value) {
// if (ownerToNameToStreamVariable == null) {
// ownerToNameToStreamVariable = new HashMap<VariableOwner, Map<String, StreamVariable>>();
// }
// Map<String, StreamVariable> nameToReceiver = ownerToNameToStreamVariable
// .get(owner);
// if (nameToReceiver == null) {
// nameToReceiver = new HashMap<String, StreamVariable>();
// ownerToNameToStreamVariable.put(owner, nameToReceiver);
// }
// nameToReceiver.put(name, value);
// ResourceURL resurl = currentUidlResponse.createResourceURL();
// resurl.setResourceID("UPLOAD");
// resurl.setParameter("name", name);
// resurl.setParameter("rec-owner", getPaintableId((Paintable) owner));
// resurl.setProperty("name", name);
// resurl.setProperty("rec-owner", getPaintableId((Paintable) owner));
// return resurl.toString();
// }
//
// @Override
// protected void cleanStreamVariable(VariableOwner owner, String name) {
// Map<String, StreamVariable> map = ownerToNameToStreamVariable
// .get(owner);
// map.remove(name);
// if (map.isEmpty()) {
// ownerToNameToStreamVariable.remove(owner);
// }
// }
//
// }

+ 3
- 3
src/com/vaadin/ui/AbstractComponent.java View File

@@ -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;

+ 9
- 9
src/com/vaadin/ui/AbstractField.java View File

@@ -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;
}

+ 3
- 3
src/com/vaadin/ui/Component.java View File

@@ -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>
*

+ 58
- 0
src/com/vaadin/ui/DefaultRoot.java View File

@@ -0,0 +1,58 @@
package com.vaadin.ui;

import java.util.Collections;
import java.util.Iterator;

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;

@ClientWidget(VView.class)
public class DefaultRoot extends AbstractComponentContainer implements Root {
private final Component content;
private Terminal terminal;
private final Application application;

public DefaultRoot(Application application, Component content) {
this.application = application;
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);
}

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;
}
}

+ 13
- 12
src/com/vaadin/ui/LoginForm.java View File

@@ -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();
}


+ 13
- 0
src/com/vaadin/ui/Root.java View File

@@ -0,0 +1,13 @@
package com.vaadin.ui;

import com.vaadin.terminal.Terminal;

public interface Root extends Component {

public String getName();

public Terminal getTerminal();

public void setTerminal(Terminal terminal);

}

+ 1141
- 1110
src/com/vaadin/ui/Window.java
File diff suppressed because it is too large
View File


Loading…
Cancel
Save