diff options
author | Jonatan Kronqvist <jonatan@vaadin.com> | 2014-04-14 11:53:11 +0300 |
---|---|---|
committer | Jonatan Kronqvist <jonatan@vaadin.com> | 2014-04-14 12:06:05 +0300 |
commit | 416e2f97bcaf93e4d2a782149a963fca95b8400e (patch) | |
tree | eac6d22107b7c2d7bf6371e5278078f02bb860e9 /server/src/com | |
parent | d2e24feb09ccba7f3a2f253687488774af2bc340 (diff) | |
parent | eda9edcbde781d29ff5939defb61ba5fb159e206 (diff) | |
download | vaadin-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/src/com')
-rw-r--r-- | server/src/com/vaadin/data/util/MethodProperty.java | 26 | ||||
-rw-r--r-- | server/src/com/vaadin/server/VaadinPortlet.java | 228 | ||||
-rw-r--r-- | server/src/com/vaadin/server/VaadinService.java | 12 | ||||
-rw-r--r-- | server/src/com/vaadin/server/VaadinSession.java | 82 | ||||
-rw-r--r-- | server/src/com/vaadin/server/communication/AtmospherePushConnection.java | 10 | ||||
-rw-r--r-- | server/src/com/vaadin/server/communication/PushHandler.java | 78 | ||||
-rw-r--r-- | server/src/com/vaadin/ui/AbstractOrderedLayout.java | 10 | ||||
-rw-r--r-- | server/src/com/vaadin/ui/ComboBox.java | 14 | ||||
-rw-r--r-- | server/src/com/vaadin/ui/UI.java | 3 | ||||
-rw-r--r-- | server/src/com/vaadin/ui/Window.java | 29 |
10 files changed, 343 insertions, 149 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; } /** |