diff options
16 files changed, 227 insertions, 109 deletions
diff --git a/server/src/com/vaadin/server/AbstractCommunicationManager.java b/server/src/com/vaadin/server/AbstractCommunicationManager.java index 8ea0b88b74..b7b97cbefd 100644 --- a/server/src/com/vaadin/server/AbstractCommunicationManager.java +++ b/server/src/com/vaadin/server/AbstractCommunicationManager.java @@ -1279,7 +1279,7 @@ public abstract class AbstractCommunicationManager implements Serializable { stateType, uI.getConnectorTracker()); if (supportsDiffState) { connectorTracker.setDiffState(connector, - encodeResult.getEncodedValue()); + (JSONObject) encodeResult.getEncodedValue()); } return (JSONObject) encodeResult.getDiff(); } diff --git a/server/src/com/vaadin/server/CommunicationManager.java b/server/src/com/vaadin/server/CommunicationManager.java index f876e748f8..5f61079261 100644 --- a/server/src/com/vaadin/server/CommunicationManager.java +++ b/server/src/com/vaadin/server/CommunicationManager.java @@ -110,8 +110,9 @@ public class CommunicationManager extends AbstractCommunicationManager { @Override protected InputStream getThemeResourceAsStream(UI uI, String themeName, String resource) { - VaadinServletSession session = (VaadinServletSession) uI.getSession(); - ServletContext servletContext = session.getHttpSession() + VaadinServletService service = (VaadinServletService) uI.getSession() + .getService(); + ServletContext servletContext = service.getServlet() .getServletContext(); return servletContext.getResourceAsStream("/" + VaadinServlet.THEME_DIRECTORY_PATH + themeName + "/" diff --git a/server/src/com/vaadin/server/GAEVaadinServlet.java b/server/src/com/vaadin/server/GAEVaadinServlet.java index 6c9c1882ea..c68f25a282 100644 --- a/server/src/com/vaadin/server/GAEVaadinServlet.java +++ b/server/src/com/vaadin/server/GAEVaadinServlet.java @@ -361,11 +361,18 @@ public class GAEVaadinServlet extends VaadinServlet { * * @param request */ - private void cleanSession(HttpServletRequest request) { - HttpSession session = request.getSession(false); - if (session != null) { - session.removeAttribute(VaadinServletSession.class.getName()); + private void cleanSession(VaadinServletRequest request) { + // Should really be replaced with a session storage API... + WrappedSession wrappedSession = request.getWrappedSession(false); + if (wrappedSession == null) { + return; + } + VaadinServiceSession serviceSession = VaadinServiceSession + .getForSession(getService(), wrappedSession); + if (serviceSession == null) { + return; } + serviceSession.removeFromSession(getService()); } /** diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java index add32bf57b..c56d6caeb5 100644 --- a/server/src/com/vaadin/server/VaadinService.java +++ b/server/src/com/vaadin/server/VaadinService.java @@ -437,8 +437,10 @@ public abstract class VaadinService implements Serializable { * @throws ServletException * @throws MalformedURLException */ - protected abstract VaadinServiceSession createVaadinSession( - VaadinRequest request) throws ServiceException; + protected VaadinServiceSession createVaadinSession(VaadinRequest request) + throws ServiceException { + return new VaadinServiceSession(this); + } private void onVaadinSessionStarted(VaadinRequest request, VaadinServiceSession session) throws ServiceException { diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java index 7f664be6fb..9d1d79d8b1 100644 --- a/server/src/com/vaadin/server/VaadinServlet.java +++ b/server/src/com/vaadin/server/VaadinServlet.java @@ -232,7 +232,7 @@ public class VaadinServlet extends HttpServlet implements Constants { return; } - VaadinServletSession vaadinSession = null; + VaadinServiceSession vaadinSession = null; try { // If a duplicate "close application" URL is received for an @@ -254,8 +254,7 @@ public class VaadinServlet extends HttpServlet implements Constants { } // Find out the service session this request is related to - vaadinSession = (VaadinServletSession) getService() - .findVaadinSession(request); + vaadinSession = getService().findVaadinSession(request); if (vaadinSession == null) { return; } @@ -1173,26 +1172,6 @@ public class VaadinServlet extends HttpServlet implements Constants { return request.getPathInfo(); } - /** - * Gets relative location of a theme resource. - * - * @param theme - * the Theme name. - * @param resource - * the Theme resource. - * @return External URI specifying the resource - * - * @deprecated might be refactored or removed before 7.0.0 - */ - @Deprecated - public String getResourceLocation(String theme, ThemeResource resource) { - - if (resourcePath == null) { - return resource.getResourceId(); - } - return resourcePath + theme + "/" + resource.getResourceId(); - } - public class RequestError implements Terminal.ErrorEvent, Serializable { private final Throwable throwable; diff --git a/server/src/com/vaadin/server/VaadinServletService.java b/server/src/com/vaadin/server/VaadinServletService.java index ca894b8a4f..d746ee2303 100644 --- a/server/src/com/vaadin/server/VaadinServletService.java +++ b/server/src/com/vaadin/server/VaadinServletService.java @@ -186,12 +186,6 @@ public class VaadinServletService extends VaadinService { } @Override - protected VaadinServiceSession createVaadinSession(VaadinRequest request) - throws ServiceException { - return new VaadinServletSession(this); - } - - @Override public String getServiceName() { return getServlet().getServletName(); } diff --git a/server/src/com/vaadin/server/VaadinServletSession.java b/server/src/com/vaadin/server/VaadinServletSession.java deleted file mode 100644 index aa31a19c1b..0000000000 --- a/server/src/com/vaadin/server/VaadinServletSession.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2011 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.vaadin.server; - -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionBindingListener; - -/** - * Web application context for Vaadin applications. - * - * This is automatically added as a {@link HttpSessionBindingListener} when - * added to a {@link HttpSession}. - * - * @author Vaadin Ltd. - * @since 3.1 - * - * @deprecated might be refactored or removed before 7.0.0 - */ -@Deprecated -@SuppressWarnings("serial") -public class VaadinServletSession extends VaadinServiceSession { - - /** - * Create a servlet service session for the given servlet service - * - * @param service - * the servlet service to which the new session belongs - */ - public VaadinServletSession(VaadinServletService service) { - super(service); - } - - /** - * Gets the http-session application is running in. - * - * @return HttpSession this application context resides in. - */ - public HttpSession getHttpSession() { - WrappedSession session = getSession(); - return ((WrappedHttpSession) session).getHttpSession(); - } - -} diff --git a/server/src/com/vaadin/server/WrappedHttpSession.java b/server/src/com/vaadin/server/WrappedHttpSession.java index e13a63635b..65db010ba9 100644 --- a/server/src/com/vaadin/server/WrappedHttpSession.java +++ b/server/src/com/vaadin/server/WrappedHttpSession.java @@ -88,4 +88,9 @@ public class WrappedHttpSession implements WrappedSession { session.invalidate(); } + @Override + public String getId() { + return session.getId(); + } + } diff --git a/server/src/com/vaadin/server/WrappedPortletSession.java b/server/src/com/vaadin/server/WrappedPortletSession.java index 03c1d7ba1f..f4a6003ed5 100644 --- a/server/src/com/vaadin/server/WrappedPortletSession.java +++ b/server/src/com/vaadin/server/WrappedPortletSession.java @@ -74,4 +74,9 @@ public class WrappedPortletSession implements WrappedSession { public void invalidate() { session.invalidate(); } + + @Override + public String getId() { + return session.getId(); + } } diff --git a/server/src/com/vaadin/server/WrappedSession.java b/server/src/com/vaadin/server/WrappedSession.java index 34443239c7..cf0b1a2fbd 100644 --- a/server/src/com/vaadin/server/WrappedSession.java +++ b/server/src/com/vaadin/server/WrappedSession.java @@ -86,4 +86,11 @@ public interface WrappedSession { * @see PortletSession#invalidate() */ public void invalidate(); + + /** + * Gets a string with a unique identifier for the session. + * + * @return a unique session id string + */ + public String getId(); } diff --git a/server/src/com/vaadin/ui/ConnectorTracker.java b/server/src/com/vaadin/ui/ConnectorTracker.java index 3fb83eeb92..ddb02129d4 100644 --- a/server/src/com/vaadin/ui/ConnectorTracker.java +++ b/server/src/com/vaadin/ui/ConnectorTracker.java @@ -15,6 +15,7 @@ */ package com.vaadin.ui; +import java.io.IOException; import java.io.Serializable; import java.util.Collection; import java.util.HashMap; @@ -25,6 +26,9 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import org.json.JSONException; +import org.json.JSONObject; + import com.vaadin.server.AbstractClientConnector; import com.vaadin.server.AbstractCommunicationManager; import com.vaadin.server.ClientConnector; @@ -59,7 +63,7 @@ public class ConnectorTracker implements Serializable { private boolean writingResponse = false; private UI uI; - private transient Map<ClientConnector, Object> diffStates = new HashMap<ClientConnector, Object>(); + private transient Map<ClientConnector, JSONObject> diffStates = new HashMap<ClientConnector, JSONObject>(); /** * Gets a logger for this class @@ -409,11 +413,11 @@ public class ConnectorTracker implements Serializable { return dirtyConnectors; } - public Object getDiffState(ClientConnector connector) { + public JSONObject getDiffState(ClientConnector connector) { return diffStates.get(connector); } - public void setDiffState(ClientConnector connector, Object diffState) { + public void setDiffState(ClientConnector connector, JSONObject diffState) { diffStates.put(connector, diffState); } @@ -457,4 +461,39 @@ public class ConnectorTracker implements Serializable { } this.writingResponse = writingResponse; } + + /* Special serialization to JSONObjects which are not serializable */ + private void writeObject(java.io.ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + // Convert JSONObjects in diff state to String representation as + // JSONObject is not serializable + HashMap<ClientConnector, String> stringDiffStates = new HashMap<ClientConnector, String>( + diffStates.size()); + for (ClientConnector key : diffStates.keySet()) { + stringDiffStates.put(key, diffStates.get(key).toString()); + } + out.writeObject(stringDiffStates); + }; + + /* Special serialization to JSONObjects which are not serializable */ + private void readObject(java.io.ObjectInputStream in) throws IOException, + ClassNotFoundException { + in.defaultReadObject(); + + // Read String versions of JSONObjects and parse into JSONObjects as + // JSONObject is not serializable + diffStates = new HashMap<ClientConnector, JSONObject>(); + @SuppressWarnings("unchecked") + HashMap<ClientConnector, String> stringDiffStates = (HashMap<ClientConnector, String>) in + .readObject(); + diffStates = new HashMap<ClientConnector, JSONObject>(); + for (ClientConnector key : stringDiffStates.keySet()) { + try { + diffStates.put(key, new JSONObject(stringDiffStates.get(key))); + } catch (JSONException e) { + throw new IOException(e); + } + } + + } } diff --git a/uitest/src/com/vaadin/tests/applicationcontext/ChangeSessionId.java b/uitest/src/com/vaadin/tests/applicationcontext/ChangeSessionId.java index 4495b343d0..fa0f13e172 100644 --- a/uitest/src/com/vaadin/tests/applicationcontext/ChangeSessionId.java +++ b/uitest/src/com/vaadin/tests/applicationcontext/ChangeSessionId.java @@ -1,7 +1,6 @@ package com.vaadin.tests.applicationcontext; import com.vaadin.server.VaadinService; -import com.vaadin.server.VaadinServletSession; import com.vaadin.tests.components.AbstractTestCase; import com.vaadin.tests.util.Log; import com.vaadin.ui.Button; @@ -30,15 +29,13 @@ public class ChangeSessionId extends AbstractTestCase { })); setMainWindow(mainWindow); - loginButton.addListener(new ClickListener() { + loginButton.addClickListener(new ClickListener() { @Override public void buttonClick(ClickEvent event) { - VaadinServletSession context = ((VaadinServletSession) getContext()); - - String oldSessionId = context.getHttpSession().getId(); - context.getService().reinitializeSession( - VaadinService.getCurrentRequest()); - String newSessionId = context.getHttpSession().getId(); + String oldSessionId = getSessionId(); + VaadinService.reinitializeSession(VaadinService + .getCurrentRequest()); + String newSessionId = getSessionId(); if (oldSessionId.equals(newSessionId)) { log.log("FAILED! Both old and new session id is " + newSessionId); @@ -57,7 +54,7 @@ public class ChangeSessionId extends AbstractTestCase { } protected String getSessionId() { - return ((VaadinServletSession) getContext()).getHttpSession().getId(); + return getContext().getSession().getId(); } @Override diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetShouldUpdateHeight.html b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetShouldUpdateHeight.html new file mode 100644 index 0000000000..2536ed50f6 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetShouldUpdateHeight.html @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="http://localhost:9999/" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/TabsheetShouldUpdateHeight?restartApplication</td> + <td></td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runTabsheetShouldUpdateHeight::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VTabsheet[0]/VTabsheetPanel[0]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td> + <td>12,8</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runTabsheetShouldUpdateHeight::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td> + <td>21,4</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runTabsheetShouldUpdateHeight::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runTabsheetShouldUpdateHeight::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VTabsheet[0]/VTabsheetPanel[0]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td> + <td>18,3</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>tab3</td> +</tr> +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetShouldUpdateHeight.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetShouldUpdateHeight.java new file mode 100644 index 0000000000..af0cd8b49b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetShouldUpdateHeight.java @@ -0,0 +1,59 @@ +package com.vaadin.tests.components.tabsheet;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+
+public class TabsheetShouldUpdateHeight extends TestBase {
+
+ @Override
+ public void setup() {
+ final TabSheet tabsOuter = new TabSheet();
+ final TabSheet tabsInner = new TabSheet();
+
+ final Component tab2;
+
+ tabsInner.addTab(tab2 = getLayoutWithComponents(6, "tab2"), "Tab 2");
+ tabsInner.addTab(getLayoutWithComponents(8, "tab3"), "Tab 3");
+
+ tabsOuter.addTab(tabsInner, "Inner tabs");
+ tabsOuter.addTab(getLayoutWithComponents(10, "tab1"), "Tab 1");
+
+ final Button btnSwitch = new Button("switch to Tab2",
+ new Button.ClickListener() {
+
+ public void buttonClick(final ClickEvent inEvent) {
+ tabsOuter.setSelectedTab(tabsInner);
+ tabsInner.setSelectedTab(tab2);
+ }
+ });
+
+ addComponent(tabsOuter);
+ addComponent(btnSwitch);
+ }
+
+ private VerticalLayout getLayoutWithComponents(final int inAmount, String id) {
+ final VerticalLayout v = new VerticalLayout();
+ v.setDebugId(id);
+ v.setSpacing(true);
+ v.setMargin(true);
+ for (int i = 0; i < inAmount; i++) {
+ v.addComponent(new TextField("Text field:"));
+ }
+ return v;
+ }
+
+ @Override
+ protected String getDescription() {
+ return "click with mouse first on tab 3 and then on tab 1. now click on the button 'switch to tab2'. then click on tab 3 again and the scrollbars appear";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 9275;
+ }
+}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/ui/UISerialization.html b/uitest/src/com/vaadin/tests/components/ui/UISerialization.html index 2e62166cb8..1eb6dffcc0 100644 --- a/uitest/src/com/vaadin/tests/components/ui/UISerialization.html +++ b/uitest/src/com/vaadin/tests/components/ui/UISerialization.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.ui.UISerialization?debug</td> + <td>/run/com.vaadin.tests.components.ui.UISerialization?restartApplication</td> <td></td> </tr> <tr> @@ -24,9 +24,18 @@ <tr> <td>assertText</td> <td>vaadin=runcomvaadintestscomponentsuiUISerialization::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VLabel[0]</td> + <td>3. Diff states match, size: *</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentsuiUISerialization::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VLabel[0]</td> + <td>2. Deserialized UI in *ms</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentsuiUISerialization::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VVerticalLayout[0]/VOrderedLayout$Slot[2]/VLabel[0]</td> <td>1. Serialized UI in *ms into * bytes</td> </tr> - </tbody></table> </body> </html> diff --git a/uitest/src/com/vaadin/tests/components/ui/UISerialization.java b/uitest/src/com/vaadin/tests/components/ui/UISerialization.java index ebb3ff6333..927d00a388 100644 --- a/uitest/src/com/vaadin/tests/components/ui/UISerialization.java +++ b/uitest/src/com/vaadin/tests/components/ui/UISerialization.java @@ -15,8 +15,10 @@ */ package com.vaadin.tests.components.ui; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Date; @@ -69,6 +71,18 @@ public class UISerialization extends AbstractTestUI { long elapsed = new Date().getTime() - d.getTime(); log.log("Serialized UI in " + elapsed + "ms into " + result.length + " bytes"); + Object diffStateBefore = getConnectorTracker().getDiffState( + UISerialization.this); + UISerialization app = (UISerialization) deserialize(result); + log.log("Deserialized UI in " + elapsed + "ms"); + Object diffStateAfter = getConnectorTracker().getDiffState( + UISerialization.this); + if (diffStateBefore.equals(diffStateAfter)) { + log.log("Diff states match, size: " + + diffStateBefore.toString().length()); + } else { + log.log("Diff states do not match"); + } } })); @@ -112,6 +126,17 @@ public class UISerialization extends AbstractTestUI { } } + protected Object deserialize(byte[] result) { + ByteArrayInputStream is = new ByteArrayInputStream(result); + ObjectInputStream ois; + try { + ois = new ObjectInputStream(is); + return ois.readObject(); + } catch (Exception e) { + throw new RuntimeException("Deserialization failed", e); + } + } + @Override protected String getTestDescription() { // TODO Auto-generated method stub |