package pl.net.bluesoft.rnd.processtool.ui.basewidgets;
import com.vaadin.data.Property;
import com.vaadin.terminal.StreamResource;
import com.vaadin.ui.*;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Upload.*;
import pl.net.bluesoft.rnd.processtool.model.ProcessInstanceAttachmentAttribute;
import pl.net.bluesoft.rnd.util.i18n.I18NSource;
import pl.net.bluesoft.util.lang.StringUtil;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
public class FileUploadComponent extends CustomComponent implements StartedListener, FailedListener, SucceededListener,
ProgressListener, FinishedListener, Receiver, Property {
public static final String UPLOAD_CANCEL = "fileupload.cancel";
public static final String UPLOAD_START = "fileupload.start";
public static final String UPLOAD_DOWNLOAD = "fileupload.download";
public static final String UPLOAD_CHOOSE_FILE = "fileupload.choose";
public static final String UPLOAD_FILE_NAME = "fileupload.filename";
public static final String UPLOAD_PROGRESS = "fileupload.progress";
public static final String PROGRESS_PROCESSED = "fileupload.progress.processed";
public static final String PROGRESS_FAILED = "fileupload.progress.failed";
private I18NSource i18NSource;
private ProgressIndicator pi = new ProgressIndicator();
private Upload uploadFile = new Upload(null, this);
private Button downloadFile = new Button();
private Button cancelProcessing = new Button();
private Label textualProgress = new Label();
private Label fileName = new Label();
private Label failedMessage = new Label();
private FormLayout mainPanel = new FormLayout();
private HorizontalLayout stateLayout;
private ProcessInstanceAttachmentAttribute instanceAttachment;
private ByteArrayOutputStream baos = null;
private String receivedFileName;
private String receivedMimeType;
public FileUploadComponent(I18NSource i18NSource) {
this.i18NSource = i18NSource;
uploadFile.addStyleName("default");
uploadFile.setButtonCaption(i18NSource.getMessage(UPLOAD_START));
uploadFile.addListener((FailedListener) this);
uploadFile.addListener((FinishedListener) this);
uploadFile.addListener((ProgressListener) this);
uploadFile.addListener((StartedListener) this);
uploadFile.addListener((SucceededListener) this);
mainPanel.setMargin(true);
initView();
setCompositionRoot(mainPanel);
}
@Override
public Object getValue() {
if (baos != null && StringUtil.hasText(receivedFileName) && StringUtil.hasText(receivedMimeType)) {
if (instanceAttachment == null) {
instanceAttachment = new ProcessInstanceAttachmentAttribute();
}
instanceAttachment.setData(baos.toByteArray());
instanceAttachment.setFileName(receivedFileName);
instanceAttachment.setMimeType(receivedMimeType);
}
return instanceAttachment;
}
@Override
public void setValue(Object newValue) throws ReadOnlyException, ConversionException {
if (newValue != null && !(newValue instanceof ProcessInstanceAttachmentAttribute)) {
throw new ConversionException("Cannot convert " + newValue.getClass() + " to " + ProcessInstanceAttachmentAttribute.class);
}
if (isReadOnly()) {
throw new ReadOnlyException("Property is readonly!");
}
instanceAttachment = (ProcessInstanceAttachmentAttribute) newValue;
if (instanceAttachment != null && StringUtil.hasText(instanceAttachment.getFileName())) {
fileName.setValue(instanceAttachment.getFileName());
}
downloadFile.setEnabled(canDownload());
}
@Override
public Class<?> getType() {
return ProcessInstanceAttachmentAttribute.class;
}
private boolean canDownload() {
return getValue() != null && instanceAttachment.getData() != null && StringUtil.hasText(instanceAttachment.getFileName())
&& StringUtil.hasText(instanceAttachment.getMimeType());
}
@Override
public void setReadOnly(boolean readOnly) {
uploadFile.setVisible(!readOnly);
super.setReadOnly(readOnly);
}
private void initView() {
uploadFile.setImmediate(true);
downloadFile.addListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
if (instanceAttachment != null && instanceAttachment.getData() != null) {
StreamResource.StreamSource source = new StreamResource.StreamSource() {
@Override
public InputStream getStream() {
return new ByteArrayInputStream(instanceAttachment.getData());
}
};
StreamResource resource = new StreamResource(source, instanceAttachment.getFileName(), getApplication());
resource.setMIMEType(instanceAttachment.getMimeType());
getApplication().getMainWindow().open(resource, "_new");
}
}
});
downloadFile.addStyleName("default");
downloadFile.setEnabled(false);
downloadFile.setStyleName("small");
downloadFile.setCaption(i18NSource.getMessage(UPLOAD_DOWNLOAD));
cancelProcessing.addStyleName("default");
cancelProcessing.addListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
uploadFile.interruptUpload();
}
});
cancelProcessing.setCaption(i18NSource.getMessage(UPLOAD_CANCEL));
cancelProcessing.setStyleName("small");
HorizontalLayout fileLayout = new HorizontalLayout();
fileLayout.setSpacing(true);
fileLayout.addComponent(new Label("<b>" + i18NSource.getMessage(UPLOAD_FILE_NAME) + "</b>", Label.CONTENT_RAW));
fileLayout.addComponent(fileName);
fileLayout.addComponent(uploadFile);
fileLayout.addComponent(downloadFile);
fileName.setValue(i18NSource.getMessage(UPLOAD_CHOOSE_FILE));
mainPanel.addComponent(fileLayout);
stateLayout = new HorizontalLayout();
stateLayout.setSpacing(true);
stateLayout.addComponent(new Label("<b>" + i18NSource.getMessage(UPLOAD_PROGRESS) + "</b>", Label.CONTENT_RAW));
stateLayout.addComponent(pi);
stateLayout.addComponent(cancelProcessing);
for (Iterator<Component> it = stateLayout.getComponentIterator(); it.hasNext();) {
stateLayout.setComponentAlignment(it.next(), Alignment.MIDDLE_CENTER);
}
for (Iterator<Component> it = fileLayout.getComponentIterator(); it.hasNext();) {
fileLayout.setComponentAlignment(it.next(), Alignment.MIDDLE_CENTER);
}
}
@Override
public void uploadStarted(StartedEvent event) {
pi.setValue(0f);
pi.setPollingInterval(500);
fileName.setValue(event.getFilename());
mainPanel.addComponent(stateLayout);
mainPanel.addComponent(textualProgress);
mainPanel.removeComponent(failedMessage);
downloadFile.setEnabled(false);
}
@Override
public void uploadFailed(FailedEvent event) {
baos = null;
failedMessage.setValue("<b>" + i18NSource.getMessage(PROGRESS_FAILED).replaceFirst("%s", "" + Math.round(100 * (Float) pi.getValue())) + "</b>");
mainPanel.addComponent(failedMessage);
downloadFile.setEnabled(canDownload());
}
@Override
public void updateProgress(long readBytes, long contentLength) {
pi.setValue(new Float(readBytes / (float) contentLength));
textualProgress.setValue(i18NSource.getMessage(PROGRESS_PROCESSED).replaceFirst("%s", "" + readBytes).replaceFirst("%s", "" + contentLength));
}
@Override
public void uploadSucceeded(SucceededEvent event) {
downloadFile.setEnabled(canDownload());
}
@Override
public void uploadFinished(FinishedEvent event) {
mainPanel.removeComponent(stateLayout);
mainPanel.removeComponent(textualProgress);
}
@Override
public OutputStream receiveUpload(String filename, String mimeType) {
receivedFileName = filename;
receivedMimeType = mimeType;
return baos = new ByteArrayOutputStream();
}
}