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.dam.app.ui.field.upload;
35
36 import info.magnolia.dam.app.ui.field.configuration.PreviewComponentProvider;
37 import info.magnolia.dam.app.ui.field.configuration.ThumbnailComponentProvider;
38 import info.magnolia.dam.app.ui.field.definition.DamUploadFieldDefinition;
39 import info.magnolia.i18nsystem.SimpleTranslator;
40 import info.magnolia.objectfactory.ComponentProvider;
41 import info.magnolia.ui.api.context.UiContext;
42 import info.magnolia.ui.api.overlay.OverlayCloser;
43 import info.magnolia.ui.form.field.upload.basic.BasicUploadField;
44 import info.magnolia.ui.imageprovider.ImageProvider;
45 import info.magnolia.ui.mediaeditor.MediaEditorPresenter;
46 import info.magnolia.ui.mediaeditor.MediaEditorPresenterFactory;
47 import info.magnolia.ui.mediaeditor.event.MediaEditorCompletedEvent;
48 import info.magnolia.ui.vaadin.overlay.MessageStyleTypeEnum;
49
50 import java.io.FileInputStream;
51 import java.io.FileNotFoundException;
52 import java.io.InputStream;
53
54 import org.apache.commons.io.FileUtils;
55 import org.apache.commons.lang3.StringUtils;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59 import com.google.common.net.MediaType;
60 import com.vaadin.server.Resource;
61 import com.vaadin.server.StreamResource;
62 import com.vaadin.server.StreamResource.StreamSource;
63 import com.vaadin.ui.Alignment;
64 import com.vaadin.ui.Button;
65 import com.vaadin.ui.Button.ClickEvent;
66 import com.vaadin.ui.Component;
67 import com.vaadin.ui.CssLayout;
68 import com.vaadin.ui.HorizontalLayout;
69 import com.vaadin.ui.Label;
70 import com.vaadin.ui.Layout;
71 import com.vaadin.ui.NativeButton;
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 public class DamUploadField<D extends AssetUploadReceiver> extends BasicUploadField<D> {
93 private static final long serialVersionUID = 1L;
94 private static final Logger log = LoggerFactory.getLogger(DamUploadField.class);
95
96 private final SimpleTranslator i18n;
97
98
99 private MediaEditorPresenterFactory mediaEditorFactory;
100 private ComponentProvider componentProvider;
101 private String lightboxCaption;
102 private String editFileCaption;
103
104 public DamUploadField(ImageProvider imageProvider, UiContext uiContext, MediaEditorPresenterFactory mediaEditorFactory, ComponentProvider componentProvider, DamUploadFieldDefinition definition, SimpleTranslator i18n) {
105 super(imageProvider, uiContext, definition, i18n);
106
107 populateFromDefinition(definition);
108
109 this.mediaEditorFactory = mediaEditorFactory;
110 this.componentProvider = componentProvider;
111 this.i18n = i18n;
112 }
113
114
115
116
117 @Override
118 protected Component getFileDetailSize() {
119 Label label = new Label();
120 label.setCaption(i18n.translate(fileDetailSizeCaption));
121 StringBuilder sb = new StringBuilder();
122 if (getValue().isImage()) {
123 sb.append(getValue().getWidth() + " x " + getValue().getHeight() + ", ");
124 }
125 sb.append(FileUtils.byteCountToDisplaySize(getValue().getFileSize()));
126 if (getValue().getDuration() > 0) {
127 sb.append("(x:x min)");
128 }
129
130 label.setValue(sb.toString());
131 return label;
132 }
133
134
135
136
137
138 @Override
139 protected Layout createCompletedActionLayout() {
140 if (isReadOnly()) {
141 return new HorizontalLayout();
142 }
143
144 HorizontalLayout actionLayout = new HorizontalLayout();
145 actionLayout.setSizeUndefined();
146 actionLayout.addStyleName("buttons");
147 actionLayout.setSpacing(true);
148
149 if (getValue() != null && !getValue().isEmpty() && getValue().getEditAssetAppConfiguration().hasEditConfig()) {
150 Button edit = createEditButton();
151 actionLayout.addComponent(edit);
152 }
153
154 getUpload().setButtonCaption(getCaption(selectAnotherCaption, null));
155 actionLayout.addComponent(getUpload());
156
157 if (getValue() != null && !getValue().isEmpty()) {
158 Button delete = createDeleteButton();
159 actionLayout.addComponent(delete);
160 actionLayout.setComponentAlignment(delete, Alignment.MIDDLE_LEFT);
161 }
162 return actionLayout;
163 }
164
165
166
167
168
169 private Button createEditButton() {
170 Button editButton = new Button(getCaption(editFileCaption, null), createEditButtonListener());
171 editButton.setDisableOnClick(true);
172 editButton.addStyleName("edit");
173 return editButton;
174 }
175
176 private Button.ClickListener createEditButtonListener() {
177 return new Button.ClickListener() {
178 private static final long serialVersionUID = 1L;
179
180 @Override
181 public void buttonClick(ClickEvent event) {
182
183 try {
184 openMediaEditor();
185 } catch (FileNotFoundException fnfe) {
186 log.warn("could not open MediaEditor");
187 uiContext.openAlert(MessageStyleTypeEnum.ERROR, "ERROR", i18n.translate("dam.assets.uploadField.alert.couldNotOpenMediaEditor")
188 + " "
189 + getValue().getEditAssetAppConfiguration().getEditConfig().getMediaEditorId(),
190 "ok", null);
191 } finally {
192 event.getButton().setEnabled(true);
193 }
194 }
195 };
196 }
197
198
199
200
201
202
203
204 private void openMediaEditor() throws FileNotFoundException {
205
206 String presenterById = null;
207 if (getValue().getEditAssetAppConfiguration() == null || !getValue().getEditAssetAppConfiguration().hasEditConfig()) {
208 log.warn("No Media Editor defined for the following mimeType {} ", getValue().getMimeType());
209 return;
210 } else {
211 presenterById = "ui-mediaeditor:" + getValue().getEditAssetAppConfiguration().getEditConfig().getMediaEditorId();
212 log.debug("Will open the following mediaEditor Presenter {}", presenterById);
213 }
214
215 final NativeButton mediaEditorPlaceholder = new NativeButton(i18n.translate("dam.assets.uploadField.button.mediaEditorPlaceholder"));
216 mediaEditorPlaceholder.addStyleName("btn-form btn-form-commit");
217
218 MediaEditorPresenter mediaEditorPresenter = mediaEditorFactory.getPresenterById(presenterById);
219 final InputStream inputStream = new FileInputStream(getValue().getFile());
220 final OverlayCloser overlayCloser = uiContext.openOverlay(mediaEditorPresenter.start(inputStream));
221 mediaEditorPresenter.addCompletionHandler(new MediaEditorCompletedEvent.Handler() {
222 @Override
223 public void onSubmit(MediaEditorCompletedEvent event) {
224 final InputStream is = event.getStream();
225 getValue().updateContent(event.getStream());
226
227 updateDisplay();
228 overlayCloser.close();
229 closeInputStream(inputStream);
230 getPropertyDataSource().setValue(getValue());
231 }
232
233 @Override
234 public void onCancel(MediaEditorCompletedEvent event) {
235 overlayCloser.close();
236 closeInputStream(inputStream);
237 }
238
239 private void closeInputStream(InputStream inputStream) {
240 try {
241 if (inputStream != null) {
242 inputStream.close();
243 }
244 } catch (Exception e) {
245 log.warn("Could not close the InputStream ", e);
246 }
247 }
248 });
249 }
250
251
252
253
254
255
256
257
258 @Override
259 protected Component createThumbnailComponent() {
260
261 CssLayout previewLayout = new CssLayout();
262 previewLayout.addStyleName("file-preview-area");
263 previewLayout.setWidth("150px");
264 previewLayout.setHeight("150px");
265
266 Component image = createPreviewComponent();
267 if (image != null) {
268 image.addStyleName("preview-image");
269 previewLayout.addComponent(image);
270 }
271
272
273 if (getValue().getEditAssetAppConfiguration().hasEditConfig() && !isReadOnly()) {
274 Button editButton = new Button();
275 editButton.addStyleName("edit-button");
276 editButton.setHtmlContentAllowed(true);
277 editButton.setCaption("<span class=\"" + getValue().getEditAssetAppConfiguration().getEditConfig().getIconStyleName() + "\"></span>");
278 editButton.setDescription(getCaption(editFileCaption, null));
279 previewLayout.addComponent(editButton);
280
281
282 editButton.setDisableOnClick(true);
283 editButton.addClickListener(createEditButtonListener());
284 }
285
286
287 if (getValue().getEditAssetAppConfiguration().hasPreviewConfig()) {
288 Button lightboxButton = new Button();
289 lightboxButton.addStyleName("lightbox-button");
290 lightboxButton.setHtmlContentAllowed(true);
291 lightboxButton.setCaption("<span class=\"" + getValue().getEditAssetAppConfiguration().getPreviewConfig().getIconStyleName() + "\"></span>");
292 lightboxButton.setDescription(i18n.translate(lightboxCaption));
293 previewLayout.addComponent(lightboxButton);
294
295 lightboxButton.addClickListener(new Button.ClickListener() {
296 private static final long serialVersionUID = 1L;
297
298 @Override
299 public void buttonClick(ClickEvent event) {
300
301 Class<? extends PreviewComponentProvider> previewActionClass = getValue().getEditAssetAppConfiguration().getPreviewConfig().getPreviewComponentProviderClass();
302 if (previewActionClass != null) {
303 PreviewComponentProvider implementation = componentProvider.newInstance(previewActionClass);
304 implementation.open(getResource());
305 } else {
306 log.warn("No Preview Defined is defined ");
307 }
308 }
309 });
310 }
311 return previewLayout;
312 }
313
314
315
316
317
318
319 private Component createPreviewComponent() {
320 Class<? extends ThumbnailComponentProvider> thumbnailProviderClass = getValue().getEditAssetAppConfiguration().getThumbnailComponentProviderClass();
321 if (thumbnailProviderClass != null) {
322 ThumbnailComponentProvider implementation = componentProvider.newInstance(thumbnailProviderClass);
323 return implementation.createThumbnailComponent(null, getValue().getFile(), getValue().getMimeType());
324 } else {
325 log.warn("No ThumbnailComponentProvider is defined ");
326 return null;
327 }
328 }
329
330
331
332
333 private Resource getResource() {
334 final StreamSource source = new StreamResource.StreamSource() {
335 private static final long serialVersionUID = 1L;
336
337 @Override
338 public InputStream getStream() {
339 try {
340 return new FileInputStream(getValue().getFile());
341 } catch (FileNotFoundException fnfe) {
342 log.warn("could not found File", fnfe);
343 return null;
344 }
345 }
346 };
347
348 final Resource resource = new StreamResource(source, "") {
349 @Override
350 public String getMIMEType() {
351 return getValue().getMimeType();
352 }
353 };
354
355 return resource;
356 }
357
358 protected void populateFromDefinition(DamUploadFieldDefinition definition) {
359 super.populateFromDefinition(definition);
360 this.setLightboxCaption(definition.getLightboxCaption());
361 this.setEditFileCaption(definition.getEditFileCaption());
362 }
363
364
365
366
367 @Override
368 protected void setCaptionExtension(String mimeType) {
369 if (StringUtils.isNotBlank(mimeType)) {
370 captionExtension = MediaType.parse(mimeType).type();
371 } else if (StringUtils.isNotBlank(getValue().getMimeType())) {
372 captionExtension = MediaType.parse(getValue().getMimeType()).type();
373 }
374 }
375
376 public void setLightboxCaption(String lightboxCaption) {
377 this.lightboxCaption = lightboxCaption;
378 }
379
380 public void setEditFileCaption(String editFileCaption) {
381 this.editFileCaption = editFileCaption;
382 }
383 }