/* * Copyright 2013 gergo. * * 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 com.wcs.wcslib.vaadin.widget.multifileupload.component; import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.server.StreamVariable; import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.Html5File; import com.vaadin.ui.LegacyComponent; import com.vaadin.ui.Notification; import java.io.OutputStream; import java.util.*; /** * Server side component for the VMultiUpload widget. Pretty much hacked up together to test new Receiver support in the * GWT terminal. * <p> * <p> * This is a modified version of org.vaadin.easyuploads.MultiUpload.java which is part of the EasyUploads 7.0.0 Vaadin * addon. */ @SuppressWarnings("serial") public class MultiUpload extends AbstractComponent implements LegacyComponent, UploadComponent { private boolean focus = false; private int tabIndex = 0; List<FileDetail> pendingFiles = new ArrayList<>(); private List<Long> interruptedFileIds = new ArrayList<>(); private MultiUploadHandler receiver; private String buttonCaption = "..."; private boolean uploading; private boolean ready; private boolean interrupted = false; private long maxFileSize; private String sizeErrorMsg; private String acceptFilter; private List<String> acceptedMimeTypes; private boolean enabled = true; private String mimeTypeErrorMsg; private int maxFileCount; private String fileCountErrorMsg; StreamVariable streamVariable = new StreamVariable() { @Override public void streamingStarted(StreamingStartEvent event) { uploading = true; interrupted = false; Iterator<FileDetail> iterator = getPendingFileNames().iterator(); if (!iterator.hasNext()) { return; } final FileDetail next = iterator.next(); receiver.streamingStarted(new StreamingStartEvent() { @Override public String getMimeType() { return next.getMimeType(); } @Override public String getFileName() { return next.getFileName(); } @Override public long getContentLength() { return next.getContentLength(); } @Override public long getBytesReceived() { return 0; } @Override public void disposeStreamVariable() { } }); } @Override public void streamingFinished(final StreamingEndEvent event) { uploading = false; interrupted = false; Iterator<FileDetail> iterator = getPendingFileNames().iterator(); if (!iterator.hasNext()) { return; } final FileDetail next = iterator.next(); receiver.streamingFinished(new StreamingEndEvent() { @Override public String getMimeType() { return next.getMimeType(); } @Override public String getFileName() { return next.getFileName(); } @Override public long getContentLength() { return next.getContentLength(); } @Override public long getBytesReceived() { return event.getBytesReceived(); } }); pendingFiles.remove(0); } @Override public void streamingFailed(StreamingErrorEvent event) { uploading = false; interrupted = false; receiver.streamingFailed(event); if (!pendingFiles.isEmpty()) { pendingFiles.remove(0); } } @Override public void onProgress(StreamingProgressEvent event) { receiver.onProgress(event); } @Override public boolean listenProgress() { return true; } @Override public boolean isInterrupted() { return interrupted; } @Override public OutputStream getOutputStream() { return receiver.getOutputStream(); } }; public void setHandler(MultiUploadHandler receiver) { this.receiver = receiver; } @Override public void paintContent(PaintTarget target) throws PaintException { target.addVariable(this, "target", streamVariable); target.addAttribute("maxFileSize", maxFileSize); target.addAttribute("sizeErrorMsg", sizeErrorMsg); target.addAttribute("acceptFilter", acceptFilter); if (acceptedMimeTypes != null) { target.addAttribute("acceptedMimeTypes", acceptedMimeTypes.toArray(new String[acceptedMimeTypes.size()])); } else { target.addAttribute("acceptedMimeTypes", new String[]{}); } target.addAttribute("mimeTypeErrorMsg", mimeTypeErrorMsg); target.addAttribute("enabled", enabled); if (ready) { target.addAttribute("ready", true); ready = false; } target.addAttribute("buttoncaption", getButtonCaption()); if (!interruptedFileIds.isEmpty()) { target.addAttribute("interruptedFileIds", interruptedFileIds.toArray(new Long[interruptedFileIds.size()])); interruptedFileIds = new ArrayList<>(); } if (focus) { target.addAttribute("focus", true); focus = false; } if (tabIndex >= 0) { target.addAttribute("tabindex", tabIndex); } } @Override public void changeVariables(Object source, Map<String, Object> variables) { if (variables.containsKey("filequeue")) { String[] fileQueue = (String[]) variables.get("filequeue"); List<FileDetail> newFiles = new ArrayList<>(fileQueue.length); for (String string : fileQueue) { if (pendingFiles.size() + newFiles.size() >= maxFileCount) { Notification.show(UploadUtil.formatErrorMessage(fileCountErrorMsg, maxFileCount), Notification.Type.WARNING_MESSAGE); break; } newFiles.add(new FileDetail(string)); } pendingFiles.addAll(newFiles); receiver.filesQueued(newFiles); markAsDirty(); if (!isUploading()) { ready = true; } } } @Override public void interruptUpload(long fileId) { int ndx = 0; for (ListIterator<FileDetail> it = pendingFiles.listIterator(); it.hasNext();) { FileDetail fileDetail = it.next(); if (fileDetail.getId() == fileId) { if (ndx == 0) { interrupted = true; return; } else { it.remove(); interruptedFileIds.add(fileId); markAsDirty(); return; } } ndx++; } } public void registerDropComponent(MultiUploadDropHandler dropHandler) { dropHandler.addFilesReceivedListener((List<Html5File> html5Files) -> { final List<FileDetail> newFiles = new ArrayList<>(); for (Html5File html5File : html5Files) { if (pendingFiles.size() + newFiles.size() >= maxFileCount) { Notification.show(UploadUtil.formatErrorMessage(fileCountErrorMsg, maxFileCount), Notification.Type.WARNING_MESSAGE); break; } html5File.setStreamVariable(streamVariable); newFiles.add(new FileDetail(html5File.getFileName(), html5File.getType(), html5File.getFileSize())); } pendingFiles.addAll(newFiles); receiver.filesQueued(newFiles); markAsDirty(); if (!isUploading()) { ready = true; } }); } public Collection<FileDetail> getPendingFileNames() { return Collections.unmodifiableCollection(pendingFiles); } @Override public void setButtonCaption(String buttonCaption) { this.buttonCaption = buttonCaption; } public String getButtonCaption() { return buttonCaption; } public boolean isUploading() { return uploading; } @Override public void setMaxFileSize(long maxFileSize) { this.maxFileSize = maxFileSize; } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); this.enabled = enabled; } @Override public void setSizeErrorMsgPattern(String sizeErrorMsg) { this.sizeErrorMsg = sizeErrorMsg; } @Override public void setAcceptFilter(String acceptFilter) { this.acceptFilter = acceptFilter; } @Override public void setAcceptedMimeTypes(List<String> acceptedMimeTypes) { this.acceptedMimeTypes = acceptedMimeTypes; } @Override public void setMimeTypeErrorMsgPattern(String pattern) { this.mimeTypeErrorMsg = pattern; } public void setMaxFileCount(int maxFileCount) { this.maxFileCount = maxFileCount; } public void setFileCountErrorMsgPattern(String pattern) { this.fileCountErrorMsg = pattern; } @Override public void focus() { focus = true; } @Override public int getTabIndex() { return tabIndex; } @Override public void setTabIndex(int tabIndex) { this.tabIndex = tabIndex; } }