]> source.dussan.org Git - vaadin-framework.git/commitdiff
Make UI.pushConnection transient to prevent null resource after deserialization ...
authorJohannes Dahlström <johannesd@vaadin.com>
Wed, 5 Jun 2013 13:20:27 +0000 (16:20 +0300)
committerVaadin Code Review <review@vaadin.com>
Thu, 6 Jun 2013 16:20:06 +0000 (16:20 +0000)
* PushConnection is not Serializable anymore
* AtmospherePushConnection fields are not transient
* UI.setSession calls setPushConnection(null) instead of pushConnection.disconnect()
* pushConnection.disconnect() asserts isConnected()
* If UI has a push connection, it should now always have isConnected() == true

Change-Id: I3c2e877b8e723b7cc2993cacd620920aecdef5fb

server/src/com/vaadin/server/communication/AtmospherePushConnection.java
server/src/com/vaadin/server/communication/PushConnection.java
server/src/com/vaadin/server/communication/PushHandler.java
server/src/com/vaadin/ui/UI.java

index 9e57ccb45d8c371615d464f00a20529655e5662c..e325550c4b10bec874171fb6caca886e89d2ea41 100644 (file)
@@ -93,12 +93,13 @@ public class AtmospherePushConnection implements PushConnection {
     }
 
     private UI ui;
-    private transient AtmosphereResource resource;
-    private transient Future<String> outgoingMessage;
-    private transient FragmentedMessage incomingMessage;
+    private AtmosphereResource resource;
+    private Future<String> outgoingMessage;
+    private FragmentedMessage incomingMessage;
 
-    public AtmospherePushConnection(UI ui) {
+    public AtmospherePushConnection(UI ui, AtmosphereResource resource) {
         this.ui = ui;
+        this.resource = resource;
     }
 
     @Override
@@ -176,21 +177,6 @@ public class AtmospherePushConnection implements PushConnection {
         }
     }
 
