]> source.dussan.org Git - vaadin-framework.git/commitdiff
Properly cleanup stream variables if DragAndDropWrapper is detached (#14882)
authorArtur Signell <artur@vaadin.com>
Wed, 30 Sep 2015 14:05:24 +0000 (17:05 +0300)
committerVaadin Code Review <review@vaadin.com>
Mon, 5 Oct 2015 10:17:07 +0000 (10:17 +0000)
If DragAndDropWrapper is removed from the UI for whatever reason before cleanup
happens, the UI can no longer be found through it. If we do not do cleanup, we
leave a reference hanging forever in ConnectorTracker.

Change-Id: I9fc3da5d616276a7810ddc4a18cbebf8621635fe

server/src/com/vaadin/server/communication/FileUploadHandler.java
uitest/src/com/vaadin/tests/components/draganddropwrapper/SingleUseDragAndDropUpload.java [new file with mode: 0644]

index 532c7fe95b0631d6f5a3bbdaf64fc9ed7267dcb9..b9eaff3bd17894101dceea266d2b61fd4a216ebc 100644 (file)
@@ -450,10 +450,13 @@ public class FileUploadHandler implements RequestHandler {
             session.unlock();
         }
         try {
+            // Store ui reference so we can do cleanup even if connector is
+            // detached in some event handler
+            UI ui = connector.getUI();
             boolean forgetVariable = streamToReceiver(session, inputStream,
                     streamVariable, filename, mimeType, contentLength);
             if (forgetVariable) {
-                cleanStreamVariable(session, connector, variableName);
+                cleanStreamVariable(session, ui, connector, variableName);
             }
         } catch (Exception e) {
             session.lock();
@@ -684,15 +687,13 @@ public class FileUploadHandler implements RequestHandler {
         out.close();
     }
 
-    private void cleanStreamVariable(VaadinSession session,
+    private void cleanStreamVariable(VaadinSession session, final UI ui,
             final ClientConnector owner, final String variableName) {
         session.accessSynchronously(new Runnable() {
             @Override
             public void run() {
-                owner.getUI()
-                        .getConnectorTracker()
-                        .cleanStreamVariable(owner.getConnectorId(),
-                                variableName);
+                ui.getConnectorTracker().cleanStreamVariable(
+                        owner.getConnectorId(), variableName);
             }
         });
     }
diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/SingleUseDragAndDropUpload.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/SingleUseDragAndDropUpload.java
new file mode 100644 (file)
index 0000000..7c7e17a
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2000-2014 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.components.draganddropwrapper;
+
+import java.io.OutputStream;
+
+import org.apache.commons.io.output.NullOutputStream;
+
+import com.vaadin.annotations.Theme;
+import com.vaadin.event.Transferable;
+import com.vaadin.event.dd.DragAndDropEvent;
+import com.vaadin.event.dd.DropHandler;
+import com.vaadin.event.dd.acceptcriteria.AcceptAll;
+import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
+import com.vaadin.server.FontAwesome;
+import com.vaadin.server.StreamVariable;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.DragAndDropWrapper;
+import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable;
+import com.vaadin.ui.Html5File;
+import com.vaadin.ui.Label;
+
+@Theme("valo")
+public class SingleUseDragAndDropUpload extends AbstractTestUIWithLog {
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        Label upload = new Label(FontAwesome.UPLOAD.getHtml(), ContentMode.HTML);
+        upload.setSizeUndefined();
+        upload.setStyleName("upload");
+        getPage()
+                .getStyles()
+                .add(".upload{ font-size: 36px; border: 1px solid black; padding:15px;}");
+
+        final DragAndDropWrapper dnd = new DragAndDropWrapper(upload);
+        dnd.setSizeUndefined();
+        addComponent(dnd);
+        dnd.setDropHandler(new DropHandler() {
+
+            @Override
+            public AcceptCriterion getAcceptCriterion() {
+                return AcceptAll.get();
+            }
+
+            @Override
+            public void drop(DragAndDropEvent event) {
+                Transferable transferable = event.getTransferable();
+                log("Drop occured");
+                if (transferable instanceof WrapperTransferable) {
+                    WrapperTransferable wTransferable = (WrapperTransferable) transferable;
+                    Html5File[] files = wTransferable.getFiles();
+
+                    if (files != null) {
+                        for (Html5File file : files) {
+                            log("Uploading file " + file.getFileName());
+                            file.setStreamVariable(new StreamVariable() {
+
+                                @Override
+                                public void streamingStarted(
+                                        StreamingStartEvent event) {
+                                    log("Streaming started");
+                                }
+
+                                @Override
+                                public void streamingFinished(
+                                        StreamingEndEvent event) {
+                                    log("Streaming finished");
+                                    removeComponent(dnd);
+                                    log("DragAndDropWrapper removed");
+                                }
+
+                                @Override
+                                public void streamingFailed(
+                                        StreamingErrorEvent event) {
+                                }
+
+                                @Override
+                                public void onProgress(
+                                        StreamingProgressEvent event) {
+                                }
+
+                                @Override
+                                public boolean listenProgress() {
+                                    return false;
+                                }
+
+                                @Override
+                                public boolean isInterrupted() {
+                                    return false;
+                                }
+
+                                @Override
+                                public OutputStream getOutputStream() {
+                                    return new NullOutputStream();
+                                }
+                            });
+                        }
+                    }
+                }
+            }
+        });
+        addComponent(new Button("Poll for changes"));
+    }
+
+    @Override
+    protected String getTestDescription() {
+        return "Drag a file to the upload icon and ensure there is no exceptions logged in the console";
+    }
+}