]> source.dussan.org Git - vaadin-framework.git/commitdiff
Refactor UIProvider management and fix multi-servlet (#9619, #9637)
authorLeif Åstrand <leif@vaadin.com>
Fri, 21 Sep 2012 10:21:18 +0000 (13:21 +0300)
committerLeif Åstrand <leif@vaadin.com>
Fri, 21 Sep 2012 10:21:31 +0000 (13:21 +0300)
16 files changed:
WebContent/WEB-INF/web.xml
server/src/com/vaadin/server/AbstractCommunicationManager.java
server/src/com/vaadin/server/BootstrapFragmentResponse.java
server/src/com/vaadin/server/BootstrapHandler.java
server/src/com/vaadin/server/BootstrapPageResponse.java
server/src/com/vaadin/server/BootstrapResponse.java
server/src/com/vaadin/server/CommunicationManager.java
server/src/com/vaadin/server/LegacyVaadinPortlet.java
server/src/com/vaadin/server/LegacyVaadinServlet.java
server/src/com/vaadin/server/ServletPortletHelper.java
server/src/com/vaadin/server/VaadinPortlet.java
server/src/com/vaadin/server/VaadinService.java
server/src/com/vaadin/server/VaadinServlet.java
server/src/com/vaadin/server/VaadinSession.java
server/src/com/vaadin/ui/UI.java
uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java

index d752b8eb334aa9c7568eba7578e0863e3558b270..d8a8066edc6e08edd1234c261808fc743a4ee8e3 100644 (file)
@@ -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>
index 49243a0589368e2d7e17afcdec4655fcc180b39c..eaef7485b3a06e695df5bcd0555e903f3061204c 100644 (file)
@@ -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.
index 0269d1cfc0834b974656acaa31c08415aabf01d3..8fc3183a7c0b7894871cd60c9b3c40445ef41c14 100644 (file)
@@ -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;
     }
 
index 7e4fd653bf85c0adac6a69e8d6d67b70cb217f4d..8721550a41dac9f1c3959c95931a54a4c0f8f697 100644 (file)
@@ -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());
     }
 
index 72bc2163e632f5b8b7ff2b1cdee9623c34ab6250..8a85765e971a42517b2f70d1237852dc9e125912 100644 (file)
@@ -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;
     }
index 86b37de22e85cc264f7456d7d73ccf0216aa5c73..c6e5fdc2addbd8e1366d70f764b48144620e0c80 100644 (file)
@@ -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;
+    }
+
 }
index e4029a847a24f691995eddfe4eb9b5bd709cb388..7e5539659236407e1b519ce5cb045c6f3cb6117d 100644 (file)
@@ -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);
index de970d5c17f80bd0554eca7da5b39b300077aa63..113cae6bf727784fa5873e8559129512937231b3 100644 (file)
@@ -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) {
index 69655eba34bffc3375c8a7f30a9030225461c56c..18911dc96e10783414be2ec0d640aaa6ac68e76a 100644 (file)
@@ -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);
     }
 
 }
index efa3c62f6efb6854e5de7a70af26e246d676427d..45c91d1970d3a1566e2ba682bacd0596890f8abc 100644 (file)
@@ -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.");
index 83d152d653d030df93b7eede0a86886aabb20afe..5849d77c4defe47586891000e011cfae43374ae1 100644 (file)
@@ -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
index 766ae47fdb56ee7dfbd220a3f2dc9127c4d01d94..e7bf14e2582917db52a0b430a2308b546a121667 100644 (file)
@@ -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());
+    }
 }
index 518d26070bb0b710873f63ce30e026a6bd9f40f6..60f385146aaf580134fd7db58a4128576bc95d3d 100644 (file)
@@ -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);
                 }
index c3699bacfaab67d789420b1f846c7504739f5871..0bf5f8616b3c4988a27e3a4e112fe557e4e80885 100644 (file)
@@ -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,21 +210,12 @@ 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.
      * 
@@ -608,137 +596,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
@@ -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);
+    }
+
 }
index 5beb80ffcdf050dcef2911cb39d086211a055740..0d9fcd2c0a95bb991ee9d2fb162207553f6ecdb0 100644 (file)
@@ -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);
 
index 1323e247d99f33327f008d29dc471b93a9ae7426..971102495d1c43786346c92615faaacfa819fdc2 100644 (file)
@@ -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");