summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebContent/WEB-INF/web.xml2
-rw-r--r--server/src/com/vaadin/server/AbstractCommunicationManager.java98
-rw-r--r--server/src/com/vaadin/server/BootstrapFragmentResponse.java7
-rw-r--r--server/src/com/vaadin/server/BootstrapHandler.java65
-rw-r--r--server/src/com/vaadin/server/BootstrapPageResponse.java6
-rw-r--r--server/src/com/vaadin/server/BootstrapResponse.java17
-rw-r--r--server/src/com/vaadin/server/CommunicationManager.java11
-rw-r--r--server/src/com/vaadin/server/LegacyVaadinPortlet.java2
-rw-r--r--server/src/com/vaadin/server/LegacyVaadinServlet.java2
-rw-r--r--server/src/com/vaadin/server/ServletPortletHelper.java8
-rw-r--r--server/src/com/vaadin/server/VaadinPortlet.java45
-rw-r--r--server/src/com/vaadin/server/VaadinService.java196
-rw-r--r--server/src/com/vaadin/server/VaadinServlet.java9
-rw-r--r--server/src/com/vaadin/server/VaadinSession.java422
-rw-r--r--server/src/com/vaadin/ui/UI.java28
-rw-r--r--uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java22
16 files changed, 513 insertions, 427 deletions
diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml
index d752b8eb33..d8a8066edc 100644
--- a/WebContent/WEB-INF/web.xml
+++ b/WebContent/WEB-INF/web.xml
@@ -26,7 +26,7 @@
<servlet-name>Embed App 2</servlet-name>
<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
<init-param>
- <param-name>ui</param-name>
+ <param-name>UI</param-name>
<param-value>com.vaadin.tests.components.label.MarginsInLabels</param-value>
</init-param>
</servlet>
diff --git a/server/src/com/vaadin/server/AbstractCommunicationManager.java b/server/src/com/vaadin/server/AbstractCommunicationManager.java
index 49243a0589..eaef7485b3 100644
--- a/server/src/com/vaadin/server/AbstractCommunicationManager.java
+++ b/server/src/com/vaadin/server/AbstractCommunicationManager.java
@@ -68,6 +68,7 @@ import com.vaadin.server.StreamVariable.StreamingEndEvent;
import com.vaadin.server.StreamVariable.StreamingErrorEvent;
import com.vaadin.server.Terminal.ErrorEvent;
import com.vaadin.server.Terminal.ErrorListener;
+import com.vaadin.server.VaadinRequest.BrowserDetails;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.Connector;
import com.vaadin.shared.JavaScriptConnectorState;
@@ -2432,10 +2433,7 @@ public abstract class AbstractCommunicationManager implements Serializable {
response.setContentType("application/json; charset=UTF-8");
- UI uI = session.getUIForRequest(combinedRequest);
- if (uI == null) {
- uI = session.createUI(combinedRequest);
- }
+ UI uI = getBrowserDetailsUI(combinedRequest);
JSONObject params = new JSONObject();
params.put(UIConstants.UI_ID_PARAMETER, uI.getUIId());
@@ -2461,6 +2459,98 @@ public abstract class AbstractCommunicationManager implements Serializable {
}
}
+ private UI getBrowserDetailsUI(VaadinRequest request) {
+ VaadinService vaadinService = request.getVaadinService();
+ VaadinSession session = VaadinSession.getForSession(request
+ .getWrappedSession());
+
+ List<UIProvider> uiProviders = vaadinService.getUIProviders(session);
+
+ UIProvider provider = null;
+ Class<? extends UI> uiClass = null;
+ for (UIProvider p : uiProviders) {
+ // Check if some UI provider has an existing UI available
+ UI existingUi = p.getExistingUI(request);
+ if (existingUi != null) {
+ UI.setCurrent(existingUi);
+ return existingUi;
+ }
+
+ uiClass = p.getUIClass(request);
+ if (uiClass != null) {
+ provider = p;
+ break;
+ }
+ }
+
+ if (provider == null || uiClass == null) {
+ return null;
+ }
+
+ // Check for an existing UI based on window.name
+ BrowserDetails browserDetails = request.getBrowserDetails();
+ boolean hasBrowserDetails = browserDetails != null
+ && browserDetails.getUriFragment() != null;
+
+ Map<String, Integer> retainOnRefreshUIs = session
+ .getPreserveOnRefreshUIs();
+ if (hasBrowserDetails && !retainOnRefreshUIs.isEmpty()) {
+ // Check for a known UI
+
+ @SuppressWarnings("null")
+ String windowName = browserDetails.getWindowName();
+ Integer retainedUIId = retainOnRefreshUIs.get(windowName);
+
+ if (retainedUIId != null) {
+ UI retainedUI = session.getUIById(retainedUIId.intValue());
+ if (uiClass.isInstance(retainedUI)) {
+ return retainedUI;
+ } else {
+ getLogger()
+ .info("Not using retained UI in " + windowName
+ + " because retained UI was of type "
+ + retainedUIId.getClass() + " but "
+ + uiClass + " is expected for the request.");
+ }
+ }
+ }
+
+ // No existing UI found - go on by creating and initializing one
+
+ // Explicit Class.cast to detect if the UIProvider does something
+ // unexpected
+ UI ui = uiClass.cast(provider.createInstance(request, uiClass));
+
+ // Initialize some fields for a newly created UI
+ if (ui.getSession() != session) {
+ // Session already set for LegacyWindow
+ ui.setSession(session);
+ }
+ Integer uiId = Integer.valueOf(session.getNextUIid());
+
+ // Set thread local here so it is available in init
+ UI.setCurrent(ui);
+
+ ui.doInit(request, uiId.intValue());
+
+ session.addUI(ui);
+
+ // Remember if it should be remembered
+ if (vaadinService.preserveUIOnRefresh(request, ui, provider)) {
+ // Remember this UI
+ String windowName = request.getBrowserDetails().getWindowName();
+ if (windowName == null) {
+ getLogger().warning(
+ "There is no window.name available for UI " + uiClass
+ + " that should be preserved.");
+ } else {
+ session.getPreserveOnRefreshUIs().put(windowName, uiId);
+ }
+ }
+
+ return ui;
+ }
+
/**
* Generates the initial UIDL message that can e.g. be included in a html
* page to avoid a separate round trip just for getting the UIDL.
diff --git a/server/src/com/vaadin/server/BootstrapFragmentResponse.java b/server/src/com/vaadin/server/BootstrapFragmentResponse.java
index 0269d1cfc0..8fc3183a7c 100644
--- a/server/src/com/vaadin/server/BootstrapFragmentResponse.java
+++ b/server/src/com/vaadin/server/BootstrapFragmentResponse.java
@@ -52,11 +52,14 @@ public class BootstrapFragmentResponse extends BootstrapResponse {
* @param fragmentNodes
* a mutable list containing the DOM nodes that will make up the
* application HTML
+ * @param uiProvider
+ * the UI provider for the bootstrap
*/
public BootstrapFragmentResponse(BootstrapHandler handler,
VaadinRequest request, VaadinSession session,
- Class<? extends UI> uiClass, List<Node> fragmentNodes) {
- super(handler, request, session, uiClass);
+ Class<? extends UI> uiClass, List<Node> fragmentNodes,
+ UIProvider uiProvider) {
+ super(handler, request, session, uiClass, uiProvider);
this.fragmentNodes = fragmentNodes;
}
diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java
index 7e4fd653bf..8721550a41 100644
--- a/server/src/com/vaadin/server/BootstrapHandler.java
+++ b/server/src/com/vaadin/server/BootstrapHandler.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -115,10 +116,30 @@ public abstract class BootstrapHandler implements RequestHandler {
VaadinResponse response) throws IOException {
try {
- Class<? extends UI> uiClass = session.getUIClass(request);
+ List<UIProvider> uiProviders = request.getVaadinService()
+ .getUIProviders(session);
+
+ // Find UI provider and UI class
+ Class<? extends UI> uiClass = null;
+ UIProvider provider = null;
+ for (UIProvider p : uiProviders) {
+ uiClass = p.getUIClass(request);
+ // If we found something
+ if (uiClass != null) {
+ provider = p;
+ break;
+ }
+ }
+
+ if (provider == null) {
+ // Can't generate bootstrap if no UI provider matches
+ return false;
+ }
+
+ BootstrapContext context = new BootstrapContext(response,
+ new BootstrapFragmentResponse(this, request, session,
+ uiClass, new ArrayList<Node>(), provider));
- BootstrapContext context = createContext(request, response,
- session, uiClass);
setupMainDiv(context);
BootstrapFragmentResponse fragmentResponse = context
@@ -148,7 +169,8 @@ public abstract class BootstrapHandler implements RequestHandler {
Document document = Document.createShell("");
BootstrapPageResponse pageResponse = new BootstrapPageResponse(
this, request, context.getVaadinSession(),
- context.getUIClass(), document, headers);
+ context.getUIClass(), document, headers,
+ fragmentResponse.getUIProvider());
List<Node> fragmentNodes = fragmentResponse.getFragmentNodes();
Element body = document.body();
for (Node node : fragmentNodes) {
@@ -223,9 +245,8 @@ public abstract class BootstrapHandler implements RequestHandler {
head.appendElement("meta").attr("http-equiv", "X-UA-Compatible")
.attr("content", "chrome=1");
- String title = context.getVaadinSession()
- .getUiProvider(context.getRequest(), context.getUIClass())
- .getPageTitle(context.getRequest(), context.getUIClass());
+ String title = response.getUIProvider().getPageTitle(
+ context.getRequest(), context.getUIClass());
if (title != null) {
head.appendElement("title").appendText(title);
}
@@ -250,15 +271,6 @@ public abstract class BootstrapHandler implements RequestHandler {
body.addClass(ApplicationConstants.GENERATED_BODY_CLASSNAME);
}
- private BootstrapContext createContext(VaadinRequest request,
- VaadinResponse response, VaadinSession application,
- Class<? extends UI> uiClass) {
- BootstrapContext context = new BootstrapContext(response,
- new BootstrapFragmentResponse(this, request, application,
- uiClass, new ArrayList<Node>()));
- return context;
- }
-
protected String getMainDivStyle(BootstrapContext context) {
return null;
}
@@ -276,8 +288,7 @@ public abstract class BootstrapHandler implements RequestHandler {
public String getWidgetsetForUI(BootstrapContext context) {
VaadinRequest request = context.getRequest();
- String widgetset = context.getVaadinSession()
- .getUiProvider(context.getRequest(), context.getUIClass())
+ String widgetset = context.getBootstrapResponse().getUIProvider()
.getWidgetset(context.getRequest(), context.getUIClass());
if (widgetset == null) {
widgetset = request.getVaadinService().getConfiguredWidgetset(
@@ -399,9 +410,9 @@ public abstract class BootstrapHandler implements RequestHandler {
throws JSONException, PaintException {
JSONObject appConfig = new JSONObject();
- if (context.getThemeName() != null) {
- appConfig.put("themeUri",
- getThemeUri(context, context.getThemeName()));
+ String themeName = context.getThemeName();
+ if (themeName != null) {
+ appConfig.put("themeUri", getThemeUri(context, themeName));
}
JSONObject versionInfo = new JSONObject();
@@ -412,8 +423,13 @@ public abstract class BootstrapHandler implements RequestHandler {
appConfig.put("initialPath", context.getRequest().getRequestPathInfo());
- Map<String, String[]> parameterMap = context.getRequest()
- .getParameterMap();
+ Map<String, String[]> parameterMap = new HashMap<String, String[]>(
+ context.getRequest().getParameterMap());
+
+ // Include theme as a fake initial param so that UI can know its theme
+ // for serving CustomLayout templates
+ parameterMap.put("theme", new String[] { themeName });
+
appConfig.put("initialParams", parameterMap);
return appConfig;
@@ -500,8 +516,7 @@ public abstract class BootstrapHandler implements RequestHandler {
* @return
*/
public String getThemeName(BootstrapContext context) {
- return context.getVaadinSession()
- .getUiProvider(context.getRequest(), context.getUIClass())
+ return context.getBootstrapResponse().getUIProvider()
.getTheme(context.getRequest(), context.getUIClass());
}
diff --git a/server/src/com/vaadin/server/BootstrapPageResponse.java b/server/src/com/vaadin/server/BootstrapPageResponse.java
index 72bc2163e6..8a85765e97 100644
--- a/server/src/com/vaadin/server/BootstrapPageResponse.java
+++ b/server/src/com/vaadin/server/BootstrapPageResponse.java
@@ -55,12 +55,14 @@ public class BootstrapPageResponse extends BootstrapResponse {
* the DOM document making up the HTML page
* @param headers
* a map into which header data can be added
+ * @param uiProvider
+ * the UI provider for the bootstrap
*/
public BootstrapPageResponse(BootstrapHandler handler,
VaadinRequest request, VaadinSession session,
Class<? extends UI> uiClass, Document document,
- Map<String, Object> headers) {
- super(handler, request, session, uiClass);
+ Map<String, Object> headers, UIProvider uiProvider) {
+ super(handler, request, session, uiClass, uiProvider);
this.headers = headers;
this.document = document;
}
diff --git a/server/src/com/vaadin/server/BootstrapResponse.java b/server/src/com/vaadin/server/BootstrapResponse.java
index 86b37de22e..c6e5fdc2ad 100644
--- a/server/src/com/vaadin/server/BootstrapResponse.java
+++ b/server/src/com/vaadin/server/BootstrapResponse.java
@@ -31,6 +31,7 @@ public abstract class BootstrapResponse extends EventObject {
private final VaadinRequest request;
private final VaadinSession session;
private final Class<? extends UI> uiClass;
+ private final UIProvider uiProvider;
/**
* Creates a new bootstrap event.
@@ -44,13 +45,17 @@ public abstract class BootstrapResponse extends EventObject {
* the session for which the bootstrap page should be generated
* @param uiClass
* the class of the UI that will be displayed on the page
+ * @param uiProvider
+ * the UI provider for the bootstrap
*/
public BootstrapResponse(BootstrapHandler handler, VaadinRequest request,
- VaadinSession session, Class<? extends UI> uiClass) {
+ VaadinSession session, Class<? extends UI> uiClass,
+ UIProvider uiProvider) {
super(handler);
this.request = request;
this.session = session;
this.uiClass = uiClass;
+ this.uiProvider = uiProvider;
}
/**
@@ -95,4 +100,14 @@ public abstract class BootstrapResponse extends EventObject {
return uiClass;
}
+ /**
+ * Gets the UI provider that is used to provide information about the
+ * bootstapped UI.
+ *
+ * @return the UI provider
+ */
+ public UIProvider getUIProvider() {
+ return uiProvider;
+ }
+
}
diff --git a/server/src/com/vaadin/server/CommunicationManager.java b/server/src/com/vaadin/server/CommunicationManager.java
index e4029a847a..7e55396592 100644
--- a/server/src/com/vaadin/server/CommunicationManager.java
+++ b/server/src/com/vaadin/server/CommunicationManager.java
@@ -17,6 +17,7 @@
package com.vaadin.server;
import java.io.InputStream;
+import java.net.MalformedURLException;
import java.net.URL;
import javax.servlet.ServletContext;
@@ -79,8 +80,14 @@ public class CommunicationManager extends AbstractCommunicationManager {
// don't use server and port in uri. It may cause problems with
// some
// virtual server configurations which lose the server name
- VaadinSession session = context.getVaadinSession();
- URL url = session.getURL();
+ URL url;
+
+ try {
+ url = context.getRequest().getVaadinService()
+ .getApplicationUrl(context.getRequest());
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
String appUrl = url.getPath();
if (appUrl.endsWith("/")) {
appUrl = appUrl.substring(0, appUrl.length() - 1);
diff --git a/server/src/com/vaadin/server/LegacyVaadinPortlet.java b/server/src/com/vaadin/server/LegacyVaadinPortlet.java
index de970d5c17..113cae6bf7 100644
--- a/server/src/com/vaadin/server/LegacyVaadinPortlet.java
+++ b/server/src/com/vaadin/server/LegacyVaadinPortlet.java
@@ -87,7 +87,7 @@ public class LegacyVaadinPortlet extends VaadinPortlet {
private void onVaadinSessionStarted(VaadinPortletRequest request,
VaadinPortletSession session) throws PortletException {
- session.addUIProvider(provider);
+ getVaadinService().addUIProvider(session, provider);
}
protected boolean shouldCreateApplication(PortletRequest request) {
diff --git a/server/src/com/vaadin/server/LegacyVaadinServlet.java b/server/src/com/vaadin/server/LegacyVaadinServlet.java
index 69655eba34..18911dc96e 100644
--- a/server/src/com/vaadin/server/LegacyVaadinServlet.java
+++ b/server/src/com/vaadin/server/LegacyVaadinServlet.java
@@ -92,7 +92,7 @@ public class LegacyVaadinServlet extends VaadinServlet {
private void onVaadinSessionStarted(VaadinRequest request,
VaadinSession session) throws ServletException {
- session.addUIProvider(provider);
+ getVaadinService().addUIProvider(session, provider);
}
}
diff --git a/server/src/com/vaadin/server/ServletPortletHelper.java b/server/src/com/vaadin/server/ServletPortletHelper.java
index efa3c62f6e..45c91d1970 100644
--- a/server/src/com/vaadin/server/ServletPortletHelper.java
+++ b/server/src/com/vaadin/server/ServletPortletHelper.java
@@ -123,13 +123,13 @@ class ServletPortletHelper implements Serializable {
.getInitParameters().getProperty(VaadinSession.UI_PARAMETER);
if (uiProperty != null) {
verifyUIClass(uiProperty, vaadinService.getClassLoader());
- session.addUIProvider(new DefaultUIProvider());
+ vaadinService.addUIProvider(session, new DefaultUIProvider());
}
}
- public static void checkUiProviders(VaadinSession session)
- throws ServiceException {
- if (session.getUIProviders().isEmpty()) {
+ public static void checkUiProviders(VaadinSession session,
+ VaadinService vaadinService) throws ServiceException {
+ if (vaadinService.getUIProviders(session).isEmpty()) {
throw new ServiceException(
"No UIProvider has been added and there is no \""
+ VaadinSession.UI_PARAMETER + "\" init parameter.");
diff --git a/server/src/com/vaadin/server/VaadinPortlet.java b/server/src/com/vaadin/server/VaadinPortlet.java
index 83d152d653..5849d77c4d 100644
--- a/server/src/com/vaadin/server/VaadinPortlet.java
+++ b/server/src/com/vaadin/server/VaadinPortlet.java
@@ -246,6 +246,20 @@ public class VaadinPortlet extends GenericPortlet implements Constants {
throws ServiceException {
return new VaadinPortletSession();
}
+
+ @Override
+ public String getServiceName() {
+ return getPortlet().getPortletName();
+ }
+
+ /**
+ * Always preserve UIs in portlets to make portlet actions work.
+ */
+ @Override
+ public boolean preserveUIOnRefresh(VaadinRequest request, UI ui,
+ UIProvider provider) {
+ return true;
+ }
}
public static class VaadinHttpAndPortletRequest extends
@@ -574,9 +588,6 @@ public class VaadinPortlet extends GenericPortlet implements Constants {
if (vaadinSession == null) {
return;
}
- VaadinSession.setCurrent(vaadinSession);
- request.setAttribute(VaadinSession.class.getName(),
- vaadinSession);
PortletCommunicationManager communicationManager = (PortletCommunicationManager) vaadinSession
.getCommunicationManager();
@@ -601,32 +612,8 @@ public class VaadinPortlet extends GenericPortlet implements Constants {
// Finds the right UI
UI uI = null;
- vaadinSession.getLock().lock();
- try {
- switch (requestType) {
- case RENDER:
- case ACTION:
- // Both action requests and render requests are ok
- // without a UI as they render the initial HTML
- // and then do a second request
- uI = vaadinSession.getUIForRequest(vaadinRequest);
- break;
- case BROWSER_DETAILS:
- // Should not try to find a UI here as the
- // combined request details might change the UI
- break;
- case FILE_UPLOAD:
- // no window
- break;
- case APP:
- // Not related to any UI
- break;
- default:
- uI = vaadinSession.getUIForRequest(vaadinRequest);
- }
- // if window not found, not a problem - use null
- } finally {
- vaadinSession.getLock().unlock();
+ if (requestType == RequestType.UIDL) {
+ uI = getVaadinService().findUI(vaadinRequest);
}
// TODO Should this happen before or after the transaction
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java
index 766ae47fdb..e7bf14e258 100644
--- a/server/src/com/vaadin/server/VaadinService.java
+++ b/server/src/com/vaadin/server/VaadinService.java
@@ -23,7 +23,10 @@ import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Locale;
import java.util.ServiceLoader;
@@ -32,8 +35,10 @@ import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import com.vaadin.LegacyApplication;
+import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.event.EventRouter;
import com.vaadin.server.VaadinSession.SessionStartEvent;
+import com.vaadin.shared.ui.ui.UIConstants;
import com.vaadin.ui.UI;
import com.vaadin.util.CurrentInstance;
import com.vaadin.util.ReflectTools;
@@ -48,6 +53,69 @@ import com.vaadin.util.ReflectTools;
*/
public abstract class VaadinService implements Serializable {
+ /**
+ * Service specific data that is stored in VaadinSession separately for each
+ * VaadinService using that particular session.
+ *
+ * @author Vaadin Ltd
+ */
+ public static class VaadinServiceData {
+ private final VaadinService vaadinService;
+ private LinkedList<UIProvider> uiProviders = new LinkedList<UIProvider>();
+
+ /**
+ * Create a new service data object for the given Vaadin service
+ *
+ * @param vaadinService
+ * the Vaadin service to which the data belongs
+ */
+ public VaadinServiceData(VaadinService vaadinService) {
+ this.vaadinService = vaadinService;
+ }
+
+ /**
+ * Gets a list of all the UI providers registered for a particular
+ * Vaadin service
+ *
+ * @see #addUIProvider(UIProvider)
+ *
+ * @return and unmodifiable list of UI providers
+ */
+ public List<UIProvider> getUIProviders() {
+ return Collections.unmodifiableList(uiProviders);
+ }
+
+ /**
+ * Adds a UI provider for a Vaadin service.
+ *
+ * @param uiProvider
+ * the UI provider to add
+ */
+ public void addUIProvider(UIProvider uiProvider) {
+ uiProviders.addFirst(uiProvider);
+ }
+
+ /**
+ * Removes a UI provider from a Vaadin service.
+ *
+ * @param uiProvider
+ * the UI provider to remove
+ */
+ public void removeUIProvider(UIProvider uiProvider) {
+ uiProviders.remove(uiProvider);
+ }
+
+ /**
+ * Gets the Vaadin service that this data belongs to.
+ *
+ * @return the Vaadin service that htis data belongs to
+ */
+ public VaadinService getVaadinService() {
+ return vaadinService;
+ }
+
+ }
+
private static final Method SESSION_INIT_METHOD = ReflectTools.findMethod(
VaadinSessionInitializationListener.class,
"vaadinSessionInitialized", VaadinSessionInitializeEvent.class);
@@ -309,7 +377,26 @@ public abstract class VaadinService implements Serializable {
*/
public VaadinSession findVaadinSession(VaadinRequest request)
throws ServiceException, SessionExpiredException {
+ VaadinSession vaadinSession = findOrCreateVaadinSession(request);
+ if (vaadinSession == null) {
+ return null;
+ }
+ if (!vaadinSession.hasVaadinServiceData(this)) {
+ vaadinSession.addVaadinServiceData(new VaadinServiceData(this));
+
+ ServletPortletHelper.initDefaultUIProvider(vaadinSession, this);
+
+ onVaadinSessionStarted(request, vaadinSession);
+ }
+
+ VaadinSession.setCurrent(vaadinSession);
+ request.setAttribute(VaadinSession.class.getName(), vaadinSession);
+
+ return vaadinSession;
+ }
+ private VaadinSession findOrCreateVaadinSession(VaadinRequest request)
+ throws SessionExpiredException, ServiceException {
boolean requestCanCreateSession = requestCanCreateSession(request);
/* Find an existing session for this request. */
@@ -360,9 +447,6 @@ public abstract class VaadinService implements Serializable {
throws ServiceException {
VaadinSession session = createVaadinSession(request);
- ServletPortletHelper.initDefaultUIProvider(session, this);
-
- session.setVaadinService(this);
session.storeInSession(request.getWrappedSession());
URL applicationUrl;
@@ -379,8 +463,6 @@ public abstract class VaadinService implements Serializable {
getDeploymentConfiguration(),
createCommunicationManager(session)));
- onVaadinSessionStarted(request, session);
-
return session;
}
@@ -430,7 +512,7 @@ public abstract class VaadinService implements Serializable {
eventRouter.fireEvent(new VaadinSessionInitializeEvent(this, session,
request));
- ServletPortletHelper.checkUiProviders(session);
+ ServletPortletHelper.checkUiProviders(session, this);
}
private void closeSession(VaadinSession vaadinSession,
@@ -551,4 +633,106 @@ public abstract class VaadinService implements Serializable {
return CurrentInstance.get(VaadinResponse.class);
}
+ /**
+ * Gets a unique name for this service. The name should be unique among
+ * different services of the same type but the same for corresponding
+ * instances running in different JVMs in a cluster. This is typically based
+ * on e.g. the configured servlet's or portlet's name.
+ *
+ * @return the unique name of this service instance.
+ */
+ public abstract String getServiceName();
+
+ /**
+ * Gets all the UI providers from a session that are configured for this
+ * service.
+ *
+ * @param session
+ * the Vaadin session to get the UI providers from
+ * @return an unmodifiable list of UI providers
+ */
+ public List<UIProvider> getUIProviders(VaadinSession session) {
+ return session.getVaadinServiceData(this).getUIProviders();
+ }
+
+ /**
+ * Finds the {@link UI} that belongs to the provided request. This is
+ * generally only supported for UIDL requests as other request types are not
+ * related to any particular UI or have the UI information encoded in a
+ * non-standard way. The returned UI is also set as the current UI (
+ * {@link UI#setCurrent(UI)}).
+ *
+ * @param request
+ * the request for which a UI is desired
+ * @return the UI belonging to the request
+ *
+ */
+ public UI findUI(VaadinRequest request) {
+ VaadinSession session = VaadinSession.getForSession(request
+ .getWrappedSession());
+
+ // Get UI id from the request
+ String uiIdString = request.getParameter(UIConstants.UI_ID_PARAMETER);
+ int uiId = Integer.parseInt(uiIdString);
+
+ // Get lock before accessing data in session
+ session.getLock().lock();
+ try {
+ UI ui = session.getUIById(uiId);
+
+ UI.setCurrent(ui);
+ return ui;
+ } finally {
+ session.getLock().unlock();
+ }
+ }
+
+ /**
+ * Adds a UI provider to a Vaadin session and associates it with this Vaadin
+ * service.
+ *
+ * @param vaadinSession
+ * the Vaadin session to store the UI provider in
+ * @param uiProvider
+ * the UI provider that should be added
+ */
+ public void addUIProvider(VaadinSession vaadinSession, UIProvider uiProvider) {
+ vaadinSession.getVaadinServiceData(this).addUIProvider(uiProvider);
+ }
+
+ /**
+ * Removes a UI provider association for this service from a Vaadin session.
+ *
+ * @param vaadinSession
+ * the Vaadin session where the UI provider is stored
+ * @param uiProvider
+ * the UI provider that should be removed
+ */
+ public void removeUIProvider(VaadinSession vaadinSession,
+ UIProvider uiProvider) {
+ vaadinSession.getVaadinServiceData(this).removeUIProvider(uiProvider);
+ }
+
+ /**
+ * Check if the given UI should be associated with the
+ * <code>window.name</code> so that it can be re-used if the browser window
+ * is reloaded. This is typically determined by the UI provider which
+ * typically checks the @{@link PreserveOnRefresh} annotation but UI
+ * providers and ultimately VaadinService implementations may choose to
+ * override the defaults.
+ *
+ * @param request
+ * the Vaadin request used to initialize the UI
+ * @param ui
+ * the UI for which the preserve setting should be returned
+ * @param provider
+ * the UI provider responsible for the UI
+ * @return <code>true</code> if the UI should be preserved on refresh;
+ * <code>false</code> if a new UI instance should be initialized on
+ * refreshed.
+ */
+ public boolean preserveUIOnRefresh(VaadinRequest request, UI ui,
+ UIProvider provider) {
+ return provider.isPreservedOnRefresh(request, ui.getClass());
+ }
}
diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java
index 518d26070b..60f385146a 100644
--- a/server/src/com/vaadin/server/VaadinServlet.java
+++ b/server/src/com/vaadin/server/VaadinServlet.java
@@ -220,6 +220,11 @@ public class VaadinServlet extends HttpServlet implements Constants {
throws ServiceException {
return new VaadinServletSession();
}
+
+ @Override
+ public String getServiceName() {
+ return getServlet().getServletName();
+ }
}
private static class AbstractApplicationServletWrapper implements Callback {
@@ -431,8 +436,6 @@ public class VaadinServlet extends HttpServlet implements Constants {
if (vaadinSession == null) {
return;
}
- request.setAttribute(VaadinSession.class.getName(), vaadinSession);
- VaadinSession.setCurrent(vaadinSession);
CommunicationManager communicationManager = (CommunicationManager) vaadinSession
.getCommunicationManager();
@@ -458,7 +461,7 @@ public class VaadinServlet extends HttpServlet implements Constants {
response);
return;
} else if (requestType == RequestType.UIDL) {
- UI uI = vaadinSession.getUIForRequest(request);
+ UI uI = getVaadinService().findUI(request);
if (uI == null) {
throw new ServletException(ERROR_NO_UI_FOUND);
}
diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java
index c3699bacfa..0bf5f8616b 100644
--- a/server/src/com/vaadin/server/VaadinSession.java
+++ b/server/src/com/vaadin/server/VaadinSession.java
@@ -25,7 +25,6 @@ import java.util.Collections;
import java.util.EventObject;
import java.util.HashMap;
import java.util.LinkedList;
-import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.locks.Lock;
@@ -38,12 +37,12 @@ import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import com.vaadin.LegacyApplication;
+import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.ConverterFactory;
import com.vaadin.data.util.converter.DefaultConverterFactory;
import com.vaadin.event.EventRouter;
-import com.vaadin.server.VaadinRequest.BrowserDetails;
-import com.vaadin.shared.ui.ui.UIConstants;
+import com.vaadin.server.VaadinService.VaadinServiceData;
import com.vaadin.ui.AbstractField;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
@@ -180,8 +179,6 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
private final EventRouter eventRouter = new EventRouter();
- private List<UIProvider> uiProviders = new LinkedList<UIProvider>();
-
private GlobalResourceHandler globalResourceHandler;
protected WebBrowser browser = new WebBrowser();
@@ -196,7 +193,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
private final Map<String, Object> attributes = new HashMap<String, Object>();
- private VaadinService vaadinService;
+ private Map<String, VaadinServiceData> serviceData = new HashMap<String, VaadinServiceData>();
/**
* @see javax.servlet.http.HttpSessionBindingListener#valueBound(HttpSessionBindingEvent)
@@ -213,22 +210,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
public void valueUnbound(HttpSessionBindingEvent event) {
// If we are going to be unbound from the session, the session must be
// closing
- if (vaadinService != null) {
- vaadinService.fireSessionDestroy(this);
+ // Notify all services that have used this session.
+ for (VaadinServiceData vaadinServiceData : serviceData.values()) {
+ vaadinServiceData.getVaadinService().fireSessionDestroy(this);
}
}
/**
- * Sets the Vaadin service to which this session belongs.
- *
- * @param vaadinService
- * the Vaadin service.
- */
- public void setVaadinService(VaadinService vaadinService) {
- this.vaadinService = vaadinService;
- }
-
- /**
* Get the web browser associated with this session.
*
* @return
@@ -609,137 +597,6 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
}
/**
- * Gets the UI class for a request for which no UI is already known. This
- * method is called when the framework processes a request that does not
- * originate from an existing UI instance. This typically happens when a
- * host page is requested.
- *
- * @param request
- * the Vaadin request for which a UI is needed
- * @return a UI instance to use for the request
- *
- * @see UI
- * @see VaadinRequest#getBrowserDetails()
- *
- * @since 7.0
- *
- * @deprecated might be refactored or removed before 7.0.0
- */
- @Deprecated
- public Class<? extends UI> getUIClass(VaadinRequest request) {
- UIProvider uiProvider = getUiProvider(request, null);
- return uiProvider.getUIClass(request);
- }
-
- /**
- * Creates an UI instance for a request for which no UI is already known.
- * This method is called when the framework processes a request that does
- * not originate from an existing UI instance. This typically happens when a
- * host page is requested.
- *
- * @param request
- * @param uiClass
- * @return
- *
- * @deprecated might be refactored or removed before 7.0.0
- */
- @Deprecated
- protected <T extends UI> T createUIInstance(VaadinRequest request,
- Class<T> uiClass) {
- UIProvider uiProvider = getUiProvider(request, uiClass);
- return uiClass.cast(uiProvider.createInstance(request, uiClass));
- }
-
- /**
- * Gets the {@link UIProvider} that should be used for a request. The
- * selection can further be restricted by also requiring the UI provider to
- * support a specific UI class.
- *
- * @see UIProvider
- * @see #addUIProvider(UIProvider)
- *
- * @param request
- * the request for which to get an UI provider
- * @param uiClass
- * the UI class for which a provider is required, or
- * <code>null</code> to use the first UI provider supporting the
- * request.
- * @return an UI provider supporting the request (and the UI class if
- * provided).
- *
- * @since 7.0.0
- *
- * @deprecated might be refactored or removed before 7.0.0
- */
- @Deprecated
- public UIProvider getUiProvider(VaadinRequest request, Class<?> uiClass) {
- UIProvider provider = (UIProvider) request
- .getAttribute(UIProvider.class.getName());
- if (provider != null) {
- // Cached provider found, verify that it's a sensible selection
- Class<? extends UI> providerClass = provider.getUIClass(request);
- if (uiClass == null && providerClass != null) {
- // Use it if it gives any answer if no specific class is
- // required
- return provider;
- } else if (uiClass == providerClass) {
- // Use it if it gives the expected UI class
- return provider;
- } else {
- // Don't keep it cached if it doesn't match the expectations
- request.setAttribute(UIProvider.class.getName(), null);
- }
- }
-
- // Iterate all current providers if no matching cached provider found
- provider = doGetUiProvider(request, uiClass);
-
- // Cache the found provider
- request.setAttribute(UIProvider.class.getName(), provider);
-
- return provider;
- }
-
- /**
- * @param request
- * @param uiClass
- * @return
- *
- * @deprecated might be refactored or removed before 7.0.0
- */
- @Deprecated
- private UIProvider doGetUiProvider(VaadinRequest request, Class<?> uiClass) {
- int providersSize = uiProviders.size();
- if (providersSize == 0) {
- throw new IllegalStateException("There are no UI providers");
- }
-
- for (int i = providersSize - 1; i >= 0; i--) {
- UIProvider provider = uiProviders.get(i);
-
- Class<? extends UI> providerClass = provider.getUIClass(request);
- // If we found something
- if (providerClass != null) {
- if (uiClass == null) {
- // Not looking for anything particular -> anything is ok
- return provider;
- } else if (providerClass == uiClass) {
- // Looking for a specific provider -> only use if matching
- return provider;
- } else {
- getLogger().warning(
- "Mismatching UI classes. Expected " + uiClass
- + " but got " + providerClass + " from "
- + provider);
- // Continue looking
- }
- }
- }
-
- throw new RuntimeException("No UI provider found for request");
- }
-
- /**
* Adds a request handler to this session. Request handlers can be added to
* provide responses to requests that are not handled by the default
* functionality of the framework.
@@ -828,175 +685,6 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
CurrentInstance.setInheritable(VaadinSession.class, session);
}
- public void addUIProvider(UIProvider uIProvider) {
- uiProviders.add(uIProvider);
- }
-
- public void removeUIProvider(UIProvider uIProvider) {
- uiProviders.remove(uIProvider);
- }
-
- /**
- * Finds the {@link UI} to which a particular request belongs. If the
- * request originates from an existing UI, that UI is returned. In other
- * cases, the method attempts to create and initialize a new UI and might
- * throw a {@link UIRequiresMoreInformationException} if all required
- * information is not available.
- * <p>
- * Please note that this method can also return a newly created
- * <code>UI</code> which has not yet been initialized. You can use
- * {@link #isUIInitPending(int)} with the UI's id ( {@link UI#getUIId()} to
- * check whether the initialization is still pending.
- * </p>
- *
- * @param request
- * the request for which a UI is desired
- * @return a UI belonging to the request
- *
- * @see #createUI(VaadinRequest)
- *
- * @since 7.0
- *
- * @deprecated might be refactored or removed before 7.0.0
- */
- @Deprecated
- public UI getUIForRequest(VaadinRequest request) {
- UI uI = UI.getCurrent();
- if (uI != null) {
- return uI;
- }
- Integer uiId = getUIId(request);
- getLock().lock();
- try {
- uI = uIs.get(uiId);
-
- if (uI == null) {
- uI = findExistingUi(request);
- }
-
- } finally {
- getLock().unlock();
- }
-
- UI.setCurrent(uI);
-
- return uI;
- }
-
- /**
- * @param request
- * @return
- *
- * @deprecated might be refactored or removed before 7.0.0
- */
- @Deprecated
- private UI findExistingUi(VaadinRequest request) {
- // Check if some UI provider has an existing UI available
- for (int i = uiProviders.size() - 1; i >= 0; i--) {
- UIProvider provider = uiProviders.get(i);
- UI existingUi = provider.getExistingUI(request);
- if (existingUi != null) {
- return existingUi;
- }
- }
-
- BrowserDetails browserDetails = request.getBrowserDetails();
- boolean hasBrowserDetails = browserDetails != null
- && browserDetails.getUriFragment() != null;
-
- if (hasBrowserDetails && !retainOnRefreshUIs.isEmpty()) {
- // Check for a known UI
-
- @SuppressWarnings("null")
- String windowName = browserDetails.getWindowName();
- Integer retainedUIId = retainOnRefreshUIs.get(windowName);
-
- if (retainedUIId != null) {
- Class<? extends UI> expectedUIClass = getUIClass(request);
- UI retainedUI = uIs.get(retainedUIId);
- // We've had the same UI instance in a window with this
- // name, but should we still use it?
- if (retainedUI.getClass() == expectedUIClass) {
- return retainedUI;
- } else {
- getLogger().info(
- "Not using retained UI in " + windowName
- + " because retained UI was of type "
- + retainedUIId.getClass() + " but "
- + expectedUIClass
- + " is expected for the request.");
- }
- }
- }
-
- return null;
- }
-
- /**
- * @param request
- * @return
- *
- * @deprecated might be refactored or removed before 7.0.0
- */
- @Deprecated
- public UI createUI(VaadinRequest request) {
- Class<? extends UI> uiClass = getUIClass(request);
-
- UI ui = createUIInstance(request, uiClass);
-
- // Initialize some fields for a newly created UI
- if (ui.getSession() == null) {
- ui.setSession(this);
- }
- // Get the next id
- Integer uiId = Integer.valueOf(nextUIId++);
-
- uIs.put(uiId, ui);
-
- // Set thread local here so it is available in init
- UI.setCurrent(ui);
-
- ui.doInit(request, uiId.intValue());
-
- if (getUiProvider(request, uiClass).isPreservedOnRefresh(request,
- uiClass)) {
- // Remember this UI
- String windowName = request.getBrowserDetails().getWindowName();
- if (windowName == null) {
- getLogger().warning(
- "There is no window.name available for UI " + uiClass
- + " that should be preserved.");
- } else {
- retainOnRefreshUIs.put(windowName, uiId);
- }
- }
-
- return ui;
- }
-
- /**
- * Internal helper to finds the UI id for a request.
- *
- * @param request
- * the request to get the UI id for
- * @return a UI id, or <code>null</code> if no UI id is defined
- *
- * @since 7.0
- *
- * @deprecated might be refactored or removed before 7.0.0
- */
- @Deprecated
- private static Integer getUIId(VaadinRequest request) {
- if (request instanceof CombinedRequest) {
- // Combined requests has the uiId parameter in the second request
- CombinedRequest combinedRequest = (CombinedRequest) request;
- request = combinedRequest.getSecondRequest();
- }
- String uiIdString = request.getParameter(UIConstants.UI_ID_PARAMETER);
- Integer uiId = uiIdString == null ? null : new Integer(uiIdString);
- return uiId;
- }
-
/**
* Gets all the UIs of this session. This includes UIs that have been
* requested but not yet initialized. UIs that receive no heartbeat requests
@@ -1239,10 +927,6 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
return globalResourceHandler;
}
- public Collection<UIProvider> getUIProviders() {
- return Collections.unmodifiableCollection(uiProviders);
- }
-
/**
* Gets the lock that should be used to synchronize usage of data inside
* this session.
@@ -1360,4 +1044,98 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
}
}
+ /**
+ * Checks whether there this session has any Vaadin service data for a
+ * particular Vaadin service.
+ *
+ * @see #addVaadinServiceData(VaadinServiceData)
+ * @see VaadinServiceData
+ *
+ * @param vaadinService
+ * the Vaadin service to check for
+ * @return <code>true</code> if there is a Vaadin service data object for
+ * the passed Vaadin service; otherwise <code>false</code>
+ */
+ public boolean hasVaadinServiceData(VaadinService vaadinService) {
+ return getVaadinServiceData(vaadinService) != null;
+ }
+
+ /**
+ * Gets the data stored for the passed Vaadin service.
+ *
+ * @see #addVaadinServiceData(VaadinServiceData)
+ * @see VaadinServiceData
+ *
+ * @param vaadinService
+ * the Vaadin service to get the data for
+ * @return the Vaadin service data for the provided Vaadin service; or
+ * <code>null</code> if there is no data for the service
+ */
+ public VaadinServiceData getVaadinServiceData(VaadinService vaadinService) {
+ return serviceData.get(getServiceKey(vaadinService));
+ }
+
+ /**
+ * Adds Vaadin service specific data to this session.
+ *
+ * @see #getVaadinServiceData(VaadinService)
+ * @see VaadinServiceData
+ *
+ * @param serviceData
+ * the Vaadin service data to add
+ */
+ public void addVaadinServiceData(VaadinServiceData serviceData) {
+ VaadinService vaadinService = serviceData.getVaadinService();
+ assert !hasVaadinServiceData(vaadinService);
+
+ this.serviceData.put(getServiceKey(vaadinService), serviceData);
+ }
+
+ private static String getServiceKey(VaadinService vaadinService) {
+ String serviceKey = vaadinService.getClass().getName() + "."
+ + vaadinService.getServiceName();
+ return serviceKey;
+ }
+
+ /**
+ * Creates a new unique id for a UI.
+ *
+ * @return a unique UI id
+ */
+ public int getNextUIid() {
+ return nextUIId++;
+ }
+
+ /**
+ * Gets the mapping from <code>window.name</code> to UI id for UIs that are
+ * should be retained on refresh.
+ *
+ * @see VaadinService#preserveUIOnRefresh(VaadinRequest, UI, UIProvider)
+ * @see PreserveOnRefresh
+ *
+ * @return the mapping between window names and UI ids for this session.
+ */
+ public Map<String, Integer> getPreserveOnRefreshUIs() {
+ return retainOnRefreshUIs;
+ }
+
+ /**
+ * Adds an initialized UI to this session.
+ *
+ * @param ui
+ * the initialized UI to add.
+ */
+ public void addUI(UI ui) {
+ if (ui.getUIId() == -1) {
+ throw new IllegalArgumentException(
+ "Can not add an UI that has not been initialized.");
+ }
+ if (ui.getSession() != this) {
+ throw new IllegalArgumentException(
+ "The UI belongs to a different session");
+ }
+
+ uIs.put(Integer.valueOf(ui.getUIId()), ui);
+ }
+
}
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index 5beb80ffcd..0d9fcd2c0a 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -41,8 +41,10 @@ import com.vaadin.server.Page.BrowserWindowResizeListener;
import com.vaadin.server.PaintException;
import com.vaadin.server.PaintTarget;
import com.vaadin.server.Resource;
+import com.vaadin.server.UIProvider;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinRequest.BrowserDetails;
+import com.vaadin.server.VaadinService;
import com.vaadin.server.VaadinServlet;
import com.vaadin.server.VaadinSession;
import com.vaadin.shared.EventId;
@@ -66,10 +68,10 @@ import com.vaadin.util.ReflectTools;
* </p>
* <p>
* When a new UI instance is needed, typically because the user opens a URL in a
- * browser window which points to {@link VaadinServlet},
- * {@link VaadinSession#getUIForRequest(VaadinRequest)} is invoked to get a UI.
- * That method does by default create a UI according to the
- * {@value VaadinSession#UI_PARAMETER} parameter from web.xml.
+ * browser window which points to e.g. {@link VaadinServlet}, all
+ * {@link UIProvider}s registered to the current {@link VaadinSession} are
+ * queried for the UI class that should be used. The selection is by defaylt
+ * based on the {@value VaadinSession#UI_PARAMETER} parameter from web.xml.
* </p>
* <p>
* After a UI has been created by the application, it is initialized using
@@ -81,7 +83,7 @@ import com.vaadin.util.ReflectTools;
* </p>
*
* @see #init(VaadinRequest)
- * @see VaadinSession#createUI(VaadinRequest)
+ * @see UIProvider
*
* @since 7.0
*/
@@ -466,7 +468,7 @@ public abstract class UI extends AbstractComponentContainer implements
* which a request originates. A negative value indicates that the UI id has
* not yet been assigned by the Application.
*
- * @see VaadinSession#nextUIId
+ * @see VaadinSession#getNextUIid()
*/
private int uiId = -1;
@@ -748,8 +750,8 @@ public abstract class UI extends AbstractComponentContainer implements
* Gets the id of the UI, used to identify this UI within its application
* when processing requests. The UI id should be present in every request to
* the server that originates from this UI.
- * {@link VaadinSession#getUIForRequest(VaadinRequest)} uses this id to find
- * the route to which the request belongs.
+ * {@link VaadinService#findUI(VaadinRequest)} uses this id to find the
+ * route to which the request belongs.
*
* @return
*/
@@ -759,10 +761,7 @@ public abstract class UI extends AbstractComponentContainer implements
/**
* Adds a window as a subwindow inside this UI. To open a new browser window
- * or tab, you should instead use {@link open(Resource)} with an url
- * pointing to this application and ensure
- * {@link VaadinSession#createUI(VaadinRequest)} returns an appropriate UI
- * for the request.
+ * or tab, you should instead use a {@link UIProvider}.
*
* @param window
* @throws IllegalArgumentException
@@ -984,8 +983,9 @@ public abstract class UI extends AbstractComponentContainer implements
throw new IllegalStateException("UI id has already been defined");
}
this.uiId = uiId;
- theme = getSession().getUiProvider(request, getClass()).getTheme(
- request, getClass());
+
+ // Actual theme - used for finding CustomLayout templates
+ theme = request.getParameter("theme");
getPage().init(request);
diff --git a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java
index 1323e247d9..971102495d 100644
--- a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java
+++ b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java
@@ -35,11 +35,11 @@ import com.vaadin.server.DeploymentConfiguration;
import com.vaadin.server.LegacyVaadinServlet;
import com.vaadin.server.ServiceException;
import com.vaadin.server.UIProvider;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinServletRequest;
import com.vaadin.server.VaadinSession;
import com.vaadin.server.VaadinSessionInitializationListener;
import com.vaadin.server.VaadinSessionInitializeEvent;
-import com.vaadin.server.VaadinServletRequest;
-import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.TestBase;
import com.vaadin.ui.UI;
@@ -143,17 +143,19 @@ public class ApplicationRunnerServlet extends LegacyVaadinServlet {
try {
final Class<?> classToRun = getClassToRun();
if (UI.class.isAssignableFrom(classToRun)) {
- session.addUIProvider(new AbstractUIProvider() {
-
- @Override
- public Class<? extends UI> getUIClass(VaadinRequest request) {
- return (Class<? extends UI>) classToRun;
- }
- });
+ getVaadinService().addUIProvider(session,
+ new AbstractUIProvider() {
+ @Override
+ public Class<? extends UI> getUIClass(
+ VaadinRequest request) {
+ return (Class<? extends UI>) classToRun;
+ }
+ });
} else if (LegacyApplication.class.isAssignableFrom(classToRun)) {
// Avoid using own UIProvider for legacy Application
} else if (UIProvider.class.isAssignableFrom(classToRun)) {
- session.addUIProvider((UIProvider) classToRun.newInstance());
+ getVaadinService().addUIProvider(session,
+ (UIProvider) classToRun.newInstance());
} else {
throw new ServiceException(classToRun.getCanonicalName()
+ " is neither an Application nor a UI");