Java tutorial
/* * Copyright (c) 2008-2016 Haulmont. * * 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.haulmont.cuba.web.widgets.client.jqueryfileupload; import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Focusable; import com.google.gwt.user.client.ui.HasEnabled; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.BrowserInfo; import com.vaadin.client.StyleConstants; import com.vaadin.client.WidgetUtil; import com.vaadin.client.ui.VButton; import com.vaadin.client.ui.VNotification; import com.vaadin.shared.Position; import java.util.Set; public class CubaFileUploadWidget extends FlowPanel implements Focusable, HasEnabled { public static final String DEFAULT_CLASSNAME = "c-fileupload"; public static final String CUBA_FILEUPLOAD_DROPZONE_CLASS = "c-fileupload-dropzone"; protected VButton submitButton; protected JQueryFileUploadOverlay fileUpload; protected CubaFileUploadProgressWindow progressWindow; protected String unableToUploadFileMessage; protected String progressWindowCaption; protected String cancelButtonCaption; protected boolean ignoreExceptions = false; protected long fileSizeLimit = -1; protected Set<String> permittedExtensions; protected FilePermissionsHandler filePermissionsHandler; protected QueueUploadListener queueUploadListener; protected FileUploadedListener fileUploadedListener; protected boolean enabled; public CubaFileUploadWidget() { submitButton = new VButton(); submitButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { fireNativeClick(getFileInputElement()); } }); add(submitButton); submitButton.setTabIndex(-1); setStyleName(DEFAULT_CLASSNAME); Element inputElement = Document.get().createFileInputElement(); inputElement.setAttribute("name", "files[]"); if (!BrowserInfo.get().isIE() && !BrowserInfo.get().isEdge()) { inputElement.setAttribute("title", " "); } listenToFocusEvents(inputElement); getElement().appendChild(inputElement); fileUpload = new JQueryFileUploadOverlay(this) { protected boolean canceled = false; @Override protected boolean isValidFile(String name, double size) { if (fileSizeLimit > 0 && size > fileSizeLimit) { if (filePermissionsHandler != null) { filePermissionsHandler.fileSizeLimitExceeded(name); } return false; } if (hasInvalidExtension(name)) { if (filePermissionsHandler != null) { filePermissionsHandler.fileExtensionNotAllowed(name); } return false; } return true; } protected boolean hasInvalidExtension(String name) { if (permittedExtensions != null && !permittedExtensions.isEmpty()) { if (name.lastIndexOf(".") > 0) { String fileExtension = name.substring(name.lastIndexOf("."), name.length()); return !permittedExtensions.contains(fileExtension.toLowerCase()); } return true; } return false; } @Override protected void queueUploadStart() { // listen to events of new input element listenToFocusEvents(getFileInputElement()); progressWindow = new CubaFileUploadProgressWindow(); progressWindow.setOwner(CubaFileUploadWidget.this); progressWindow.addStyleName(getStylePrimaryName() + "-progresswindow"); progressWindow.setVaadinModality(true); progressWindow.setDraggable(true); progressWindow.setResizable(false); progressWindow.setClosable(true); progressWindow.setCaption(progressWindowCaption); progressWindow.setCancelButtonCaption(cancelButtonCaption); progressWindow.closeListener = new CubaFileUploadProgressWindow.CloseListener() { @Override public void onClose() { canceled = true; // null progress to prevent repeated hide() call inside cancelUploading progressWindow = null; cancelUploading(); if (queueUploadListener != null) { queueUploadListener.uploadFinished(); } } }; progressWindow.setVisible(false); progressWindow.show(); progressWindow.center(); progressWindow.setVisible(true); canceled = false; } @Override protected void fileUploadStart(String fileName) { if (progressWindow != null) { progressWindow.setCurrentFileName(fileName); } } @Override protected void fileUploadSucceed(String fileName) { if (fileUploadedListener != null) { fileUploadedListener.fileUploaded(fileName); } } @Override protected void uploadProgress(double loaded, double total) { if (progressWindow != null) { float ratio = (float) (loaded / total); progressWindow.setProgress(ratio); } } @Override protected void queueUploadStop() { if (progressWindow != null) { progressWindow.hide(); progressWindow = null; } getFileInputElement().focus(); if (queueUploadListener != null) { queueUploadListener.uploadFinished(); } } @Override protected void uploadFailed(String textStatus, String errorThrown) { if (ignoreExceptions) { if (progressWindow != null) progressWindow.hide(); return; } if (!canceled) { if (unableToUploadFileMessage != null) { // show notification without server round trip, server may be unreachable VNotification notification = VNotification.createNotification(-1, CubaFileUploadWidget.this); String fileName = ""; if (progressWindow != null) { fileName = progressWindow.getCurrentFileName(); } String message = "<h1>" + WidgetUtil.escapeHTML(unableToUploadFileMessage.replace("%s", fileName)) + "</h1>"; notification.show(message, Position.MIDDLE_CENTER, "error"); } canceled = true; cancelUploading(); } } }; } protected void listenToFocusEvents(Element inputElement) { DOM.sinkEvents(inputElement, Event.ONFOCUS | Event.ONBLUR); } // Due to jquery file upload behavior we need to get input element from DOM protected Element getFileInputElement() { return getElement().getElementsByTagName("input").getItem(0); } @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); int type = DOM.eventGetType(event); if (getFileInputElement().isOrHasChild(Element.as(event.getEventTarget()))) { if (type == Event.ONFOCUS) { submitButton.addStyleDependentName("focus"); } else if (type == Event.ONBLUR) { submitButton.removeStyleDependentName("focus"); } } } protected static native void fireNativeClick(Element element) /*-{ element.click(); }-*/; public void setMultiSelect(boolean multiple) { if (multiple) { getFileInputElement().setAttribute("multiple", ""); } else { getFileInputElement().removeAttribute("multiple"); } } public void setUploadUrl(String uploadUrl) { fileUpload.setUploadUrl(uploadUrl); } public void setDropZone(final Widget dropZone, String dropZonePrompt) { if (dropZone != null) { Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { @Override public void execute() { fileUpload.setDropZone(dropZone.getElement()); } }); dropZone.getElement().setAttribute("dropzone-prompt", dropZonePrompt != null ? dropZonePrompt : ""); } else { fileUpload.setDropZone(null); } } public void setPasteZone(final Widget pasteZone) { if (pasteZone != null) { Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { @Override public void execute() { fileUpload.setPasteZone(pasteZone.getElement()); } }); } else { fileUpload.setPasteZone(null); } } public void setAccept(String accept) { if (accept != null) { getFileInputElement().setAttribute("accept", accept); } else { getFileInputElement().removeAttribute("accept"); } } public void disableUpload() { setEnabledForSubmitButton(false); // Cannot disable the fileupload while submitting or the file won't // be submitted at all getFileInputElement().setAttribute("disabled", "disabled"); enabled = false; } public void enableUpload() { setEnabledForSubmitButton(true); getFileInputElement().removeAttribute("disabled"); enabled = true; } protected void setEnabledForSubmitButton(boolean enabled) { submitButton.setEnabled(enabled); submitButton.setStyleName(StyleConstants.DISABLED, !enabled); } public VButton getSubmitButton() { return submitButton; } public void cancelAllUploads() { fileUpload.cancelUploading(); } public void continueUploading() { fileUpload.continueUploading(); } @Override public int getTabIndex() { return getFileInputElement().getTabIndex(); } @Override public void setAccessKey(char key) { } @Override public void setFocus(boolean focused) { if (focused) { getFileInputElement().focus(); } else { getFileInputElement().blur(); } } @Override public void setTabIndex(int index) { getFileInputElement().setTabIndex(index); } @Override public boolean isEnabled() { return enabled; } protected boolean isIgnoreExceptions() { return ignoreExceptions; } protected void setIgnoreExceptions(boolean ignoreExceptions) { this.ignoreExceptions = ignoreExceptions; } @Override public void setEnabled(boolean enabled) { this.enabled = enabled; if (enabled) { enableUpload(); } else { disableUpload(); } } public interface FilePermissionsHandler { void fileSizeLimitExceeded(String filename); void fileExtensionNotAllowed(String filename); } public interface QueueUploadListener { void uploadFinished(); } public interface FileUploadedListener { void fileUploaded(String fileName); } }