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