1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.form.field.upload.basic;
35
36 import info.magnolia.i18nsystem.SimpleTranslator;
37 import info.magnolia.ui.api.context.UiContext;
38 import info.magnolia.ui.form.field.definition.BasicUploadFieldDefinition;
39 import info.magnolia.ui.form.field.upload.AbstractUploadField;
40 import info.magnolia.ui.form.field.upload.UploadProgressIndicator;
41 import info.magnolia.ui.form.field.upload.UploadReceiver;
42 import info.magnolia.ui.imageprovider.ImageProvider;
43 import info.magnolia.ui.vaadin.overlay.MessageStyleTypeEnum;
44
45 import org.apache.commons.io.FileUtils;
46 import org.apache.commons.lang3.StringUtils;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 import com.vaadin.ui.Alignment;
51 import com.vaadin.ui.Button;
52 import com.vaadin.ui.Button.ClickEvent;
53 import com.vaadin.ui.Component;
54 import com.vaadin.ui.CssLayout;
55 import com.vaadin.ui.FormLayout;
56 import com.vaadin.ui.Layout;
57 import com.vaadin.ui.NativeButton;
58 import com.vaadin.v7.data.Property;
59 import com.vaadin.v7.shared.ui.label.ContentMode;
60 import com.vaadin.v7.ui.HorizontalLayout;
61 import com.vaadin.v7.ui.Label;
62 import com.vaadin.v7.ui.TextField;
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 @Deprecated
79 public class BasicUploadField<T extends UploadReceiver> extends AbstractUploadField<T> {
80 private static final long serialVersionUID = 1L;
81 private static final Logger log = LoggerFactory.getLogger(BasicUploadField.class);
82
83 private static final String PREFIX_MEDIA_KEY = "field.upload.media";
84 private static final String MEDIA = "media";
85
86
87 private final CssLayout layout;
88 private UploadProgressIndicator progress;
89 protected final ImageProvider imageProvider;
90 private boolean editFileName = false;
91 private boolean editFileFormat = false;
92 protected UiContext uiContext;
93 private final SimpleTranslator i18n;
94
95 public BasicUploadField(ImageProvider imageProvider, UiContext uiContext, BasicUploadFieldDefinition definition, SimpleTranslator i18n) {
96 super();
97
98 populateFromDefinition(definition);
99
100 this.imageProvider = imageProvider;
101 this.layout = new CssLayout();
102 this.layout.setSizeUndefined();
103 this.uiContext = uiContext;
104 this.i18n = i18n;
105
106 setRootLayout(createDropZone(layout));
107
108 addStyleName("upload-image-field");
109 addStyleName("no-horizontal-drag-hints");
110 addStyleName("no-vertical-drag-hints");
111 }
112
113
114
115
116
117
118
119 @Override
120 public void attach() {
121 super.attach();
122 updateDisplay();
123 log.debug("Component was attached ...");
124 }
125
126
127
128
129
130
131
132 @Override
133 protected void buildEmptyLayout() {
134 layout.removeAllComponents();
135 if (isReadOnly()) {
136 return;
137 }
138
139 getUpload().setButtonCaption(getCaption(selectNewCaption, null));
140 layout.addComponent(getUpload());
141
142 Label uploadText = new Label(getCaption(dropZoneCaption, null), ContentMode.HTML);
143 uploadText.addStyleName("upload-text");
144 layout.addComponent(uploadText);
145
146
147 getRootLayout().removeStyleName("start");
148 getRootLayout().removeStyleName("done");
149 getRootLayout().removeStyleName("in-progress");
150 getRootLayout().addStyleName("upload");
151 getRootLayout().addStyleName("initial");
152
153 log.debug("buildEmptyLayout() called ...");
154 }
155
156
157
158
159
160
161
162 @Override
163 protected void buildInProgressLayout(String uploadedFileMimeType) {
164 layout.removeAllComponents();
165
166 setCaptionExtension(uploadedFileMimeType);
167
168 progress = new BasicUploadProgressIndicator(inProgressCaption, inProgressRatioCaption, i18n);
169 progress.setVisible(true);
170 progress.setProgress(0);
171 layout.addComponent(progress.asVaadinComponent());
172
173
174 layout.addComponent(createCancelButton());
175
176
177 getRootLayout().removeStyleName("done");
178 getRootLayout().addStyleName("upload");
179 getRootLayout().addStyleName("initial");
180 getRootLayout().addStyleName("in-progress");
181
182 log.debug("buildInProgressLayout() called ...");
183 }
184
185 @Override
186 protected void refreshInProgressLayout(long readBytes, long contentLength, String fileName) {
187 if (progress != null) {
188 progress.refreshLayout(readBytes, contentLength, fileName);
189 }
190 }
191
192
193
194
195
196
197
198
199
200
201
202 @Override
203 protected void buildCompletedLayout() {
204 layout.removeAllComponents();
205
206 setCaptionExtension(null);
207
208 layout.addComponent(createFileInfoComponent());
209
210 layout.addComponent(createCompletedActionLayout());
211
212
213 layout.addComponent(createThumbnailComponent());
214
215
216 getRootLayout().addStyleName("upload");
217 getRootLayout().removeStyleName("in-progress");
218 getRootLayout().removeStyleName("initial");
219 getRootLayout().addStyleName("done");
220
221 log.debug("buildCompletedLayout() called ...");
222 }
223
224
225
226
227 protected Layout createCompletedActionLayout() {
228
229 HorizontalLayout actionLayout = new HorizontalLayout();
230 actionLayout.setSizeUndefined();
231 actionLayout.addStyleName("buttons");
232 actionLayout.setSpacing(true);
233
234 getUpload().setButtonCaption(getCaption(selectAnotherCaption, null));
235 actionLayout.addComponent(getUpload());
236
237 if (!getValue().isEmpty()) {
238 Button delete = createDeleteButton();
239 actionLayout.addComponent(delete);
240 actionLayout.setComponentAlignment(delete, Alignment.MIDDLE_RIGHT);
241 }
242 return actionLayout;
243 }
244
245
246
247
248
249 private Button createCancelButton() {
250 Button cancelButton = new NativeButton(null, new Button.ClickListener() {
251 private static final long serialVersionUID = 1L;
252
253 @Override
254 public void buttonClick(ClickEvent event) {
255 interruptUpload(InterruptionReason.USER);
256 }
257 });
258 cancelButton.addStyleName("cancel");
259 return cancelButton;
260 }
261
262
263
264
265 protected Button createDeleteButton() {
266 Button deleteButton = new Button();
267 deleteButton.setHtmlContentAllowed(true);
268 deleteButton.setCaption("<span class=\"" + "icon-trash" + "\"></span>");
269 deleteButton.addStyleName("inline");
270 deleteButton.setDescription(i18n.translate(deleteCaption));
271
272 deleteButton.addClickListener(new Button.ClickListener() {
273 private static final long serialVersionUID = 1L;
274
275 @Override
276 public void buttonClick(ClickEvent event) {
277 resetDataSource();
278 updateDisplay();
279 }
280 });
281 return deleteButton;
282 }
283
284
285
286
287
288
289
290 private Component createFileInfoComponent() {
291 FormLayout fileInfo = new FormLayout();
292 fileInfo.setSizeUndefined();
293 fileInfo.addStyleName("file-details");
294 fileInfo.addComponent(getFileDetailHeader());
295 fileInfo.addComponent(getFileDetailFileName());
296 fileInfo.addComponent(getFileDetailSize());
297 fileInfo.addComponent(getFileDetailFileFormat());
298 return fileInfo;
299 }
300
301
302
303
304 protected Component getFileDetailHeader() {
305 Label label = new Label();
306 label.setValue(getCaption(fileDetailHeaderCaption, null));
307 return label;
308 }
309
310
311
312
313
314
315 protected Component getFileDetailFileName() {
316
317 final boolean hasExtension = StringUtils.isNotBlank(getValue().getExtension());
318 final String extension = hasExtension ? "." + getValue().getExtension() : "";
319 String fileName = StringUtils.removeEnd(getValue().getFileName(), extension);
320
321 if (this.editFileName && !isReadOnly()) {
322 TextField textField = new TextField(i18n.translate(fileDetailNameCaption), fileName);
323 textField.setNullRepresentation("");
324 textField.setCaption(i18n.translate(fileDetailNameCaption));
325 textField.addValueChangeListener(new Property.ValueChangeListener() {
326 @Override
327 public void valueChange(Property.ValueChangeEvent event) {
328 Object newFileNameObject = event.getProperty().getValue();
329 String newFileName = (newFileNameObject != null && StringUtils.isNotBlank(newFileNameObject.toString())) ? newFileNameObject.toString() : UploadReceiver.INVALID_FILE_NAME;
330 getValue().setFileName(newFileName + extension);
331 getPropertyDataSource().setValue(getValue());
332 }
333 });
334 return textField;
335 } else {
336 Label label = new Label();
337 label.setCaption(i18n.translate(fileDetailNameCaption));
338 label.setValue(fileName);
339 return label;
340 }
341 }
342
343
344
345
346 protected Component getFileDetailSize() {
347 Label label = new Label();
348 label.setCaption(i18n.translate(fileDetailSizeCaption));
349 label.setValue(FileUtils.byteCountToDisplaySize(getValue().getFileSize()));
350 return label;
351 }
352
353
354
355
356
357
358 protected Component getFileDetailFileFormat() {
359 if (this.editFileFormat && !isReadOnly()) {
360 TextField textField = new TextField(i18n.translate(fileDetailFormatCaption), getValue().getExtension());
361 textField.setNullRepresentation("");
362 textField.setCaption(i18n.translate(fileDetailFormatCaption));
363 return textField;
364 } else {
365 Label label = new Label();
366 label.setValue(getValue().getExtension());
367 label.setCaption(i18n.translate(fileDetailFormatCaption));
368 return label;
369 }
370 }
371
372
373
374
375 protected Component createThumbnailComponent() {
376 Label thumbnail = new Label();
377 thumbnail.setSizeUndefined();
378 thumbnail.addStyleName("preview-image");
379 thumbnail.addStyleName("file-preview");
380 thumbnail.addStyleName(createIconStyleName());
381 return thumbnail;
382 }
383
384
385
386
387
388
389
390 protected String createIconStyleName() {
391 return "icon-" + imageProvider.resolveIconClassName(getValue().getMimeType());
392 }
393
394 @Override
395 protected Component initContent() {
396 return getRootLayout();
397 }
398
399
400
401
402 protected void populateFromDefinition(BasicUploadFieldDefinition definition) {
403 this.setMaxUploadSize(definition.getMaxUploadSize());
404 this.setAllowedMimeTypePattern(definition.getAllowedMimeTypePattern());
405
406 this.setSelectNewCaption(definition.getSelectNewCaption());
407 this.setSelectAnotherCaption(definition.getSelectAnotherCaption());
408 this.setDropZoneCaption(definition.getDropZoneCaption());
409 this.setInProgressCaption(definition.getInProgressCaption());
410 this.setInProgressRatioCaption(definition.getInProgressRatioCaption());
411 this.setFileDetailHeaderCaption(definition.getFileDetailHeaderCaption());
412 this.setFileDetailNameCaption(definition.getFileDetailNameCaption());
413 this.setFileDetailSizeCaption(definition.getFileDetailSizeCaption());
414 this.setFileDetailFormatCaption(definition.getFileDetailFormatCaption());
415 this.setFileDetailSourceCaption(definition.getFileDetailSourceCaption());
416 this.setSuccessNoteCaption(definition.getSuccessNoteCaption());
417 this.setWarningNoteCaption(definition.getWarningNoteCaption());
418 this.setErrorNoteCaption(definition.getErrorNoteCaption());
419 this.setDeteteCaption(definition.getDeleteCaption());
420 this.setEditFileFormat(definition.isEditFileFormat());
421 this.setEditFileName(definition.isEditFileName());
422 this.setUserInterruption(definition.getUserInterruption());
423 this.setTypeInterruption(definition.getTypeInterruption());
424 this.setSizeInterruption(definition.getSizeInterruption());
425 }
426
427
428
429
430 protected String captionExtension;
431
432 protected void setCaptionExtension(String mimeType) {
433 captionExtension = "";
434 }
435
436 protected String getCaption(String caption, String[] args) {
437 if (StringUtils.isEmpty(caption)) {
438 return "";
439 }
440 if (StringUtils.isNotBlank(captionExtension)) {
441 String mediaName = i18n.translate(PREFIX_MEDIA_KEY + '.' + captionExtension);
442 String[] paras;
443 if (args != null && args.length > 0) {
444 paras = new String[args.length + 1];
445 paras[0] = mediaName;
446 System.arraycopy(args, 0, paras, 1, args.length);
447 } else {
448 paras = new String[] { mediaName };
449 }
450 return i18n.translate(caption + '.' + MEDIA, paras);
451 }
452 if (args != null && args.length > 0) {
453 return i18n.translate(caption, args);
454 } else {
455 return i18n.translate(caption);
456 }
457 }
458
459 protected String selectNewCaption;
460 protected String selectAnotherCaption;
461 protected String deleteCaption;
462 protected String dropZoneCaption;
463 protected String inProgressCaption;
464 protected String inProgressRatioCaption;
465 protected String fileDetailHeaderCaption;
466 protected String fileDetailNameCaption;
467 protected String fileDetailSizeCaption;
468 protected String fileDetailFormatCaption;
469 protected String fileDetailSourceCaption;
470 protected String successNoteCaption;
471 protected String warningNoteCaption;
472 protected String errorNoteCaption;
473 private String sizeInterruption;
474 private String typeInterruption;
475 private String userInterruption;
476
477 public void setSelectNewCaption(String selectNewCaption) {
478 this.selectNewCaption = selectNewCaption;
479 }
480
481 public void setSelectAnotherCaption(String selectAnotherCaption) {
482 this.selectAnotherCaption = selectAnotherCaption;
483 }
484
485 public void setDropZoneCaption(String dropZoneCaption) {
486 this.dropZoneCaption = dropZoneCaption;
487 }
488
489 public void setInProgressCaption(String inProgressCaption) {
490 this.inProgressCaption = inProgressCaption;
491 }
492
493 public void setInProgressRatioCaption(String inProgressRatioCaption) {
494 this.inProgressRatioCaption = inProgressRatioCaption;
495 }
496
497 public void setFileDetailHeaderCaption(String fileDetailHeaderCaption) {
498 this.fileDetailHeaderCaption = fileDetailHeaderCaption;
499 }
500
501 public void setFileDetailNameCaption(String fileDetailNameCaption) {
502 this.fileDetailNameCaption = fileDetailNameCaption;
503 }
504
505 public void setFileDetailSizeCaption(String fileDetailSizeCaption) {
506 this.fileDetailSizeCaption = fileDetailSizeCaption;
507 }
508
509 public void setFileDetailFormatCaption(String fileDetailFormatCaption) {
510 this.fileDetailFormatCaption = fileDetailFormatCaption;
511 }
512
513 public void setFileDetailSourceCaption(String fileDetailSourceCaption) {
514 this.fileDetailSourceCaption = fileDetailSourceCaption;
515 }
516
517 public void setSuccessNoteCaption(String successNoteCaption) {
518 this.successNoteCaption = successNoteCaption;
519 }
520
521 public void setWarningNoteCaption(String warningNoteCaption) {
522 this.warningNoteCaption = warningNoteCaption;
523 }
524
525 public void setErrorNoteCaption(String errorNoteCaption) {
526 this.errorNoteCaption = errorNoteCaption;
527 }
528
529 public void setDeteteCaption(String deleteCaption) {
530 this.deleteCaption = deleteCaption;
531 }
532
533 public void setSizeInterruption(String sizeInterruption) {
534 this.sizeInterruption = sizeInterruption;
535 }
536
537 public void setTypeInterruption(String typeInterruption) {
538 this.typeInterruption = typeInterruption;
539 }
540
541 public void setUserInterruption(String userInterruption) {
542 this.userInterruption = userInterruption;
543 }
544
545 @Override
546 protected void displayUploadInterruptNote(InterruptionReason reason) {
547 String caption = "";
548 if (reason.equals(InterruptionReason.USER)) {
549 caption = userInterruption;
550 } else if (reason.equals(InterruptionReason.FILE_SIZE)) {
551 caption = sizeInterruption;
552 } else {
553 caption = typeInterruption;
554 }
555 uiContext.openNotification(MessageStyleTypeEnum.WARNING, true, getCaption(warningNoteCaption, new String[] { i18n.translate(caption) }));
556 }
557
558 @Override
559 protected void displayUploadFinishedNote(String fileName) {
560 uiContext.openNotification(MessageStyleTypeEnum.INFO, true, getCaption(successNoteCaption, new String[] { fileName }));
561 }
562
563 @Override
564 protected void displayUploadFailedNote(String fileName) {
565 uiContext.openAlert(MessageStyleTypeEnum.ERROR, "ERROR", getCaption(errorNoteCaption, new String[] { fileName }), i18n.translate("button.ok"), null);
566 }
567
568 public void setEditFileName(boolean editFileName) {
569 this.editFileName = editFileName;
570 }
571
572 public void setEditFileFormat(boolean editFileFormat) {
573 this.editFileFormat = editFileFormat;
574 }
575
576
577
578
579 public CssLayout getCssLayout() {
580 return this.layout;
581 }
582
583 @Override
584 public boolean isEmpty() {
585 return getValue().isEmpty();
586 }
587
588 @Override
589 public void setReadOnly(boolean readOnly) {
590 super.setReadOnly(readOnly);
591 if (readOnly) {
592
593 if (getDropZone() != null) {
594 getDropZone().setDropHandler(null);
595 }
596 if (getUpload() != null) {
597 getUpload().removeStartedListener(this);
598 getUpload().removeFinishedListener(this);
599 getUpload().removeProgressListener(this);
600 }
601 if (getValue().isEmpty()) {
602 buildEmptyLayout();
603 }
604 }
605
606 }
607 }