diff options
author | Henrik Paul <henrik@vaadin.com> | 2013-08-15 08:59:03 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2013-08-15 10:49:25 +0000 |
commit | 36413cb556cee7a7024a552e3772a2369d8f0294 (patch) | |
tree | 0b603d5f0904413a683d8ec0fb2664e542ee9e4b | |
parent | f72be69c60432bb94251cd7a73ad167062f9c6a8 (diff) | |
download | vaadin-framework-36413cb556cee7a7024a552e3772a2369d8f0294.tar.gz vaadin-framework-36413cb556cee7a7024a552e3772a2369d8f0294.zip |
Make sure that no fileIds are replayed to the client (#12330)
Due to how ProxyReceivers are constructed and serialized, we don't want
to resend the ProxyReceivers for files that already are in the queue.
Either we needed to change the way ProxyReceivers behave, or just make
sure that they aren't resent. I chose the double-check method.
Change-Id: I7c4e866ba4287afd3e80329be3640335d4ff00af
-rw-r--r-- | server/src/com/vaadin/ui/DragAndDropWrapper.java | 27 | ||||
-rw-r--r-- | uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropBatchUpload.java | 132 |
2 files changed, 155 insertions, 4 deletions
diff --git a/server/src/com/vaadin/ui/DragAndDropWrapper.java b/server/src/com/vaadin/ui/DragAndDropWrapper.java index 6c6aa3c3f4..5d6825c868 100644 --- a/server/src/com/vaadin/ui/DragAndDropWrapper.java +++ b/server/src/com/vaadin/ui/DragAndDropWrapper.java @@ -17,10 +17,12 @@ package com.vaadin.ui; import java.io.OutputStream; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import com.vaadin.event.Transferable; import com.vaadin.event.TransferableImpl; @@ -183,6 +185,8 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, private final Map<String, Object> html5DataFlavors = new LinkedHashMap<String, Object>(); private DragStartMode dragStartMode = DragStartMode.NONE; + private Set<String> sentIds = new HashSet<String>(); + /** * Wraps given component in a {@link DragAndDropWrapper}. * @@ -229,10 +233,24 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, ProxyReceiver proxyReceiver = entry.getValue(); Html5File html5File = proxyReceiver.file; if (html5File.getStreamVariable() != null) { - target.addVariable(this, "rec-" + id, new ProxyReceiver(id, - html5File)); - // these are cleaned from receivers once the upload has - // started + if (!sentIds.contains(id)) { + target.addVariable(this, "rec-" + id, + new ProxyReceiver(id, html5File)); + + /* + * if a new batch is requested to be uploaded before the + * last one is done, any remaining ids will be replayed. + * We want to avoid a new ProxyReceiver to be made since + * it'll get a new URL, so we need to keep extra track + * on what has been sent. + * + * See #12330. + */ + sentIds.add(id); + + // these are cleaned from receivers once the upload has + // started + } } else { // instructs the client side not to send the file target.addVariable(this, "rec-" + id, (String) null); @@ -317,6 +335,7 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, } // no need tell to the client about this receiver on next paint receivers.remove(id); + sentIds.remove(id); // let the terminal GC the streamvariable and not to accept other // file uploads to this variable event.disposeStreamVariable(); diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropBatchUpload.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropBatchUpload.java new file mode 100644 index 0000000000..adb5cd9e3a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropBatchUpload.java @@ -0,0 +1,132 @@ +/* + * 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.components.draganddropwrapper; + +import java.io.OutputStream; + +import org.apache.commons.io.output.NullOutputStream; + +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.StreamVariable; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.tests.components.AbstractTestUI; +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; + +public class DragAndDropBatchUpload extends AbstractTestUI { + + private int batchId = 0; + private Label console = new Label("No activity detected yet", + ContentMode.HTML); + + @Override + protected void setup(VaadinRequest request) { + final DragAndDropWrapper dndWrapper = new DragAndDropWrapper( + new Button("Upload here by drag and dropping")); + dndWrapper.setDropHandler(new DropHandler() { + + @Override + public AcceptCriterion getAcceptCriterion() { + return AcceptAll.get(); + } + + @Override + public void drop(DragAndDropEvent event) { + Transferable transferable = event.getTransferable(); + String consoleString = "<b>Drop batch number " + (++batchId) + + "</b>"; + if (transferable instanceof WrapperTransferable) { + WrapperTransferable wTransferable = (WrapperTransferable) transferable; + Html5File[] files = wTransferable.getFiles(); + + if (files != null) { + consoleString += "<br>" + files.length + " file(s):"; + for (Html5File file : files) { + consoleString += "<br>" + file.getFileName(); + file.setStreamVariable(new StreamVariable() { + + @Override + public void streamingStarted( + StreamingStartEvent event) { + } + + @Override + public void streamingFinished( + StreamingEndEvent event) { + } + + @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(); + } + }); + } + } else { + consoleString += "<br>No files detected..."; + } + console.setValue(consoleString); + } else { + console.setValue(consoleString + + "<br>Something else than files were dragged"); + } + + } + }); + + addComponent(dndWrapper); + addComponent(console); + } + + @Override + protected String getTestDescription() { + return "Starting to upload a new batch before the old one must not reuse receivers"; + } + + @Override + protected Integer getTicketNumber() { + return 12330; + } + +} |