1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.vaadin.ui;
17
18 import java.io.OutputStream;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.Iterator;
22 import java.util.LinkedHashMap;
23 import java.util.Map;
24 import java.util.Map.Entry;
25 import java.util.Set;
26
27 import com.vaadin.event.Transferable;
28 import com.vaadin.event.TransferableImpl;
29 import com.vaadin.event.dd.DragSource;
30 import com.vaadin.event.dd.DropHandler;
31 import com.vaadin.event.dd.DropTarget;
32 import com.vaadin.event.dd.TargetDetails;
33 import com.vaadin.event.dd.TargetDetailsImpl;
34 import com.vaadin.server.PaintException;
35 import com.vaadin.server.PaintTarget;
36 import com.vaadin.server.StreamVariable;
37 import com.vaadin.shared.MouseEventDetails;
38 import com.vaadin.shared.ui.dd.HorizontalDropLocation;
39 import com.vaadin.shared.ui.dd.VerticalDropLocation;
40 import com.vaadin.shared.ui.draganddropwrapper.DragAndDropWrapperConstants;
41
42 @SuppressWarnings("serial")
43 public class DragAndDropWrapper extends CustomComponent implements DropTarget,
44 DragSource, LegacyComponent {
45
46 public class WrapperTransferable extends TransferableImpl {
47
48 private Html5File[] files;
49
50 public WrapperTransferable(Component sourceComponent,
51 Map<String, Object> rawVariables) {
52 super(sourceComponent, rawVariables);
53 Integer fc = (Integer) rawVariables.get("filecount");
54 if (fc != null) {
55 files = new Html5File[fc];
56 for (int i = 0; i < fc; i++) {
57 Html5File file = new Html5File(
58 (String) rawVariables.get("fn" + i),
59 (Integer) rawVariables.get("fs" + i),
60 (String) rawVariables.get("ft" + i));
61 String id = (String) rawVariables.get("fi" + i);
62 files[i] = file;
63 receivers.put(id, new ProxyReceiver(id, file));
64 markAsDirty();
65 }
66 }
67 }
68
69
70
71
72
73
74
75 public Component getDraggedComponent() {
76 Component object = (Component) getData("component");
77 return object;
78 }
79
80
81
82
83 public MouseEventDetails getMouseDownEvent() {
84 return MouseEventDetails.deSerialize((String) getData("mouseDown"));
85 }
86
87 public Html5File[] getFiles() {
88 return files;
89 }
90
91 public String getText() {
92 String data = (String) getData("Text");
93 if (data == null) {
94
95 data = (String) getData("text/plain");
96 }
97 return data;
98 }
99
100 public String getHtml() {
101 String data = (String) getData("Html");
102 if (data == null) {
103
104 data = (String) getData("text/html");
105 }
106 return data;
107 }
108
109 }
110
111 private Map<String, ProxyReceiver> receivers = new HashMap<String, ProxyReceiver>();
112
113 public class WrapperTargetDetails extends TargetDetailsImpl {
114
115 public WrapperTargetDetails(Map<String, Object> rawDropData) {
116 super(rawDropData, DragAndDropWrapper.this);
117 }
118
119
120
121
122 public Integer getAbsoluteLeft() {
123 return (Integer) getData("absoluteLeft");
124 }
125
126
127
128
129
130 public Integer getAbsoluteTop() {
131 return (Integer) getData("absoluteTop");
132 }
133
134
135
136
137
138 public MouseEventDetails getMouseEvent() {
139 return MouseEventDetails
140 .deSerialize((String) getData("mouseEvent"));
141 }
142
143
144
145
146 public VerticalDropLocation getVerticalDropLocation() {
147 return VerticalDropLocation
148 .valueOf((String) getData("verticalLocation"));
149 }
150
151
152
153
154
155 public HorizontalDropLocation getHorizontalDropLocation() {
156 return HorizontalDropLocation
157 .valueOf((String) getData("horizontalLocation"));
158 }
159
160 }
161
162 public enum DragStartMode {
163
164
165
166 NONE,
167
168
169
170 COMPONENT,
171
172
173
174 WRAPPER,
175
176
177
178
179
180
181
182 HTML5,
183 }
184
185 private final Map<String, Object> html5DataFlavors = new LinkedHashMap<String, Object>();
186 private DragStartMode dragStartMode = DragStartMode.NONE;
187
188 private Set<String> sentIds = new HashSet<String>();
189
190
191
192
193
194
195
196 public DragAndDropWrapper(Component root) {
197 super(root);
198 }
199
200
201
202
203
204
205
206
207
208
209
210
211 public void setHTML5DataFlavor(String type, Object value) {
212 html5DataFlavors.put(type, value);
213 markAsDirty();
214 }
215
216 @Override
217 public void changeVariables(Object source, Map<String, Object> variables) {
218
219 }
220
221 @Override
222 public void paintContent(PaintTarget target) throws PaintException {
223 target.addAttribute(DragAndDropWrapperConstants.DRAG_START_MODE,
224 dragStartMode.ordinal());
225 if (getDropHandler() != null) {
226 getDropHandler().getAcceptCriterion().paint(target);
227 }
228 if (receivers != null && receivers.size() > 0) {
229 for (Iterator<Entry<String, ProxyReceiver>> it = receivers
230 .entrySet().iterator(); it.hasNext();) {
231 Entry<String, ProxyReceiver> entry = it.next();
232 String id = entry.getKey();
233 ProxyReceiver proxyReceiver = entry.getValue();
234 Html5File html5File = proxyReceiver.file;
235 if (html5File.getStreamVariable() != null) {
236 if (!sentIds.contains(id)) {
237 target.addVariable(this, "rec-" + id,
238 new ProxyReceiver(id, html5File));
239
240
241
242
243
244
245
246
247
248
249 sentIds.add(id);
250
251
252
253 }
254 } else {
255
256 target.addVariable(this, "rec-" + id, (String) null);
257
258 it.remove();
259 }
260 }
261 }
262 target.addAttribute(DragAndDropWrapperConstants.HTML5_DATA_FLAVORS,
263 html5DataFlavors);
264 }
265
266 private DropHandler dropHandler;
267
268 @Override
269 public DropHandler getDropHandler() {
270 return dropHandler;
271 }
272
273 public void setDropHandler(DropHandler dropHandler) {
274 this.dropHandler = dropHandler;
275 markAsDirty();
276 }
277
278 @Override
279 public TargetDetails translateDropTargetDetails(
280 Map<String, Object> clientVariables) {
281 return new WrapperTargetDetails(clientVariables);
282 }
283
284 @Override
285 public Transferable getTransferable(final Map<String, Object> rawVariables) {
286 return new WrapperTransferable(this, rawVariables);
287 }
288
289 public void setDragStartMode(DragStartMode dragStartMode) {
290 this.dragStartMode = dragStartMode;
291 markAsDirty();
292 }
293
294 public DragStartMode getDragStartMode() {
295 return dragStartMode;
296 }
297
298 final class ProxyReceiver implements StreamVariable {
299
300 private String id;
301 private Html5File file;
302
303 public ProxyReceiver(String id, Html5File file) {
304 this.id = id;
305 this.file = file;
306 }
307
308 private boolean listenProgressOfUploadedFile;
309
310 @Override
311 public OutputStream getOutputStream() {
312 if (file.getStreamVariable() == null) {
313 return null;
314 }
315 return file.getStreamVariable().getOutputStream();
316 }
317
318 @Override
319 public boolean listenProgress() {
320 return file.getStreamVariable().listenProgress();
321 }
322
323 @Override
324 public void onProgress(StreamingProgressEvent event) {
325 file.getStreamVariable().onProgress(
326 new ReceivingEventWrapper(event));
327 }
328
329 @Override
330 public void streamingStarted(StreamingStartEvent event) {
331 listenProgressOfUploadedFile = file.getStreamVariable() != null;
332 if (listenProgressOfUploadedFile) {
333 file.getStreamVariable().streamingStarted(
334 new ReceivingEventWrapper(event));
335 }
336
337 receivers.remove(id);
338 sentIds.remove(id);
339 }
340
341 @Override
342 public void streamingFinished(StreamingEndEvent event) {
343 if (listenProgressOfUploadedFile) {
344 file.getStreamVariable().streamingFinished(
345 new ReceivingEventWrapper(event));
346 }
347 }
348
349 @Override
350 public void streamingFailed(final StreamingErrorEvent event) {
351 if (listenProgressOfUploadedFile) {
352 file.getStreamVariable().streamingFailed(
353 new ReceivingEventWrapper(event));
354 }
355 }
356
357 @Override
358 public boolean isInterrupted() {
359 return file.getStreamVariable().isInterrupted();
360 }
361
362
363
364
365
366
367
368 class ReceivingEventWrapper implements StreamingErrorEvent,
369 StreamingEndEvent, StreamingStartEvent, StreamingProgressEvent {
370
371 private StreamingEvent wrappedEvent;
372
373 ReceivingEventWrapper(StreamingEvent e) {
374 wrappedEvent = e;
375 }
376
377 @Override
378 public String getMimeType() {
379 return file.getType();
380 }
381
382 @Override
383 public String getFileName() {
384 return file.getFileName();
385 }
386
387 @Override
388 public long getContentLength() {
389 return file.getFileSize();
390 }
391
392 public StreamVariable getReceiver() {
393 return ProxyReceiver.this;
394 }
395
396 @Override
397 public Exception getException() {
398 if (wrappedEvent instanceof StreamingErrorEvent) {
399 return ((StreamingErrorEvent) wrappedEvent).getException();
400 }
401 return null;
402 }
403
404 @Override
405 public long getBytesReceived() {
406 return wrappedEvent.getBytesReceived();
407 }
408
409
410
411
412
413 @Override
414 public void disposeStreamVariable() {
415
416 }
417 }
418
419 }
420
421 }