-    /**
-     * Associates this connection with the given AtmosphereResource. If there is
-     * a push pending, commits it.
-     * 
-     * @param resource
-     *            The AtmosphereResource representing the push channel.
-     * @throws IOException
-     */
-    protected void connect(AtmosphereResource resource) throws IOException {
-        this.resource = resource;
-    }
-
-    /**
-     * Returns whether this connection is currently open.
-     */
     @Override
     public boolean isConnected() {
         return resource != null
@@ -215,6 +201,8 @@ public class AtmospherePushConnection implements PushConnection {
 
     @Override
     public void disconnect() {
+        assert isConnected();
+
         if (outgoingMessage != null) {
             // Wait for the last message to be sent before closing the
             // connection (assumes that futures are completed in order)
index bb889984029a383374b4dbe9d8de99ecd3c9dc37..7f78d1d48e977772891251f2b43c2204c50e9943 100644 (file)
@@ -16,8 +16,6 @@
 
 package com.vaadin.server.communication;
 
-import java.io.Serializable;
-
 import com.vaadin.ui.UI;
 
 /**
@@ -27,18 +25,20 @@ import com.vaadin.ui.UI;
  * @author Vaadin Ltd
  * @since 7.1
  */
-public interface PushConnection extends Serializable {
+public interface PushConnection {
 
     /**
-     * Pushes pending state changes and client RPC calls to the client. It is
-     * NOT safe to invoke this method if not holding the session lock.
+     * Pushes pending state changes and client RPC calls to the client. Cannot
+     * be called if {@link #isConnected()} is false. It is NOT safe to invoke
+     * this method if not holding the session lock.
      * <p>
      * This is internal API; please use {@link UI#push()} instead.
      */
     public void push();
 
     /**
-     * Disconnects the connection.
+     * Closes the connection. Cannot be called if {@link #isConnected()} is
+     * false.
      */
     public void disconnect();
 
index 7efcb8fd8cf03ccb3206639809ac84bc9b0c8c46..6b853063a7baac965f2ec7ef496f088868105a92 100644 (file)
@@ -109,8 +109,7 @@ public class PushHandler implements AtmosphereHandler {
             resource.suspend();
 
             AtmospherePushConnection connection = new AtmospherePushConnection(
-                    ui);
-            connection.connect(resource);
+                    ui, resource);
 
             ui.setPushConnection(connection);
         }
@@ -305,12 +304,9 @@ public class PushHandler implements AtmosphereHandler {
     private static AtmospherePushConnection getConnectionForUI(UI ui) {
         PushConnection pushConnection = ui.getPushConnection();
         if (pushConnection instanceof AtmospherePushConnection) {
-            AtmospherePushConnection apc = (AtmospherePushConnection) pushConnection;
-            if (apc.isConnected()) {
-                return apc;
-            }
+            assert pushConnection.isConnected();
+            return (AtmospherePushConnection) pushConnection;
         }
-
         return null;
     }
 
@@ -374,11 +370,14 @@ public class PushHandler implements AtmosphereHandler {
      */
     private static void sendRefreshAndDisconnect(AtmosphereResource resource)
             throws IOException {
-        AtmospherePushConnection connection = new AtmospherePushConnection(null);
-        connection.connect(resource);
-        connection.sendMessage(VaadinService.createCriticalNotificationJSON(
-                null, null, null, null));
-        connection.disconnect();
+        AtmospherePushConnection connection = new AtmospherePushConnection(
+                null, resource);
+        try {
+            connection.sendMessage(VaadinService
+                    .createCriticalNotificationJSON(null, null, null, null));
+        } finally {
+            connection.disconnect();
+        }
     }
 
     private static final Logger getLogger() {
index fa38666dc2982bf0bd0b96c55887ae719cbb5ee1..6c9551ea81f2c65946c4c6a45d793bd060e7c019 100644 (file)
@@ -411,12 +411,9 @@ public abstract class UI extends AbstractSingleComponentContainer implements
         } else {
             if (session == null) {
                 detach();
-                if (pushConnection != null && pushConnection.isConnected()) {
-                    // Close the push connection when UI is detached. Otherwise
-                    // the push connection and possibly VaadinSession will live
-                    // on.
-                    pushConnection.disconnect();
-                }
+                // Close the push connection when UI is detached. Otherwise the
+                // push connection and possibly VaadinSession will live on.
+                setPushConnection(null);
             }
             this.session = session;
         }
@@ -536,7 +533,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
 
     private Navigator navigator;
 
-    private PushConnection pushConnection = null;
+    private transient PushConnection pushConnection = null;
 
     private boolean hasPendingPush = false;
 
@@ -1072,7 +1069,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
 
         boolean sessionExpired = (session == null || session.isClosing());
         getRpcProxy(UIClientRpc.class).uiClosed(sessionExpired);
-        if (getPushConnection() != null && getPushConnection().isConnected()) {
+        if (getPushConnection() != null) {
             // Push the Rpc to the client. The connection will be closed when
             // the UI is detached and cleaned up.
             getPushConnection().push();
@@ -1342,19 +1339,24 @@ public abstract class UI extends AbstractSingleComponentContainer implements
 
     /**
      * Returns the internal push connection object used by this UI. This method
-     * should only be called by the framework.
+     * should only be called by the framework. If the returned PushConnection is
+     * not null, it is guaranteed to have {@code isConnected() == true}.
      */
     public PushConnection getPushConnection() {
+        assert (pushConnection == null || pushConnection.isConnected());
         return pushConnection;
     }
 
     /**
      * Sets the internal push connection object used by this UI. This method
-     * should only be called by the framework.
+     * should only be called by the framework. If {@pushConnection} is not null,
+     * its {@code isConnected()} must be true.
      */
     public void setPushConnection(PushConnection pushConnection) {
         // If pushMode is disabled then there should never be a pushConnection
-        assert (getPushConfiguration().getPushMode().isEnabled() || pushConnection == null);
+        assert (pushConnection == null || getPushConfiguration().getPushMode()
+                .isEnabled());
+        assert (pushConnection == null || pushConnection.isConnected());
 
         if (pushConnection == this.pushConnection) {
             return;