/* 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 org.activiti.explorer.ui.custom;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.activiti.explorer.ExplorerApp;
import org.activiti.explorer.I18nManager;
import org.activiti.explorer.Messages;
import org.activiti.explorer.NotificationManager;
import org.activiti.explorer.ui.mainlayout.ExplorerLayout;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptAll;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.terminal.StreamVariable;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.DragAndDropWrapper;
import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable;
import com.vaadin.ui.Html5File;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.ProgressIndicator;
import com.vaadin.ui.Upload;
import com.vaadin.ui.Upload.FailedEvent;
import com.vaadin.ui.Upload.FailedListener;
import com.vaadin.ui.Upload.FinishedEvent;
import com.vaadin.ui.Upload.FinishedListener;
import com.vaadin.ui.Upload.ProgressListener;
import com.vaadin.ui.Upload.Receiver;
import com.vaadin.ui.Upload.StartedEvent;
import com.vaadin.ui.Upload.StartedListener;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.Reindeer;
/**
* Component that can be used to upload files using file-select and
* HTML5 file dragging. Exposes events to listen to upload start, progress,
* finish and cancel.
*
* @author Joram Barrez
* @author Frederik Heremans
*/
public class UploadComponent extends VerticalLayout implements StartedListener, FinishedListener,
FailedListener, ProgressListener, DropHandler {
private static final long serialVersionUID = 1L;
// Services
protected I18nManager i18nManager;
protected NotificationManager notificationManager;
// Ui components
protected ProgressIndicator progressIndicator;
protected Upload upload;
protected Receiver receiver;
// Additional listeners can be attached to the upload components
protected List<FinishedListener> finishedListeners = new ArrayList<FinishedListener>();
protected List<StartedListener> startedListeners = new ArrayList<StartedListener>();
protected boolean showGenericFailureMessage = true;
protected List<FailedListener> failedListeners = new ArrayList<FailedListener>();
protected List<ProgressListener> progressListeners = new ArrayList<ProgressListener>();
public UploadComponent(String description, Receiver receiver) {
this.receiver = receiver;
this.i18nManager = ExplorerApp.get().getI18nManager();
this.notificationManager = ExplorerApp.get().getNotificationManager();
init(description);
}
// UI initialisation ----------------------------------------------------------------------------
protected void init(String description) {
setSpacing(true);
setSizeFull();
addDescription(description);
addUpload();
addOrLabel();
addDropPanel();
}
protected void addDescription(String description) {
if(description != null) {
Label descriptionLabel = new Label(description);
descriptionLabel.addStyleName(Reindeer.LABEL_SMALL);
descriptionLabel.addStyleName(ExplorerLayout.STYLE_DEPLOYMENT_UPLOAD_DESCRIPTION);
addComponent(descriptionLabel);
}
}
protected void addUpload() {
this.upload = new Upload(null, receiver);
upload.setButtonCaption(i18nManager.getMessage(Messages.UPLOAD_SELECT));
upload.setImmediate(true);
addComponent(upload);
setComponentAlignment(upload, Alignment.MIDDLE_CENTER);
// register ourselves as listener for upload events
upload.addListener((StartedListener) this);
upload.addListener((FailedListener) this);
upload.addListener((FinishedListener) this);
upload.addListener((ProgressListener) this);
}
protected void addOrLabel() {
Label orLabel = new Label("or");
orLabel.setSizeUndefined();
orLabel.addStyleName(Reindeer.LABEL_SMALL);
addComponent(orLabel);
setComponentAlignment(orLabel, Alignment.MIDDLE_CENTER);
}
protected void addDropPanel() {
Panel dropPanel = new Panel();
DragAndDropWrapper dragAndDropWrapper = new DragAndDropWrapper(dropPanel);
dragAndDropWrapper.setDropHandler(this);
dragAndDropWrapper.setWidth("80%");
addComponent(dragAndDropWrapper);
setComponentAlignment(dragAndDropWrapper, Alignment.MIDDLE_CENTER);
Label dropLabel = new Label(i18nManager.getMessage(Messages.UPLOAD_DROP));
dropLabel.setSizeUndefined();
dropPanel.addComponent(dropLabel);
((VerticalLayout)dropPanel.getContent()).setComponentAlignment(dropLabel, Alignment.MIDDLE_CENTER);
}
// File upload event handling -------------------------------------------------------------------
public void uploadStarted(StartedEvent event) {
removeAllComponents(); // Visible components are replaced by a progress bar
this.progressIndicator = new ProgressIndicator();
progressIndicator.setPollingInterval(500);
addComponent(progressIndicator);
setComponentAlignment(progressIndicator, Alignment.MIDDLE_CENTER);
for (StartedListener startedListener : startedListeners) {
startedListener.uploadStarted(event);
}
}
public void updateProgress(long readBytes, long contentLength) {
progressIndicator.setValue(new Float(readBytes / (float) contentLength));
for (ProgressListener progressListener : progressListeners) {
progressListener.updateProgress(readBytes, contentLength);
}
}
public void uploadFinished(FinishedEvent event) {
// Hide progress indicator
progressIndicator.setVisible(false);
for (FinishedListener finishedListener : finishedListeners) {
finishedListener.uploadFinished(event);
}
}
public void uploadFailed(FailedEvent event) {
for (FailedListener failedListener : failedListeners) {
failedListener.uploadFailed(event);
}
}
// Drag and drop handling (DropHandler) ---------------------------------------------------------
public void drop(DragAndDropEvent event) {
WrapperTransferable transferable = (WrapperTransferable) event.getTransferable();
Html5File[] files = transferable.getFiles();
if (files.length > 0) {
final Html5File file = files[0]; // only support for one file upload at this moment
file.setStreamVariable(new StreamVariable() {
private static final long serialVersionUID = 1L;
public void streamingStarted(StreamingStartEvent event) {
uploadStarted(null); // event doesnt matter here
}
public void streamingFinished(StreamingEndEvent event) {
uploadFinished(null); // event doesnt matter here
}
public void streamingFailed(StreamingErrorEvent event) {
uploadFailed(null);
}
public void onProgress(StreamingProgressEvent event) {
updateProgress(event.getBytesReceived(), event.getContentLength());
}
public boolean listenProgress() {
return true;
}
public boolean isInterrupted() {
return false;
}
public OutputStream getOutputStream() {
return receiver.receiveUpload(file.getFileName(), file.getType());
}
});
}
}
public AcceptCriterion getAcceptCriterion() {
return AcceptAll.get();
}
// Upload Listeners ----------------------------------------------------------------------------
public void addFinishedListener(FinishedListener finishedListener) {
finishedListeners.add(finishedListener);
}
public void addStartedListener(StartedListener startedListener) {
startedListeners.add(startedListener);
}
public void addFailedListener(FailedListener failedListener) {
failedListeners.add(failedListener);
}
public void addProgressListener(ProgressListener progressListener) {
progressListeners.add(progressListener);
}
}