io.graphenee.vaadin.component.FileChooser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gx-vaadin Show documentation
Show all versions of gx-vaadin Show documentation
Set of useful Vaadin prebuilt components, views and UIs.
/*******************************************************************************
* Copyright (c) 2016, 2018 Farrukh Ijaz
*
* 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 io.graphenee.vaadin.component;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.UUID;
import java.util.function.Function;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vaadin.viritin.button.MButton;
import org.vaadin.viritin.layouts.MHorizontalLayout;
import com.vaadin.server.FileDownloader;
import com.vaadin.server.FileResource;
import com.vaadin.server.FontAwesome;
import com.vaadin.server.Resource;
import com.vaadin.server.StreamResource;
import com.vaadin.server.StreamResource.StreamSource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomField;
import com.vaadin.ui.Image;
import com.vaadin.ui.ProgressBar;
import com.vaadin.ui.UI;
import com.vaadin.ui.themes.ValoTheme;
import com.vaadin.util.FileTypeResolver;
import io.graphenee.core.storage.FileStorage;
import io.graphenee.core.storage.ResolveFailedException;
import io.graphenee.core.util.TRFileContentUtil;
import io.graphenee.gx.theme.graphenee.GrapheneeTheme;
import io.graphenee.vaadin.ResourcePreviewPanel;
import server.droporchoose.UploadComponent;
public class FileChooser extends CustomField {
public static final Logger L = LoggerFactory.getLogger(FileChooser.class);
private static final long serialVersionUID = 1L;
private Image previewImage;
private UploadComponent uploadComponent;
private FileStorage storage;
private String componentHeight;
private String componentWidth;
private ProgressBar progressBar;
private String uploadedFilePath;
private String uploadedFileName;
private Function fileNameTranslator;
private String rootFolder;
private MButton deleteButton;
private FileDownloader fileDownloader;
ResourcePreviewPanel previewPanel;
private MHorizontalLayout imageLayout;
public String getUploadedFilePath() {
return uploadedFilePath;
}
public String getUploadedFileName() {
return uploadedFileName;
}
public FileChooser() {
this(null);
}
public FileChooser(String caption) {
this(caption, (fileName) -> {
return UUID.randomUUID().toString() + "." + FilenameUtils.getExtension(fileName);
});
}
public FileChooser(String caption, Function fileNameTranslator) {
setCaption(caption);
this.fileNameTranslator = fileNameTranslator;
componentHeight = "100px";
componentWidth = "280px";
}
public void setStorage(FileStorage storage) {
this.storage = storage;
}
public void setFileNameTranslator(Function fileNameTranslator) {
this.fileNameTranslator = fileNameTranslator;
}
public String getRootFolder() {
return rootFolder;
}
public void setRootFolder(String rootFolder) {
this.rootFolder = rootFolder;
fireValueChange(true);
}
private void preview(String filePath) {
String extension = FilenameUtils.getExtension(filePath);
if (extension != null && extension.matches("(png|jpg|gif|bmp|jpeg|pdf)")) {
File file = new File(filePath);
Resource resource = null;
if (file.exists()) {
resource = new FileResource(file);
} else {
try {
String resourcePath = storage.resourcePath(getRootFolder(), filePath);
InputStream inputStream = storage.resolve(resourcePath);
InputStreamSource source = new InputStreamSource(inputStream);
resource = new StreamResource(source, UUID.randomUUID().toString() + "." + TRFileContentUtil.getExtensionFromFilename(filePath)) {
@Override
public String getMIMEType() {
String mimeType = FileTypeResolver.getMIMEType(filePath);
if (mimeType != null) {
return mimeType;
}
return super.getMIMEType();
}
};
} catch (ResolveFailedException e) {
resource = null;
}
}
if (previewPanel == null) {
previewPanel = new ResourcePreviewPanel();
}
previewPanel.build();
previewPanel.preview(resource);
previewPanel.openInModalPopup();
}
}
private void uploadReceived(String inputFileName, Path inputFilePath) {
String fileName = fileNameTranslator != null ? fileNameTranslator.apply(inputFileName) : inputFileName;
File targetFile = new File(inputFilePath.getParent().toFile(), fileName);
if (targetFile.exists()) {
targetFile.delete();
}
inputFilePath.toFile().renameTo(targetFile);
this.uploadedFilePath = targetFile.getAbsolutePath();
this.uploadedFileName = inputFileName;
setValue(uploadedFilePath);
UI.getCurrent().access(() -> {
String extension = FilenameUtils.getExtension(uploadedFilePath);
if (extension != null)
extension = extension.toLowerCase();
Resource resource = null;
if (extension == null || !extension.matches("(png|jpg|gif|bmp|jpeg)")) {
resource = GrapheneeTheme.fileExtensionIconResource(extension);
if (resource == null)
resource = GrapheneeTheme.fileExtensionIconResource("bin");
} else {
try {
InputStream inputStream = new FileInputStream(targetFile);
StreamSource source = new InputStreamSource(inputStream);
resource = new StreamResource(source, UUID.randomUUID().toString());
} catch (FileNotFoundException e) {
resource = null;
}
}
previewImage.setSource(resource);
previewImage.markAsDirty();
progressBar.setVisible(false);
previewImage.setVisible(true);
UI.getCurrent().push();
});
}
private void uploadStarted(String fileName) {
UI.getCurrent().access(() -> {
uploadComponent.setVisible(false);
imageLayout.setVisible(true);
previewImage.setVisible(false);
progressBar.setValue(0F);
progressBar.setVisible(true);
UI.getCurrent().push();
});
}
private void uploadProgress(String fileName, long readBytes, long contentLength) {
UI.getCurrent().access(() -> {
float value = (float) readBytes / contentLength;
progressBar.setValue(value);
UI.getCurrent().push();
});
}
private void uploadFailed(String fileName, Path file) {
UI.getCurrent().access(() -> {
uploadComponent.setVisible(true);
imageLayout.setVisible(false);
progressBar.setVisible(false);
previewImage.setVisible(true);
UI.getCurrent().push();
});
}
public void setComponentHeight(String height) {
componentHeight = height;
}
public void setComponentWidth(String width) {
componentWidth = width;
if (uploadComponent != null)
uploadComponent.setWidth(width);
}
@Override
protected Component initContent() {
MHorizontalLayout layout = new MHorizontalLayout().withDefaultComponentAlignment(Alignment.TOP_LEFT).withMargin(false).withSpacing(true).withWidthUndefined();
imageLayout = new MHorizontalLayout().withDefaultComponentAlignment(Alignment.MIDDLE_CENTER).withSpacing(false);
imageLayout.setHeight(componentHeight);
progressBar = new ProgressBar();
progressBar.setIndeterminate(false);
previewImage = new Image();
// previewImage.setHeight("32px");
previewImage.setSource(GrapheneeTheme.UPLOAD_ICON);
previewImage.addClickListener(event -> {
String value = getValue();
if (value != null) {
preview(value);
}
});
imageLayout.addComponent(progressBar);
// MVerticalLayout imageContainer1 = new
// MVerticalLayout().withMargin(false).withSpacing(false).withDefaultComponentAlignment(Alignment.MIDDLE_CENTER)
// .withWidth(componentHeight).withHeight(componentHeight);
// imageContainer.addComponent(previewImage);
// imageLayout.addComponent(imageContainer);
imageLayout.addComponent(previewImage);
progressBar.setVisible(false);
uploadComponent = new UploadComponent();
uploadComponent.getChoose().setButtonCaption("Choose a file");
uploadComponent.setWidth(componentWidth);
uploadComponent.setHeight(componentHeight);
uploadComponent.setStyleName("dropBoxLayout");
uploadComponent.setReceivedCallback(this::uploadReceived);
uploadComponent.setStartedCallback(this::uploadStarted);
uploadComponent.setProgressCallback(this::uploadProgress);
uploadComponent.setFailedCallback(this::uploadFailed);
deleteButton = new MButton(FontAwesome.CLOSE).withListener(event -> {
setValue(null);
}).withStyleName(ValoTheme.BUTTON_TINY, ValoTheme.BUTTON_ICON_ONLY, ValoTheme.BUTTON_QUIET);
imageLayout.addComponent(deleteButton);
imageLayout.setComponentAlignment(deleteButton, Alignment.BOTTOM_RIGHT);
imageLayout.setExpandRatio(deleteButton, 1);
addValueChangeListener(event -> {
renderComponent();
});
layout.addComponents(uploadComponent, imageLayout);
uploadComponent.setVisible(false);
imageLayout.setVisible(false);
// fireValueChange(true);
renderComponent();
return layout;
}
private void renderComponent() {
if (previewImage != null) {
if (fileDownloader != null) {
previewImage.removeExtension(fileDownloader);
fileDownloader = null;
}
previewImage.markAsDirtyRecursive();
String fileName = getValue();
Resource resource = null;
if (fileName != null) {
String extension = FilenameUtils.getExtension(fileName);
if (extension == null || !extension.matches("(png|jpg|gif|bmp|jpeg)")) {
resource = GrapheneeTheme.fileExtensionIconResource(extension);
previewImage.setHeight("32px");
previewImage.setSource(resource);
} else {
File file = new File(fileName);
if (file.isFile() && file.exists()) {
resource = new FileResource(file);
} else {
try {
String resourcePath = storage.resourcePath(getRootFolder(), fileName);
InputStream inputStream = storage.resolve(resourcePath);
InputStreamSource isr = new InputStreamSource(inputStream);
resource = new StreamResource(isr, fileName);
} catch (ResolveFailedException e1) {
resource = GrapheneeTheme.IMAGE_NOT_AVAILBLE;
}
}
previewImage.setHeight(componentHeight);
previewImage.setSource(resource);
}
if (extension == null || !extension.matches("(png|jpg|gif|bmp|jpeg|pdf)")) {
try {
File file = new File(fileName);
if (file.isFile() && file.exists()) {
Resource downloadResource = new FileResource(file);
if (fileDownloader == null) {
fileDownloader = new FileDownloader(downloadResource);
fileDownloader.extend(previewImage);
}
} else {
String resourcePath = storage.resourcePath(getRootFolder(), fileName);
InputStream inputStream = storage.resolve(resourcePath);
InputStreamSource isr = new InputStreamSource(inputStream);
Resource downloadResource = new StreamResource(isr, fileName);
if (fileDownloader == null) {
fileDownloader = new FileDownloader(downloadResource);
fileDownloader.extend(previewImage);
}
}
} catch (ResolveFailedException e1) {
resource = GrapheneeTheme.IMAGE_NOT_AVAILBLE;
}
}
uploadComponent.setVisible(false);
imageLayout.setVisible(true);
} else {
imageLayout.setVisible(false);
uploadComponent.setVisible(true);
}
}
}
@Override
public Class getType() {
return String.class;
}
}