blob: 84b7136e65596caed02db7418932e166f8c54092 [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
* Jose Dominguez (Compex Systemhaus GmbH) - ongoing development
*/
package org.eclipse.osbp.blob.component;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.osbp.blob.service.BlobService;
import org.eclipse.osbp.ui.api.customfields.IBlobEvent;
import org.eclipse.osbp.ui.api.customfields.IBlobService;
import org.eclipse.osbp.ui.api.customfields.IBlobUploadEventListener;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.user.IUser;
import com.vaadin.server.Extension;
import com.vaadin.server.FileDownloader;
import com.vaadin.server.StreamResource;
import com.vaadin.server.ThemeResource;
import com.vaadin.ui.AbstractLayout;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomField;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.Label;
import com.wcs.wcslib.vaadin.widget.multifileupload.ui.MultiFileUpload;
import com.wcs.wcslib.vaadin.widget.multifileupload.ui.UploadFinishedHandler;
/**
* This custom vaadin ui component unifies the {@link Label} that represents the
* blob with the optional available {@link MultiFileUpload}-Button that persist
* the uploaded blob base64 encoded into the database via JPA.
*
* The blob representation within the {@link Label} is in case of an image mime
* type the base64 encoded string of the image and otherwise a defined image for
* each mime type representing them.
*
* To visualize the stored base64 encoded blob data it will be read from
* database via JPA and included in a HTML-IMG-Tag-String as input for the
* {@link Label}. {@code <img src="data:...;base64,...">}.
*
* The optional available Upload-Button is from the Vaadin Add-on
* 'MultiFileUpload' by 'Webstar Csoport'
* ('https://vaadin.com/directory#addon/multifileupload').
*
* It is optionally firmly linked with the first uploaded blob, which means that
* every further blob upload only replaced the blob content (data) of the first
* created blob. Otherwise every blob upload creates a new blob and the
* corresponding persistence on the database.
*
* @author dominguez
*
*/
public class BlobUploadComponent extends CustomField<String> implements IBlobUploadEventListener, IUser.UserLocaleListener {
private static final String DOWNLOAD = "download";
private static final String UPLOAD = "upload";
/**
*
*/
private static final long serialVersionUID = -3890298210810421764L;
private static final String ICONPATH = "plugin/org.eclipse.osbp.blob/images/%s.png";
public enum BUTTON_ALIGNMENT {
TOP, BUTTOM, LEFT, RIGHT, DEFAULT
}
private transient IEventBroker eventBroker = null;
private static final int DEFAULT_RESOLUTION_ID = 0;
private BlobUploadButton singleUpload;
private Button downloadButton;
private Label displayImageLabel;
private Label blobUploadCompLabel = null;
private AbstractLayout layout = null;
private int displayResolutionId = DEFAULT_RESOLUTION_ID;
private BUTTON_ALIGNMENT buttonAlignment = BUTTON_ALIGNMENT.RIGHT;
private String lastUploadedFilename;
private transient IBlobService blobService;
private transient IDSLMetadataService dslMetadataService;
private transient IUser user;
public BlobUploadComponent(IBlobService blobService, IDSLMetadataService dslMetadataService, IUser user) {
this.dslMetadataService = dslMetadataService;
this.user = user;
this.blobService = blobService;
}
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
@Override
public int hashCode() {
return super.hashCode();
}
/**
* Creates the custom vaadin ui component consisting of a {@link Label}, an
* optional {@link MultiFileUpload} and a corresponding
* {@link UploadFinishedHandler}.
*
* The {@link UploadFinishedHandler} when called after an upload sent via
* {@link IEventBroker} the message of an started upload and called the
* {@link BlobService} to persist the uploaded blob into the database via
* JPA.
*/
public void createSingleUpload() {
UploadFinishedHandler handler = new UploadFinishedHandler() {
private static final long serialVersionUID = 1L;
@Override
public void handleFile(InputStream stream, String fileName, String mimeType, long length) {
if (eventBroker != null) {
eventBroker.send(IBlobEvent.STARTED_BLOB_UPLOAD, true);
}
BlobUploadComponent.this.lastUploadedFilename = fileName;
blobService.createBlobMapping(stream, fileName, mimeType);
}
};
singleUpload = new BlobUploadButton(handler);
singleUpload.setUploadButtonIcon(new ThemeResource(String.format(ICONPATH, UPLOAD)));
singleUpload.setDescription(dslMetadataService.translate(user.getLocale().toLanguageTag(), UPLOAD));
singleUpload.setUploadButtonCaption(" ");
// a Button is still active if the component is read only.
if (isReadOnly()) {
singleUpload.setEnabled(false);
}
downloadButton = new Button(new ThemeResource(String.format(ICONPATH, DOWNLOAD)));
downloadButton.setDescription(dslMetadataService.translate(user.getLocale().toLanguageTag(), DOWNLOAD));
downloadButton.setVisible(false);
downloadButton.setEnabled(false);
}
@Override
protected Component initContent() {
// Initialization of BlobUpload required before the
// 'getImageLabel'-Method
displayImageLabel = new BlobComponent(blobService, getValue(), displayResolutionId);
createSingleUpload();
int columns = 3;
int rows = 3;
switch (buttonAlignment) {
case LEFT:
layout = new GridLayout(columns, 1);
layout.addComponent(singleUpload);
layout.addComponent(downloadButton);
layout.addComponent(displayImageLabel);
break;
case RIGHT:
case DEFAULT:
layout = new GridLayout(columns, 1);
layout.addComponent(displayImageLabel);
layout.addComponent(singleUpload);
layout.addComponent(downloadButton);
break;
case BUTTOM:
layout = new GridLayout(1, rows);
layout.addComponent(displayImageLabel);
layout.addComponent(singleUpload);
layout.addComponent(downloadButton);
break;
case TOP:
layout = new GridLayout(1, rows);
layout.addComponent(singleUpload);
layout.addComponent(downloadButton);
layout.addComponent(displayImageLabel);
break;
}
return layout;
}
@Override
public Class<String> getType() {
return String.class;
}
public String getValue() { // NOSONAR
return super.getValue();
}
public Label getBlobUploadCompLabel() {
return blobUploadCompLabel;
}
/**
* Sets the uuid for the blob to be displayed, obtained the corresponding
* blob data for the already defined resolution and put them into the
* {@link Label} part of this ui component.
*
* @param uploadedBlobUuid
*/
public void setUploadedBlobUuid(String uploadedBlobUuid) {
setValue(uploadedBlobUuid);
}
public void showImage() {
if (displayImageLabel != null) {
displayImageLabel.setValue(blobService.getImage(getValue(), displayResolutionId));
}
}
public void showDownloadButton() {
if (downloadButton != null && getValue() != null) {
// a Button is still active if the component is read only, so the
// downloadButton only went enabled when the component is editable.
downloadButton.setEnabled(!isReadOnly());
downloadButton.setVisible(true);
// the description is shown as tooltip on the screen.
Collection<Extension> fileDownloaderExtensions = new ArrayList<>();
for (Extension extension : downloadButton.getExtensions()) {
if (extension instanceof FileDownloader) {
fileDownloaderExtensions.add(extension);
}
}
for (Extension extension : fileDownloaderExtensions) {
if (extension instanceof FileDownloader) {
downloadButton.removeExtension(extension);
}
}
StreamResource resource = blobService.getResource(getValue(), 0);
if (resource != null) {
FileDownloader fileDownloader = new FileDownloader(resource);
fileDownloader.extend(downloadButton);
}
}
}
public void setValue(String value) { // NOSONAR
super.setValue(value);
}
@Override
protected void setInternalValue(String newValue) { // NOSONAR
super.setInternalValue(newValue);
}
@Override
public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
showImage();
showDownloadButton();
super.valueChange(event);
}
public void setDisplayResolutionId(int resolutionId) {
this.displayResolutionId = resolutionId;
}
public void setEventBroker(IEventBroker eventBroker) {
this.eventBroker = eventBroker;
}
public void setDisplayImageLabel(Label displayImageLabel) {
this.displayImageLabel = displayImageLabel;
}
public void setBlobUploadCompLabel(Label blobUploadCompLabel) {
this.blobUploadCompLabel = blobUploadCompLabel;
setCaption(blobUploadCompLabel.getCaption());
}
public void setUploadButtonCaption(String buttonCaption) {
singleUpload.setUploadButtonCaption(buttonCaption);
}
public void setUploadAcceptedMimeTypes(List<String> mimeTypes) {
singleUpload.setUploadAcceptedMimeTypes(mimeTypes);
}
public void setUploadButtonAlignment(BUTTON_ALIGNMENT buttonAlignment) {
this.buttonAlignment = buttonAlignment;
}
public void setDisplayResolution(String displayResolution) {
this.displayResolutionId = blobService.getNormalizerResolutionIdByName(displayResolution);
}
@Override
public void attach() {
super.attach();
blobService.addBlobUploadListener(this);
user.addUserLocaleListener(this);
}
@Override
public void detach() {
blobService.removeBlobUploadListener((IBlobUploadEventListener) this);
user.removeUserLocaleListener(this);
super.detach();
}
@Override
public void blobUploaded(IBlobEvent e) {
if (e.isUploadSuccessful() && e.getUploadedFile().equals(lastUploadedFilename)) {
setValue(e.getUploadedBlobId());
showImage();
if (eventBroker != null) {
eventBroker.send(IBlobEvent.STOPPED_BLOB_UPLOAD, getValue());
}
}
}
@Override
public void focus() {
super.focus();
}
@Override
public void localeChanged(Locale locale) {
if(singleUpload != null && downloadButton != null) {
singleUpload.setDescription(dslMetadataService.translate(user.getLocale().toLanguageTag(), UPLOAD));
downloadButton.setDescription(dslMetadataService.translate(user.getLocale().toLanguageTag(), DOWNLOAD));
}
}
}