<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>
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;
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());
}
}
+ 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.
* @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;
}
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;
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
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) {
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);
}
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;
}
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(
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();
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;
* @return
*/
public String getThemeName(BootstrapContext context) {
- return context.getVaadinSession()
- .getUiProvider(context.getRequest(), context.getUIClass())
+ return context.getBootstrapResponse().getUIProvider()
.getTheme(context.getRequest(), context.getUIClass());
}
* 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;
}
private final VaadinRequest request;
private final VaadinSession session;
private final Class<? extends UI> uiClass;
+ private final UIProvider uiProvider;
/**
* Creates a new bootstrap event.
* 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;
}
/**
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;
+ }
+
}
package com.vaadin.server;
import java.io.InputStream;
+import java.net.MalformedURLException;
import java.net.URL;
import javax.servlet.ServletContext;
// 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);
private void onVaadinSessionStarted(VaadinPortletRequest request,
VaadinPortletSession session) throws PortletException {
- session.addUIProvider(provider);
+ getVaadinService().addUIProvider(session, provider);
}
protected boolean shouldCreateApplication(PortletRequest request) {
private void onVaadinSessionStarted(VaadinRequest request,
VaadinSession session) throws ServletException {
- session.addUIProvider(provider);
+ getVaadinService().addUIProvider(session, provider);
}
}
.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.");
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
if (vaadinSession == null) {
return;
}
- VaadinSession.setCurrent(vaadinSession);
- request.setAttribute(VaadinSession.class.getName(),
- vaadinSession);
PortletCommunicationManager communicationManager = (PortletCommunicationManager) vaadinSession
.getCommunicationManager();
// 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
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;
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;
*/
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);
*/
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. */
throws ServiceException {
VaadinSession session = createVaadinSession(request);
- ServletPortletHelper.initDefaultUIProvider(session, this);
-
- session.setVaadinService(this);
session.storeInSession(request.getWrappedSession());
URL applicationUrl;
getDeploymentConfiguration(),
createCommunicationManager(session)));
- onVaadinSessionStarted(request, session);
-
return session;
}
eventRouter.fireEvent(new VaadinSessionInitializeEvent(this, session,
request));
- ServletPortletHelper.checkUiProviders(session);
+ ServletPortletHelper.checkUiProviders(session, this);
}
private void closeSession(VaadinSession vaadinSession,
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());
+ }
}
throws ServiceException {
return new VaadinServletSession();
}
+
+ @Override
+ public String getServiceName() {
+ return getServlet().getServletName();
+ }
}
private static class AbstractApplicationServletWrapper implements Callback {
if (vaadinSession == null) {
return;
}
- request.setAttribute(VaadinSession.class.getName(), vaadinSession);
- VaadinSession.setCurrent(vaadinSession);
CommunicationManager communicationManager = (CommunicationManager) vaadinSession
.getCommunicationManager();
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);
}
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;
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;
private final EventRouter eventRouter = new EventRouter();
- private List<UIProvider> uiProviders = new LinkedList<UIProvider>();
-
private GlobalResourceHandler globalResourceHandler;
protected WebBrowser browser = new WebBrowser();
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)
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.
*
}
- /**
- * 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
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
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.
}
}
+ /**
+ * 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);
+ }
+
}
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;
* </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
* </p>
*
* @see #init(VaadinRequest)
- * @see VaadinSession#createUI(VaadinRequest)
+ * @see UIProvider
*
* @since 7.0
*/
* 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;
* 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
*/
/**
* 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
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);
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;
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");