summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJonatan Kronqvist <jonatan@vaadin.com>2014-04-14 11:53:11 +0300
committerJonatan Kronqvist <jonatan@vaadin.com>2014-04-14 12:06:05 +0300
commit416e2f97bcaf93e4d2a782149a963fca95b8400e (patch)
treeeac6d22107b7c2d7bf6371e5278078f02bb860e9 /server
parentd2e24feb09ccba7f3a2f253687488774af2bc340 (diff)
parenteda9edcbde781d29ff5939defb61ba5fb159e206 (diff)
downloadvaadin-framework-416e2f97bcaf93e4d2a782149a963fca95b8400e.tar.gz
vaadin-framework-416e2f97bcaf93e4d2a782149a963fca95b8400e.zip
Merge branch 'master' into 7.2
72d0aa0 Update Window Javadoc based on 7.2 API review changes ee203f5 Apply abstract ordered layout settings for replaced component (#13568) 02998d8 Updated Window API based on 7.2 API review cd94b21 Discourage use of setNeedsLayout while a layout is running (#13542) f374bc7 Make ComboBox always immediate (#4054) aec102a Update 3rd party license information (#13449) 013d32d Remove old widget from tab content on replace (#12931). 3d0ff32 Prevent duplicate detach() calls with push (#13261) a452bad Refactor VaadinPortletRequest extending. (#13551) 55dfd29 Prevent duplicate session destroy events (#12612) 2067d4e Don't allocate unnecessary memory for empty array of Objects in MethodProperty (#10446). 00a9af5 Refactor PushConfigurationTest. Merge: no Change-Id: I6563769a77f91a68cfeadcb3306dd71fe431863c
Diffstat (limited to 'server')
-rw-r--r--server/src/com/vaadin/data/util/MethodProperty.java26
-rw-r--r--server/src/com/vaadin/server/VaadinPortlet.java228
-rw-r--r--server/src/com/vaadin/server/VaadinService.java12
-rw-r--r--server/src/com/vaadin/server/VaadinSession.java82
-rw-r--r--server/src/com/vaadin/server/communication/AtmospherePushConnection.java10
-rw-r--r--server/src/com/vaadin/server/communication/PushHandler.java78
-rw-r--r--server/src/com/vaadin/ui/AbstractOrderedLayout.java10
-rw-r--r--server/src/com/vaadin/ui/ComboBox.java14
-rw-r--r--server/src/com/vaadin/ui/UI.java3
-rw-r--r--server/src/com/vaadin/ui/Window.java29
-rw-r--r--server/tests/src/com/vaadin/data/util/MethodPropertyMemoryConsumption.java145
-rw-r--r--server/tests/src/com/vaadin/server/VaadinGateInRequestTests.java39
-rw-r--r--server/tests/src/com/vaadin/server/VaadinHttpAndPortletRequestTests.java140
-rw-r--r--server/tests/src/com/vaadin/server/VaadinLiferayRequestTests.java39
-rw-r--r--server/tests/src/com/vaadin/server/VaadinPortletTests.java94
-rw-r--r--server/tests/src/com/vaadin/server/VaadinServiceTest.java22
-rw-r--r--server/tests/src/com/vaadin/server/VaadinWebSpherePortalRequestTests.java39
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/LayoutSettingsOnReplace.java85
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java53
19 files changed, 996 insertions, 152 deletions
diff --git a/server/src/com/vaadin/data/util/MethodProperty.java b/server/src/com/vaadin/data/util/MethodProperty.java
index 0464d50b62..d7323d872f 100644
--- a/server/src/com/vaadin/data/util/MethodProperty.java
+++ b/server/src/com/vaadin/data/util/MethodProperty.java
@@ -19,6 +19,7 @@ package com.vaadin.data.util;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -85,6 +86,10 @@ public class MethodProperty<T> extends AbstractProperty<T> {
*/
private transient Class<? extends T> type;
+ private static final Object[] DEFAULT_GET_ARGS = new Object[0];
+
+ private static final Object[] DEFAULT_SET_ARGS = new Object[1];
+
/* Special serialization to handle method references */
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
@@ -120,8 +125,9 @@ public class MethodProperty<T> extends AbstractProperty<T> {
Class<T> class1 = (Class<T>) SerializerHelper.readClass(in);
type = class1;
instance = in.readObject();
- setArgs = (Object[]) in.readObject();
- getArgs = (Object[]) in.readObject();
+ Object[] setArgs = (Object[]) in.readObject();
+ Object[] getArgs = (Object[]) in.readObject();
+ setArguments(getArgs, setArgs, setArgumentIndex);
String name = (String) in.readObject();
Class<?>[] paramTypes = SerializerHelper.readClassArray(in);
if (name != null) {
@@ -219,7 +225,7 @@ public class MethodProperty<T> extends AbstractProperty<T> {
type = (Class<T>) returnType;
}
- setArguments(new Object[] {}, new Object[] { null }, 0);
+ setArguments(DEFAULT_GET_ARGS, DEFAULT_SET_ARGS, 0);
this.instance = instance;
}
@@ -627,13 +633,15 @@ public class MethodProperty<T> extends AbstractProperty<T> {
*/
public void setArguments(Object[] getArgs, Object[] setArgs,
int setArgumentIndex) {
- this.getArgs = new Object[getArgs.length];
- for (int i = 0; i < getArgs.length; i++) {
- this.getArgs[i] = getArgs[i];
+ if (getArgs.length == 0) {
+ this.getArgs = DEFAULT_GET_ARGS;
+ } else {
+ this.getArgs = Arrays.copyOf(getArgs, getArgs.length);
}
- this.setArgs = new Object[setArgs.length];
- for (int i = 0; i < setArgs.length; i++) {
- this.setArgs[i] = setArgs[i];
+ if (Arrays.equals(setArgs, DEFAULT_SET_ARGS)) {
+ this.setArgs = DEFAULT_SET_ARGS;
+ } else {
+ this.setArgs = Arrays.copyOf(setArgs, setArgs.length);
}
this.setArgumentIndex = setArgumentIndex;
}
diff --git a/server/src/com/vaadin/server/VaadinPortlet.java b/server/src/com/vaadin/server/VaadinPortlet.java
index 4c34b0aedb..b3ce238e72 100644
--- a/server/src/com/vaadin/server/VaadinPortlet.java
+++ b/server/src/com/vaadin/server/VaadinPortlet.java
@@ -29,6 +29,7 @@ import javax.portlet.ActionResponse;
import javax.portlet.EventRequest;
import javax.portlet.EventResponse;
import javax.portlet.GenericPortlet;
+import javax.portlet.PortalContext;
import javax.portlet.PortletConfig;
import javax.portlet.PortletContext;
import javax.portlet.PortletException;
@@ -51,61 +52,83 @@ import com.vaadin.util.CurrentInstance;
* Portlet 2.0 base class. This replaces the servlet in servlet/portlet 1.0
* deployments and handles various portlet requests from the browser.
*
- * TODO Document me!
- *
- * @author peholmst
+ * @author Vaadin Ltd
*/
public class VaadinPortlet extends GenericPortlet implements Constants,
Serializable {
/**
- * @deprecated As of 7.0. Will likely change or be removed in a future
- * version
+ * Base class for portlet requests that need access to HTTP servlet
+ * requests.
*/
- @Deprecated
- public static final String RESOURCE_URL_ID = "APP";
-
- public static class VaadinHttpAndPortletRequest extends
+ public static abstract class VaadinHttpAndPortletRequest extends
VaadinPortletRequest {
+ /**
+ * Constructs a new {@link VaadinHttpAndPortletRequest}.
+ *
+ * @since 7.2
+ * @param request
+ * {@link PortletRequest} to be wrapped
+ * @param vaadinService
+ * {@link VaadinPortletService} associated with this request
+ */
public VaadinHttpAndPortletRequest(PortletRequest request,
- HttpServletRequest originalRequest,
VaadinPortletService vaadinService) {
super(request, vaadinService);
- this.originalRequest = originalRequest;
}
- private final HttpServletRequest originalRequest;
+ private HttpServletRequest originalRequest;
+
+ /**
+ * Returns the original HTTP servlet request for this portlet request.
+ *
+ * @since 7.2
+ * @param request
+ * {@link PortletRequest} used to
+ * @return the original HTTP servlet request
+ */
+ protected abstract HttpServletRequest getServletRequest(
+ PortletRequest request);
+
+ private HttpServletRequest getOriginalRequest() {
+ if (originalRequest == null) {
+ PortletRequest request = getRequest();
+ originalRequest = getServletRequest(request);
+ }
+
+ return originalRequest;
+ }
@Override
public String getParameter(String name) {
String parameter = super.getParameter(name);
if (parameter == null) {
- parameter = originalRequest.getParameter(name);
+ parameter = getOriginalRequest().getParameter(name);
}
return parameter;
}
@Override
public String getRemoteAddr() {
- return originalRequest.getRemoteAddr();
+ return getOriginalRequest().getRemoteAddr();
}
@Override
public String getRemoteHost() {
- return originalRequest.getRemoteHost();
+ return getOriginalRequest().getRemoteHost();
}
@Override
public int getRemotePort() {
- return originalRequest.getRemotePort();
+ return getOriginalRequest().getRemotePort();
}
@Override
public String getHeader(String name) {
String header = super.getHeader(name);
if (header == null) {
- header = originalRequest.getHeader(name);
+ header = getOriginalRequest().getHeader(name);
}
return header;
}
@@ -114,7 +137,7 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
public Enumeration<String> getHeaderNames() {
Enumeration<String> headerNames = super.getHeaderNames();
if (headerNames == null) {
- headerNames = originalRequest.getHeaderNames();
+ headerNames = getOriginalRequest().getHeaderNames();
}
return headerNames;
}
@@ -123,7 +146,7 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
public Enumeration<String> getHeaders(String name) {
Enumeration<String> headers = super.getHeaders(name);
if (headers == null) {
- headers = originalRequest.getHeaders(name);
+ headers = getOriginalRequest().getHeaders(name);
}
return headers;
}
@@ -132,64 +155,21 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
public Map<String, String[]> getParameterMap() {
Map<String, String[]> parameterMap = super.getParameterMap();
if (parameterMap == null) {
- parameterMap = originalRequest.getParameterMap();
+ parameterMap = getOriginalRequest().getParameterMap();
}
return parameterMap;
}
}
- public static class VaadinGateinRequest extends VaadinHttpAndPortletRequest {
- public VaadinGateinRequest(PortletRequest request,
- VaadinPortletService vaadinService) {
- super(request, getOriginalRequest(request), vaadinService);
- }
-
- private static final HttpServletRequest getOriginalRequest(
- PortletRequest request) {
- try {
- Method getRealReq = request.getClass().getMethod(
- "getRealRequest");
- HttpServletRequestWrapper origRequest = (HttpServletRequestWrapper) getRealReq
- .invoke(request);
- return origRequest;
- } catch (Exception e) {
- throw new IllegalStateException("GateIn request not detected",
- e);
- }
- }
- }
-
- // Intentionally internal, will be refactored out in 7.2.
- static class WebSpherePortalRequest extends VaadinHttpAndPortletRequest {
-
- public WebSpherePortalRequest(PortletRequest request,
- VaadinPortletService vaadinService) {
- super(request, getServletRequest(request), vaadinService);
- }
-
- private static HttpServletRequest getServletRequest(
- PortletRequest request) {
- try {
- Class<?> portletUtils = Class
- .forName("com.ibm.ws.portletcontainer.portlet.PortletUtils");
- Method getHttpServletRequest = portletUtils.getMethod(
- "getHttpServletRequest", PortletRequest.class);
-
- return (HttpServletRequest) getHttpServletRequest.invoke(null,
- request);
- } catch (Exception e) {
- throw new IllegalStateException(
- "WebSphere Portal request not detected.");
- }
- }
- }
-
+ /**
+ * Portlet request for Liferay.
+ */
public static class VaadinLiferayRequest extends
VaadinHttpAndPortletRequest {
public VaadinLiferayRequest(PortletRequest request,
VaadinPortletService vaadinService) {
- super(request, getOriginalRequest(request), vaadinService);
+ super(request, vaadinService);
}
@Override
@@ -219,7 +199,7 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
* @throws Exception
* @return return value of the invoked method
*/
- private static Object invokeStaticLiferayMethod(String className,
+ private Object invokeStaticLiferayMethod(String className,
String methodName, Object argument, String parameterClassName)
throws Exception {
Thread currentThread = Thread.currentThread();
@@ -251,8 +231,8 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
}
}
- private static HttpServletRequest getOriginalRequest(
- PortletRequest request) {
+ @Override
+ protected HttpServletRequest getServletRequest(PortletRequest request) {
try {
// httpRequest = PortalUtil.getHttpServletRequest(request);
HttpServletRequest httpRequest = (HttpServletRequest) invokeStaticLiferayMethod(
@@ -272,10 +252,68 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
e);
}
}
+ }
+ /**
+ * Portlet request for GateIn.
+ */
+ public static class VaadinGateInRequest extends VaadinHttpAndPortletRequest {
+ public VaadinGateInRequest(PortletRequest request,
+ VaadinPortletService vaadinService) {
+ super(request, vaadinService);
+ }
+
+ @Override
+ protected HttpServletRequest getServletRequest(PortletRequest request) {
+ try {
+ Method getRealReq = request.getClass().getMethod(
+ "getRealRequest");
+ HttpServletRequestWrapper origRequest = (HttpServletRequestWrapper) getRealReq
+ .invoke(request);
+ return origRequest;
+ } catch (Exception e) {
+ throw new IllegalStateException("GateIn request not detected",
+ e);
+ }
+ }
+ }
+
+ /**
+ * Portlet request for WebSphere Portal.
+ */
+ public static class VaadinWebSpherePortalRequest extends
+ VaadinHttpAndPortletRequest {
+
+ public VaadinWebSpherePortalRequest(PortletRequest request,
+ VaadinPortletService vaadinService) {
+ super(request, vaadinService);
+ }
+
+ @Override
+ protected HttpServletRequest getServletRequest(PortletRequest request) {
+ try {
+ Class<?> portletUtils = Class
+ .forName("com.ibm.ws.portletcontainer.portlet.PortletUtils");
+ Method getHttpServletRequest = portletUtils.getMethod(
+ "getHttpServletRequest", PortletRequest.class);
+
+ return (HttpServletRequest) getHttpServletRequest.invoke(null,
+ request);
+ } catch (Exception e) {
+ throw new IllegalStateException(
+ "WebSphere Portal request not detected.");
+ }
+ }
}
/**
+ * @deprecated As of 7.0. Will likely change or be removed in a future
+ * version
+ */
+ @Deprecated
+ public static final String RESOURCE_URL_ID = "APP";
+
+ /**
* This portlet parameter is used to add styles to the main element. E.g
* "height:500px" generates a style="height:500px" to the main element.
*
@@ -443,50 +481,26 @@ public class VaadinPortlet extends GenericPortlet implements Constants,
*
* @param request
* The original PortletRequest
- * @return A wrapped version of the PorletRequest
+ * @return A wrapped version of the PortletRequest
*/
protected VaadinPortletRequest createVaadinRequest(PortletRequest request) {
- if (isLiferay(request)) {
- return new VaadinLiferayRequest(request, getService());
- } else if (isGateIn(request)) {
- return new VaadinGateinRequest(request, getService());
- } else if (isWebSphere(request)) {
- return new WebSpherePortalRequest(request, getService());
- } else {
+ PortalContext portalContext = request.getPortalContext();
+ String portalInfo = portalContext.getPortalInfo().toLowerCase().trim();
+ VaadinPortletService service = getService();
- return new VaadinPortletRequest(request, getService());
+ if (portalInfo.contains("gatein")) {
+ return new VaadinGateInRequest(request, service);
}
- }
-
- /**
- * Returns true if the portlet request is from Liferay.
- *
- * @param request
- * @return True if Liferay, false otherwise
- */
- private static boolean isLiferay(PortletRequest request) {
- String portalInfo = request.getPortalContext().getPortalInfo()
- .toLowerCase();
- return portalInfo.contains("liferay");
- }
- /**
- * Returns true if the portlet request if from GateIn
- *
- * @param request
- * @return True if GateIn, false otherwise
- */
- private static boolean isGateIn(PortletRequest request) {
- String portalInfo = request.getPortalContext().getPortalInfo()
- .toLowerCase();
- return portalInfo.contains("gatein");
- }
+ if (portalInfo.contains("liferay")) {
+ return new VaadinLiferayRequest(request, service);
+ }
- private static boolean isWebSphere(PortletRequest request) {
- String portalInfo = request.getPortalContext().getPortalInfo()
- .toLowerCase();
+ if (portalInfo.contains("websphere portal")) {
+ return new VaadinWebSpherePortalRequest(request, service);
+ }
- return portalInfo.contains("websphere portal");
+ return new VaadinPortletRequest(request, service);
}
private VaadinPortletResponse createVaadinResponse(PortletResponse response) {
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java
index ba1224568a..b96e284e6e 100644
--- a/server/src/com/vaadin/server/VaadinService.java
+++ b/server/src/com/vaadin/server/VaadinService.java
@@ -53,6 +53,7 @@ import org.json.JSONObject;
import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.event.EventRouter;
import com.vaadin.server.VaadinSession.FutureAccess;
+import com.vaadin.server.VaadinSession.State;
import com.vaadin.server.communication.FileUploadHandler;
import com.vaadin.server.communication.HeartbeatHandler;
import com.vaadin.server.communication.PublishedFileHandler;
@@ -446,7 +447,10 @@ public abstract class VaadinService implements Serializable {
session.accessSynchronously(new Runnable() {
@Override
public void run() {
- if (!session.isClosing()) {
+ if (session.getState() == State.CLOSED) {
+ return;
+ }
+ if (session.getState() == State.OPEN) {
closeSession(session);
}
ArrayList<UI> uis = new ArrayList<UI>(session.getUIs());
@@ -472,6 +476,8 @@ public abstract class VaadinService implements Serializable {
// destroy listeners
eventRouter.fireEvent(new SessionDestroyEvent(
VaadinService.this, session), session.getErrorHandler());
+
+ session.setState(State.CLOSED);
}
});
}
@@ -1127,7 +1133,7 @@ public abstract class VaadinService implements Serializable {
closeInactiveUIs(session);
removeClosedUIs(session);
} else {
- if (!session.isClosing()) {
+ if (session.getState() == State.OPEN) {
closeSession(session);
if (session.getSession() != null) {
getLogger().log(Level.FINE, "Closing inactive session {0}",
@@ -1279,7 +1285,7 @@ public abstract class VaadinService implements Serializable {
* @return true if the session is active, false if it could be closed.
*/
private boolean isSessionActive(VaadinSession session) {
- if (session.isClosing() || session.getSession() == null) {
+ if (session.getState() != State.OPEN || session.getSession() == null) {
return false;
} else {
long now = System.currentTimeMillis();
diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java
index 134a026788..ac518c1902 100644
--- a/server/src/com/vaadin/server/VaadinSession.java
+++ b/server/src/com/vaadin/server/VaadinSession.java
@@ -167,6 +167,33 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
}
/**
+ * The lifecycle state of a VaadinSession.
+ *
+ * @since 7.2
+ */
+ public enum State {
+ /**
+ * The session is active and accepting client requests.
+ */
+ OPEN,
+ /**
+ * The {@link VaadinSession#close() close} method has been called; the
+ * session will be closed as soon as the current request ends.
+ */
+ CLOSING,
+ /**
+ * The session is closed; all the {@link UI}s have been removed and
+ * {@link SessionDestroyListener}s have been called.
+ */
+ CLOSED;
+
+ private boolean isValidChange(State newState) {
+ return (this == OPEN && newState == CLOSING)
+ || (this == CLOSING && newState == CLOSED);
+ }
+ }
+
+ /**
* The name of the parameter that is by default used in e.g. web.xml to
* define the name of the default {@link UI} class.
*/
@@ -225,7 +252,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
private long lastRequestTimestamp = System.currentTimeMillis();
- private boolean closing = false;
+ private State state = State.OPEN;
private transient WrappedSession session;
@@ -279,24 +306,20 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
} else if (VaadinService.getCurrentRequest() != null
&& getCurrent() == this) {
assert hasLock();
- /*
- * Ignore if the session is being moved to a different backing
- * session or if GAEVaadinServlet is doing its normal cleanup.
- */
+ // Ignore if the session is being moved to a different backing
+ // session or if GAEVaadinServlet is doing its normal cleanup.
if (getAttribute(VaadinService.PRESERVE_UNBOUND_SESSION_ATTRIBUTE) == Boolean.TRUE) {
return;
}
// There is still a request in progress for this session. The
// session will be destroyed after the response has been written.
- if (!isClosing()) {
+ if (getState() == State.OPEN) {
close();
}
} else {
- /*
- * We are not in a request related to this session so we can
- * immediately destroy it
- */
+ // We are not in a request related to this session so we can destroy
+ // it as soon as we acquire the lock.
service.fireSessionDestroy(this);
}
session = null;
@@ -1226,19 +1249,52 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
*/
public void close() {
assert hasLock();
- closing = true;
+ state = State.CLOSING;
}
/**
- * Returns whether this session is marked to be closed.
+ * Returns whether this session is marked to be closed. Note that this
+ * method also returns true if the session is actually already closed.
*
* @see #close()
*
+ * @deprecated As of 7.2, use
+ * <code>{@link #getState() getState() != State.OPEN}</code>
+ * instead.
+ *
* @return true if this session is marked to be closed, false otherwise
*/
+ @Deprecated
public boolean isClosing() {
assert hasLock();
- return closing;
+ return state == State.CLOSING || state == State.CLOSED;
+ }
+
+ /**
+ * Returns the lifecycle state of this session.
+ *
+ * @since 7.2
+ * @return the current state
+ */
+ public State getState() {
+ assert hasLock();
+ return state;
+ }
+
+ /**
+ * Sets the lifecycle state of this session. The allowed transitions are
+ * OPEN to CLOSING and CLOSING to CLOSED.
+ *
+ * @since 7.2
+ * @param state
+ * the new state
+ */
+ protected void setState(State state) {
+ assert hasLock();
+ assert this.state.isValidChange(state) : "Invalid session state change "
+ + this.state + "->" + state;
+
+ this.state = state;
}
private static final Logger getLogger() {
diff --git a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
index 65ea43ddd4..a4290a31cf 100644
--- a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
+++ b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
@@ -260,6 +260,16 @@ public class AtmospherePushConnection implements PushConnection {
@Override
public void disconnect() {
assert isConnected();
+
+ if (resource.isResumed()) {
+ // Calling disconnect may end up invoking it again via
+ // resource.resume and PushHandler.onResume. Bail out here if
+ // the resource is already resumed; this is a bit hacky and should
+ // be implemented in a better way in 7.2.
+ resource = null;
+ return;
+ }
+
if (outgoingMessage != null) {
// Wait for the last message to be sent before closing the
// connection (assumes that futures are completed in order)
diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/com/vaadin/server/communication/PushHandler.java
index 1557ae9b19..e028968494 100644
--- a/server/src/com/vaadin/server/communication/PushHandler.java
+++ b/server/src/com/vaadin/server/communication/PushHandler.java
@@ -365,7 +365,83 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter {
}
private void disconnect(AtmosphereResourceEvent event) {
- callWithUi(event.getResource(), disconnectCallback);
+ // We don't want to use callWithUi here, as it assumes there's a client
+ // request active and does requestStart and requestEnd among other
+ // things.
+
+ AtmosphereResource resource = event.getResource();
+ VaadinServletRequest vaadinRequest = new VaadinServletRequest(
+ resource.getRequest(), service);
+ VaadinSession session = null;
+
+ try {
+ session = service.findVaadinSession(vaadinRequest);
+ } catch (ServiceException e) {
+ getLogger().log(Level.SEVERE,
+ "Could not get session. This should never happen", e);
+ return;
+ } catch (SessionExpiredException e) {
+ getLogger()
+ .log(Level.SEVERE,
+ "Session expired before push was disconnected. This should never happen",
+ e);
+ return;
+ }
+
+ UI ui = null;
+ session.lock();
+ try {
+ VaadinSession.setCurrent(session);
+ // Sets UI.currentInstance
+ ui = service.findUI(vaadinRequest);
+ if (ui == null) {
+ getLogger().log(Level.SEVERE,
+ "Could not get UI. This should never happen");
+ return;
+ }
+
+ PushMode pushMode = ui.getPushConfiguration().getPushMode();
+ AtmospherePushConnection pushConnection = getConnectionForUI(ui);
+
+ String id = resource.uuid();
+
+ if (pushConnection == null) {
+ getLogger()
+ .log(Level.WARNING,
+ "Could not find push connection to close: {0} with transport {1}",
+ new Object[] { id, resource.transport() });
+ } else {
+ if (!pushMode.isEnabled()) {
+ /*
+ * The client is expected to close the connection after push
+ * mode has been set to disabled.
+ */
+ getLogger().log(Level.FINER,
+ "Connection closed for resource {0}", id);
+ } else {
+ /*
+ * Unexpected cancel, e.g. if the user closes the browser
+ * tab.
+ */
+ getLogger()
+ .log(Level.FINER,
+ "Connection unexpectedly closed for resource {0} with transport {1}",
+ new Object[] { id, resource.transport() });
+ }
+ ui.setPushConnection(null);
+ }
+
+ } catch (final Exception e) {
+ callErrorHandler(session, e);
+ } finally {
+ try {
+ session.unlock();
+ } catch (Exception e) {
+ getLogger().log(Level.WARNING, "Error while unlocking session",
+ e);
+ // can't call ErrorHandler, we (hopefully) don't have a lock
+ }
+ }
}
/**
diff --git a/server/src/com/vaadin/ui/AbstractOrderedLayout.java b/server/src/com/vaadin/ui/AbstractOrderedLayout.java
index c9eb756daa..f5fd4d7bfc 100644
--- a/server/src/com/vaadin/ui/AbstractOrderedLayout.java
+++ b/server/src/com/vaadin/ui/AbstractOrderedLayout.java
@@ -213,8 +213,12 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
if (oldLocation == -1) {
addComponent(newComponent);
} else if (newLocation == -1) {
+ Alignment alignment = getComponentAlignment(oldComponent);
+ float expandRatio = getExpandRatio(oldComponent);
+
removeComponent(oldComponent);
addComponent(newComponent, oldLocation);
+ applyLayoutSettings(newComponent, alignment, expandRatio);
} else {
// Both old and new are in the layout
if (oldLocation > newLocation) {
@@ -444,4 +448,10 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
defaultComponentAlignment = defaultAlignment;
}
+ private void applyLayoutSettings(Component target, Alignment alignment,
+ float expandRatio) {
+ setComponentAlignment(target, alignment);
+ setExpandRatio(target, expandRatio);
+ }
+
}
diff --git a/server/src/com/vaadin/ui/ComboBox.java b/server/src/com/vaadin/ui/ComboBox.java
index 5fb2f81011..da29618efe 100644
--- a/server/src/com/vaadin/ui/ComboBox.java
+++ b/server/src/com/vaadin/ui/ComboBox.java
@@ -103,22 +103,30 @@ public class ComboBox extends AbstractSelect implements
private boolean textInputAllowed = true;
public ComboBox() {
- setNewItemsAllowed(false);
+ initDefaults();
}
public ComboBox(String caption, Collection<?> options) {
super(caption, options);
- setNewItemsAllowed(false);
+ initDefaults();
}
public ComboBox(String caption, Container dataSource) {
super(caption, dataSource);
- setNewItemsAllowed(false);
+ initDefaults();
}
public ComboBox(String caption) {
super(caption);
+ initDefaults();
+ }
+
+ /**
+ * Initialize the ComboBox with default settings
+ */
+ private void initDefaults() {
setNewItemsAllowed(false);
+ setImmediate(true);
}
/**
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index 5fbd654dcf..3ae0aea6f7 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -53,6 +53,7 @@ import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinService;
import com.vaadin.server.VaadinServlet;
import com.vaadin.server.VaadinSession;
+import com.vaadin.server.VaadinSession.State;
import com.vaadin.server.communication.PushConnection;
import com.vaadin.shared.Connector;
import com.vaadin.shared.EventId;
@@ -1162,7 +1163,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
public void close() {
closing = true;
- boolean sessionExpired = (session == null || session.isClosing());
+ boolean sessionExpired = (session == null || session.getState() != State.OPEN);
getRpcProxy(UIClientRpc.class).uiClosed(sessionExpired);
if (getPushConnection() != null) {
// Push the Rpc to the client. The connection will be closed when
diff --git a/server/src/com/vaadin/ui/Window.java b/server/src/com/vaadin/ui/Window.java
index 022adc6373..11a6fde853 100644
--- a/server/src/com/vaadin/ui/Window.java
+++ b/server/src/com/vaadin/ui/Window.java
@@ -18,9 +18,6 @@ package com.vaadin.ui;
import java.io.Serializable;
import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
import java.util.Map;
import com.vaadin.event.FieldEvents.BlurEvent;
@@ -1017,15 +1014,15 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
* window. Text contained in these components will be read by assistive
* devices when it is opened.
*
- * @param connectors
- * with the components to use as description
+ * @param components
+ * the components to use as description
*/
- public void setAssistiveDescription(Connector... connectors) {
- if (connectors == null) {
+ public void setAssistiveDescription(Component... components) {
+ if (components == null) {
throw new IllegalArgumentException(
"Parameter connectors must be non-null");
} else {
- getState().contentDescription = connectors;
+ getState().contentDescription = components;
}
}
@@ -1034,11 +1031,19 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
* contained in these components will be read by assistive devices when the
* window is opened.
*
- * @return list of previously set components
+ * @return array of previously set components
*/
- public List<Connector> getAssistiveDescription() {
- return Collections.unmodifiableList(Arrays
- .asList(getState().contentDescription));
+ public Component[] getAssistiveDescription() {
+ Connector[] contentDescription = getState().contentDescription;
+ if (contentDescription == null) {
+ return null;
+ }
+
+ Component[] target = new Component[contentDescription.length];
+ System.arraycopy(contentDescription, 0, target, 0,
+ contentDescription.length);
+
+ return target;
}
/**
diff --git a/server/tests/src/com/vaadin/data/util/MethodPropertyMemoryConsumption.java b/server/tests/src/com/vaadin/data/util/MethodPropertyMemoryConsumption.java
new file mode 100644
index 0000000000..caff33cf50
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/MethodPropertyMemoryConsumption.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2000-2013 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.data.util;
+
+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.lang.reflect.Field;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for MethodProperty: don't allocate unnecessary Object arrays.
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public class MethodPropertyMemoryConsumption {
+
+ @Test
+ public void testSetArguments() throws NoSuchFieldException,
+ SecurityException, IllegalArgumentException, IllegalAccessException {
+ TestBean bean = new TestBean();
+ TestMethodProperty<String> property = new TestMethodProperty<String>(
+ bean, "name");
+ Object[] getArgs = property.getGetArgs();
+ Object[] setArgs = property.getSetArgs();
+
+ Field getArgsField = TestMethodProperty.class
+ .getDeclaredField("getArgs");
+ getArgsField.setAccessible(true);
+
+ Field setArgsField = TestMethodProperty.class
+ .getDeclaredField("setArgs");
+ setArgsField.setAccessible(true);
+
+ Assert.assertSame("setArguments method sets non-default instance"
+ + " of empty Object array for getArgs",
+ getArgsField.get(property), getArgs);
+
+ Assert.assertSame("setArguments method sets non-default instance"
+ + " of empty Object array for setArgs",
+ setArgsField.get(property), setArgs);
+ }
+
+ @Test
+ public void testDefaultCtor() {
+ TestBean bean = new TestBean();
+ TestMethodProperty<String> property = new TestMethodProperty<String>(
+ bean, "name");
+
+ Object[] getArgs = property.getGetArgs();
+ Object[] setArgs = property.getSetArgs();
+
+ TestBean otherBean = new TestBean();
+ TestMethodProperty<String> otherProperty = new TestMethodProperty<String>(
+ otherBean, "name");
+ Assert.assertSame("setArguments method uses different instance"
+ + " of empty Object array for getArgs", getArgs,
+ otherProperty.getGetArgs());
+ Assert.assertSame("setArguments method uses different instance"
+ + " of empty Object array for setArgs", setArgs,
+ otherProperty.getSetArgs());
+ }
+
+ @Test
+ public void testDefaultArgsSerialization() throws IOException,
+ ClassNotFoundException {
+ TestBean bean = new TestBean();
+ TestMethodProperty<String> property = new TestMethodProperty<String>(
+ bean, "name");
+
+ ByteArrayOutputStream sourceOutStream = new ByteArrayOutputStream();
+ ObjectOutputStream outStream = new ObjectOutputStream(sourceOutStream);
+ outStream.writeObject(property);
+
+ ObjectInputStream inputStream = new ObjectInputStream(
+ new ByteArrayInputStream(sourceOutStream.toByteArray()));
+ Object red = inputStream.readObject();
+ TestMethodProperty<?> deserialized = (TestMethodProperty<?>) red;
+
+ Assert.assertNotNull("Deseriliation doesn't call setArguments method",
+ deserialized.getGetArgs());
+ Assert.assertNotNull("Deseriliation doesn't call setArguments method",
+ deserialized.getSetArgs());
+
+ }
+
+ public static class TestMethodProperty<T> extends MethodProperty<T> {
+
+ public TestMethodProperty(Object instance, String beanPropertyName) {
+ super(instance, beanPropertyName);
+ }
+
+ @Override
+ public void setArguments(Object[] getArgs, Object[] setArgs,
+ int setArgumentIndex) {
+ super.setArguments(getArgs, setArgs, setArgumentIndex);
+ this.getArgs = getArgs;
+ this.setArgs = setArgs;
+ }
+
+ Object[] getGetArgs() {
+ return getArgs;
+ }
+
+ Object[] getSetArgs() {
+ return setArgs;
+ }
+
+ private transient Object[] getArgs;
+ private transient Object[] setArgs;
+ }
+
+ public static class TestBean implements Serializable {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ }
+}
diff --git a/server/tests/src/com/vaadin/server/VaadinGateInRequestTests.java b/server/tests/src/com/vaadin/server/VaadinGateInRequestTests.java
new file mode 100644
index 0000000000..017613661e
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/VaadinGateInRequestTests.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2013 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 static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import com.vaadin.server.VaadinPortlet.VaadinGateInRequest;
+
+public class VaadinGateInRequestTests extends
+ VaadinHttpAndPortletRequestTests<VaadinGateInRequest> {
+
+ @Override
+ protected VaadinGateInRequest createSut() {
+
+ VaadinGateInRequest request = new VaadinGateInRequest(portletRequest,
+ vaadinPortletService);
+
+ // Although partial mocking can be considered a code smell,
+ // here it's actually quite useful to mock reflection calls.
+ VaadinGateInRequest spy = spy(request);
+ doReturn(servletRequest).when(spy).getServletRequest(portletRequest);
+
+ return spy;
+ }
+}
diff --git a/server/tests/src/com/vaadin/server/VaadinHttpAndPortletRequestTests.java b/server/tests/src/com/vaadin/server/VaadinHttpAndPortletRequestTests.java
new file mode 100644
index 0000000000..01d501c4fb
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/VaadinHttpAndPortletRequestTests.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2000-2013 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 static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Enumeration;
+import java.util.Map;
+
+import javax.portlet.PortletRequest;
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.vaadin.server.VaadinPortlet.VaadinHttpAndPortletRequest;
+import com.vaadin.server.VaadinPortletService;
+
+//Have to ignore this class - otherwise JUnit tries to instantiate it...
+@Ignore
+public abstract class VaadinHttpAndPortletRequestTests<T extends VaadinHttpAndPortletRequest> {
+
+ protected VaadinHttpAndPortletRequest sut;
+ protected HttpServletRequest servletRequest;
+ protected PortletRequest portletRequest;
+ protected VaadinPortletService vaadinPortletService;
+
+ protected abstract T createSut();
+
+ @Before
+ public void setup() {
+ portletRequest = mock(PortletRequest.class);
+ vaadinPortletService = mock(VaadinPortletService.class);
+ servletRequest = mock(HttpServletRequest.class);
+
+ sut = createSut();
+ }
+
+ @Test
+ public void parameterIsFetchedFromServletRequest() {
+ when(servletRequest.getParameter("foo")).thenReturn("bar");
+
+ String parameter = sut.getParameter("foo");
+
+ assertThat(parameter, is("bar"));
+ }
+
+ @Test
+ public void originalParameterIsOverridden() {
+ when(servletRequest.getParameter("foo")).thenReturn("braa");
+ when(portletRequest.getParameter("foo")).thenReturn("bar");
+
+ String parameter = sut.getParameter("foo");
+
+ assertThat(parameter, is("bar"));
+ }
+
+ @Test
+ public void remoteAddressIsFetchedFromServletRequest() {
+ when(servletRequest.getRemoteAddr()).thenReturn("foo");
+
+ String remoteAddr = sut.getRemoteAddr();
+
+ assertThat(remoteAddr, is("foo"));
+ }
+
+ @Test
+ public void remoteHostIsFetchedFromServletRequest() {
+ when(servletRequest.getRemoteHost()).thenReturn("foo");
+
+ String remoteHost = sut.getRemoteHost();
+
+ assertThat(remoteHost, is("foo"));
+ }
+
+ @Test
+ public void remotePortIsFetchedFromServletRequest() {
+ when(servletRequest.getRemotePort()).thenReturn(12345);
+
+ int remotePort = sut.getRemotePort();
+
+ assertThat(remotePort, is(12345));
+ }
+
+ @Test
+ public void headerIsFetchedFromServletRequest() {
+ when(servletRequest.getHeader("foo")).thenReturn("bar");
+
+ String header = sut.getHeader("foo");
+
+ assertThat(header, is("bar"));
+ }
+
+ @Test
+ public void headerNamesAreFetchedFromServletRequest() {
+ Enumeration expectedHeaderNames = mock(Enumeration.class);
+ when(servletRequest.getHeaderNames()).thenReturn(expectedHeaderNames);
+
+ Enumeration<String> actualHeaderNames = sut.getHeaderNames();
+
+ assertThat(actualHeaderNames, is(expectedHeaderNames));
+ }
+
+ @Test
+ public void headersAreFetchedFromServletRequest() {
+ Enumeration expectedHeaders = mock(Enumeration.class);
+ when(servletRequest.getHeaders("foo")).thenReturn(expectedHeaders);
+
+ Enumeration<String> actualHeaders = sut.getHeaders("foo");
+
+ assertThat(actualHeaders, is(expectedHeaders));
+ }
+
+ @Test
+ public void parameterMapIsFetchedFromServletRequest() {
+ Map expectedParameterMap = mock(Map.class);
+ when(servletRequest.getParameterMap()).thenReturn(expectedParameterMap);
+
+ Map<String, String[]> actualParameterMap = sut.getParameterMap();
+
+ assertThat(actualParameterMap, is(expectedParameterMap));
+ }
+}
diff --git a/server/tests/src/com/vaadin/server/VaadinLiferayRequestTests.java b/server/tests/src/com/vaadin/server/VaadinLiferayRequestTests.java
new file mode 100644
index 0000000000..074941a556
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/VaadinLiferayRequestTests.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2013 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 static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import com.vaadin.server.VaadinPortlet.VaadinLiferayRequest;
+
+public class VaadinLiferayRequestTests extends
+ VaadinHttpAndPortletRequestTests<VaadinLiferayRequest> {
+
+ @Override
+ protected VaadinLiferayRequest createSut() {
+
+ VaadinLiferayRequest request = new VaadinLiferayRequest(portletRequest,
+ vaadinPortletService);
+
+ // Although partial mocking can be considered a code smell,
+ // here it's actually quite useful to mock reflection calls.
+ VaadinLiferayRequest spy = spy(request);
+ doReturn(servletRequest).when(spy).getServletRequest(portletRequest);
+
+ return spy;
+ }
+} \ No newline at end of file
diff --git a/server/tests/src/com/vaadin/server/VaadinPortletTests.java b/server/tests/src/com/vaadin/server/VaadinPortletTests.java
new file mode 100644
index 0000000000..93f8fd0778
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/VaadinPortletTests.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2013 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 static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import javax.portlet.PortalContext;
+import javax.portlet.PortletRequest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.server.VaadinPortlet.VaadinGateInRequest;
+import com.vaadin.server.VaadinPortlet.VaadinLiferayRequest;
+import com.vaadin.server.VaadinPortlet.VaadinWebSpherePortalRequest;
+
+public class VaadinPortletTests {
+
+ private VaadinPortlet sut;
+ private PortletRequest portletRequest;
+ private PortalContext portalContext;
+
+ @Before
+ public void setup() {
+ sut = new VaadinPortlet();
+
+ portletRequest = mock(PortletRequest.class);
+ portalContext = mock(PortalContext.class);
+
+ when(portletRequest.getPortalContext()).thenReturn(portalContext);
+ }
+
+ private void mockPortalInfo(String name) {
+ when(portalContext.getPortalInfo()).thenReturn(name);
+ }
+
+ private VaadinPortletRequest createRequest() {
+ VaadinPortletRequest request = sut.createVaadinRequest(portletRequest);
+ return request;
+ }
+
+ @Test
+ public void gateInRequestIsCreated() {
+ mockPortalInfo("gatein");
+
+ VaadinPortletRequest request = createRequest();
+
+ assertThat(request, instanceOf(VaadinGateInRequest.class));
+ }
+
+ @Test
+ public void liferayRequestIsCreated() {
+ mockPortalInfo("liferay");
+
+ VaadinPortletRequest request = createRequest();
+
+ assertThat(request, instanceOf(VaadinLiferayRequest.class));
+ }
+
+ @Test
+ public void webspherePortalRequestIsCreated() {
+ mockPortalInfo("websphere portal");
+
+ VaadinPortletRequest request = createRequest();
+
+ assertThat(request, instanceOf(VaadinWebSpherePortalRequest.class));
+ }
+
+ @Test
+ public void defaultPortletRequestIsCreated() {
+ mockPortalInfo("foobar");
+
+ VaadinPortletRequest request = createRequest();
+
+ assertThat(request, instanceOf(VaadinPortletRequest.class));
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/server/VaadinServiceTest.java b/server/tests/src/com/vaadin/server/VaadinServiceTest.java
index cead5df79c..77eb155378 100644
--- a/server/tests/src/com/vaadin/server/VaadinServiceTest.java
+++ b/server/tests/src/com/vaadin/server/VaadinServiceTest.java
@@ -29,6 +29,16 @@ import org.junit.Test;
*/
public class VaadinServiceTest {
+ private class TestSessionDestroyListener implements SessionDestroyListener {
+
+ int callCount = 0;
+
+ @Override
+ public void sessionDestroy(SessionDestroyEvent event) {
+ callCount++;
+ }
+ }
+
@Test
public void testFireSessionDestroy() throws ServletException {
ServletConfig servletConfig = new MockServletConfig();
@@ -36,6 +46,10 @@ public class VaadinServiceTest {
servlet.init(servletConfig);
VaadinService service = servlet.getService();
+ TestSessionDestroyListener listener = new TestSessionDestroyListener();
+
+ service.addSessionDestroyListener(listener);
+
MockVaadinSession vaadinSession = new MockVaadinSession(service);
service.fireSessionDestroy(vaadinSession);
Assert.assertEquals(
@@ -45,9 +59,11 @@ public class VaadinServiceTest {
vaadinSession.valueUnbound(EasyMock
.createMock(HttpSessionBindingEvent.class));
- org.junit.Assert.assertEquals(
- "'fireSessionDestroy' method may not call 'close' "
- + "method for closing session", 1,
+ Assert.assertEquals("'fireSessionDestroy' method may not call 'close' "
+ + "method for closing session", 1,
vaadinSession.getCloseCount());
+
+ Assert.assertEquals("SessionDestroyListeners not called exactly once",
+ 1, listener.callCount);
}
}
diff --git a/server/tests/src/com/vaadin/server/VaadinWebSpherePortalRequestTests.java b/server/tests/src/com/vaadin/server/VaadinWebSpherePortalRequestTests.java
new file mode 100644
index 0000000000..0da85c7111
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/VaadinWebSpherePortalRequestTests.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2013 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 static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import com.vaadin.server.VaadinPortlet.VaadinWebSpherePortalRequest;
+
+public class VaadinWebSpherePortalRequestTests extends
+ VaadinHttpAndPortletRequestTests<VaadinWebSpherePortalRequest> {
+
+ @Override
+ protected VaadinWebSpherePortalRequest createSut() {
+
+ VaadinWebSpherePortalRequest request = new VaadinWebSpherePortalRequest(
+ portletRequest, vaadinPortletService);
+
+ // Although partial mocking can be considered a code smell,
+ // here it's actually quite useful to mock reflection calls.
+ VaadinWebSpherePortalRequest spy = spy(request);
+ doReturn(servletRequest).when(spy).getServletRequest(portletRequest);
+
+ return spy;
+ }
+} \ No newline at end of file
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/LayoutSettingsOnReplace.java b/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/LayoutSettingsOnReplace.java
new file mode 100644
index 0000000000..0af21d8cb8
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/LayoutSettingsOnReplace.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2013 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.tests.server.component.abstractorderedlayout;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.AbstractOrderedLayout;
+import com.vaadin.ui.Alignment;
+
+/**
+ * Tests for abstract layout settings which should be preserved on replace
+ * component
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public class LayoutSettingsOnReplace {
+
+ @Test
+ public void testExpandRatio() {
+ AbstractOrderedLayout layout = new AbstractOrderedLayout() {
+ };
+
+ AbstractComponent first = new AbstractComponent() {
+ };
+ AbstractComponent second = new AbstractComponent() {
+ };
+
+ layout.addComponent(first);
+ layout.addComponent(second);
+
+ int ratio = 2;
+ layout.setExpandRatio(first, ratio);
+ layout.setExpandRatio(second, 1);
+
+ AbstractComponent replace = new AbstractComponent() {
+ };
+ layout.replaceComponent(first, replace);
+
+ Assert.assertEquals("Expand ratio for replaced component is not "
+ + "the same as for previous one", ratio,
+ layout.getExpandRatio(replace), 0.0001);
+ }
+
+ @Test
+ public void testAlignment() {
+ AbstractOrderedLayout layout = new AbstractOrderedLayout() {
+ };
+
+ AbstractComponent first = new AbstractComponent() {
+ };
+ AbstractComponent second = new AbstractComponent() {
+ };
+
+ layout.addComponent(first);
+ layout.addComponent(second);
+
+ Alignment alignment = Alignment.BOTTOM_RIGHT;
+ layout.setComponentAlignment(first, alignment);
+ layout.setComponentAlignment(second, Alignment.MIDDLE_CENTER);
+
+ AbstractComponent replace = new AbstractComponent() {
+ };
+ layout.replaceComponent(first, replace);
+
+ Assert.assertEquals("Alignment for replaced component is not "
+ + "the same as for previous one", alignment,
+ layout.getComponentAlignment(replace));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java b/server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java
new file mode 100644
index 0000000000..2cd19ee153
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2013 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.tests.server.component.window;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Window;
+
+public class WindowTest {
+
+ public Window window;
+
+ @Before
+ public void setup() {
+ window = new Window();
+ }
+
+ @Test
+ public void testAssistiveDescription() {
+ Label l1 = new Label("label 1");
+ Button b2 = new Button("button 2");
+ window.setAssistiveDescription(l1, b2);
+
+ Assert.assertEquals(2, window.getAssistiveDescription().length);
+ Assert.assertEquals(l1, window.getAssistiveDescription()[0]);
+ Assert.assertEquals(b2, window.getAssistiveDescription()[1]);
+
+ // Modifying return value must not change actual value
+ window.getAssistiveDescription()[0] = null;
+
+ Assert.assertEquals(2, window.getAssistiveDescription().length);
+ Assert.assertEquals(l1, window.getAssistiveDescription()[0]);
+ Assert.assertEquals(b2, window.getAssistiveDescription()[1]);
+
+ }
+}