26 | * Note that the 'fileDialogStart' is fired after selectFile for selectFiles is called. This 27 | * event is fired immediately before the File Selection Dialog window is displayed. However, 28 | * the event may not execute until after the Dialog window is closed. 29 | *
30 | * 31 | * @author delight.wjk@gmail.com 32 | */ 33 | public class FileDialogStartEvent { 34 | 35 | /** 36 | * This constructor is intended for internal use only. You should not create file dialog start 37 | * events directly, but instead should register a {@link FileDialogStartHandler}. 38 | */ 39 | public FileDialogStartEvent() { 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/FileQueuedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Document Node Pty Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.docstr.gwt.uploader.client.events; 17 | 18 | import org.docstr.gwt.uploader.client.File; 19 | 20 | /** 21 | * Provides access to the raw information provided by Uploader when a 'fileQueued' event occurs. 22 | * This class should not be instantiated directly, but instead you should create a {@link 23 | * FileQueuedHandler} and register it via the {@link org.docstr.gwt.uploader.client 24 | * .Uploader#setFileQueuedHandler(FileQueuedHandler)} method in order to access file queued events. 25 | *
26 | * Note that the 'fileQueued' event is fired for each file that is queued after the File 27 | * Selection Dialog window is closed. 28 | * 29 | * @author delight.wjk@gmail.com 30 | */ 31 | public class FileQueuedEvent { 32 | 33 | private File file; 34 | 35 | /** 36 | * This constructor is intended for internal use only. You should not create file queued events 37 | * directly, but instead should register a {@link FileQueuedHandler}. 38 | * 39 | * @param file The file instance that was added to the queue. 40 | */ 41 | public FileQueuedEvent(File file) { 42 | this.file = file; 43 | } 44 | 45 | /** 46 | * Return the details of the file that was added to the queue. 47 | * 48 | * @return File 49 | */ 50 | public File getFile() { 51 | return file; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/FileQueuedHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Document Node Pty Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.docstr.gwt.uploader.client.events; 17 | 18 | /** 19 | * An interface that can be used as a callback handler when file queued events are fired by 20 | * the Uploader component. General usage is as follows: 21 | *
22 | * uploader.setFileQueuedEventHandler(new FileQueuedHandler() {
23 | * public boolean onFileQueued(FileQueuedEvent event) {
24 | * Window.alert("File with name " + event.getFile().getName() + " is ready to uploader");
25 | * return true;
26 | * }
27 | * });
28 | *
29 | * Note that the 'fileQueued' event is fired for each file that is queued after the File
30 | * Selection Dialog window is closed.
31 | * 32 | * See the documentation on the {@link FileQueuedEvent} class for more details on the data 33 | * available when a file queued event occurs. 34 | * 35 | * @author delight.wjk@gmail.com 36 | */ 37 | public interface FileQueuedHandler { 38 | 39 | /** 40 | * This method is fired whenever a file queued event occurs in the Uploader component. See 41 | * the {@link FileQueuedEvent} class for more details on the data available when this event is 42 | * fired. 43 | * 44 | * @param fileQueuedEvent The details of the event that occurred. 45 | * @return The response to send back to the event handler function 46 | */ 47 | public boolean onFileQueued(FileQueuedEvent fileQueuedEvent); 48 | 49 | } 50 | -------------------------------------------------------------------------------- /gwt-uploader/build.gradle: -------------------------------------------------------------------------------- 1 | archivesBaseName = "gwt-uploader" 2 | 3 | dependencies { 4 | } 5 | 6 | signing { 7 | sign publishing.publications 8 | } 9 | 10 | def ossrU = project.hasProperty("ossrhUsername") ? ossrhUsername : "" 11 | def ossrP = project.hasProperty("ossrhPassword") ? ossrhPassword : "" 12 | 13 | publishing { 14 | publications { 15 | mavenJava(MavenPublication) { 16 | from components.java 17 | versionMapping { 18 | usage('java-api') { 19 | fromResolutionOf('runtimeClasspath') 20 | } 21 | usage('java-runtime') { 22 | fromResolutionResult() 23 | } 24 | } 25 | pom { 26 | name = 'GWT Uploader' 27 | description = 'An API to enable sophisticated file upload capabilities within a GWT application.' 28 | url = 'https://github.com/jiakuan/gwt-uploader/' 29 | packaging = 'jar' 30 | licenses { 31 | license { 32 | name = 'The Apache License, Version 2.0' 33 | url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 34 | } 35 | } 36 | developers { 37 | developer { 38 | id = 'jiakuan' 39 | name = 'Jiakuan Wang' 40 | email = 'jake@documentnode.io' 41 | organization = 'Document Node' 42 | organizationUrl = 'https://documentnode.io' 43 | } 44 | } 45 | 46 | scm { 47 | connection = 'scm:git:git@github.com:jiakuan/gwt-uploader.git' 48 | developerConnection = 'scm:git:git@github.com:jiakuan/gwt-uploader.git' 49 | url = 'git@github.com:jiakuan/gwt-uploader.git' 50 | } 51 | } 52 | } 53 | } 54 | repositories { 55 | maven { 56 | def releasesRepoUrl = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/" 57 | def snapshotsRepoUrl = "https://s01.oss.sonatype.org/content/repositories/snapshots/" 58 | url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl 59 | credentials { 60 | username = ossrU 61 | password = ossrP 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/UploadProgressHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Document Node Pty Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.docstr.gwt.uploader.client.events; 17 | 18 | /** 19 | * An interface that can be used as a callback handler when uploader progress events are fired by 20 | * the Uploader component. General usage is as follows: 21 | *
22 | * uploader.setUploadProgressHandler(new UploadProgressHandler() {
23 | * public boolean onUploadProgress(UploadProgressEvent event) {
24 | * Window.alert("Uploader progressed to " + event.getBytesTotal() + " bytes");
25 | * return true;
26 | * }
27 | * });
28 | *
29 | * 30 | * Note that the 'uploadProgress' event is fired periodically by the control. This event is 31 | * useful for providing UI updates on the page. 32 | *
33 | * See the documentation on the {@link UploadProgressEvent} class for more details on the data 34 | * available when a progress event occurs. 35 | * 36 | * @author delight.wjk@gmail.com 37 | */ 38 | public interface UploadProgressHandler { 39 | 40 | /** 41 | * This method is fired whenever a progress event occurs in the Uploader component. See 42 | * the {@link UploadProgressEvent} class for more details on the data available when this event 43 | * is fired. 44 | * 45 | * @param uploadProgressEvent The details of the event that occurred. 46 | * @return The response to send back to the event handler function 47 | */ 48 | public boolean onUploadProgress(UploadProgressEvent uploadProgressEvent); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /gwt-uploader-demo/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |29 | Examples and source code that you can copy. 30 |
31 | 32 | 33 | 34 |28 | * Note that the 'uploadStart' event is called immediately before the file is uploaded. This event 29 | * provides an opportunity to perform any last minute validation, add post params or do any other 30 | * work before the file is uploaded. 31 | *
32 | * The uploader can be cancelled by returning 'false' from uploadStart in the handler. If you 33 | * return 'true' or do not return 34 | * any value then the uploader proceeds. Returning 'false' will cause an uploadError event to fired. 35 | * 36 | * @author delight.wjk@gmail.com 37 | */ 38 | public class UploadStartEvent extends UploadEvent { 39 | 40 | /** 41 | * This constructor is intended for internal use only. You should not create uploader start 42 | * events directly, but instead should register a {@link UploadStartHandler}. 43 | * 44 | * @param file The native javascript object containing the details of the file being uploaded. 45 | */ 46 | public UploadStartEvent(File file) { 47 | super(file); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/FileDialogStartHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Document Node Pty Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.docstr.gwt.uploader.client.events; 17 | 18 | /** 19 | * An interface that can be used as a callback handler when file dialog start events are fired by 20 | * the Uploader component. General usage is as follows: 21 | *
22 | * uploader.setFileDialogStartHandler(new FileDialogStartHandler() {
23 | * public boolean onFileDialogStart(FileDialogStartEvent event) {
24 | * Window.alert("Starting the file selection dialog...");
25 | * return true;
26 | * }
27 | * });
28 | *
29 | * Note that the 'fileDialogStart' is fired after selectFile for selectFiles is called. This
30 | * event is fired immediately before the File Selection Dialog window is displayed. However,
31 | * the event may not execute until after the Dialog window is closed.
32 | * 33 | * See the documentation on the {@link FileDialogStartEvent} class for more details on the data 34 | * available when a file dialog start event occurs. 35 | * 36 | * @author delight.wjk@gmail.com 37 | */ 38 | public interface FileDialogStartHandler { 39 | 40 | /** 41 | * This method is fired whenever a file dialog start event occurs in the Uploader component. See 42 | * the {@link FileDialogStartEvent} class for more details on the data available when this 43 | * event is fired. 44 | * 45 | * @param fileDialogStartEvent The details of the event that occurred. 46 | * @return The response to send back to the event handler function 47 | */ 48 | public boolean onFileDialogStartEvent(FileDialogStartEvent fileDialogStartEvent); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/UploadCompleteEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Document Node Pty Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.docstr.gwt.uploader.client.events; 17 | 18 | import org.docstr.gwt.uploader.client.File; 19 | 20 | /** 21 | * Provides access to the raw information provided by Uploader when an 'uploader complete' event 22 | * occurs. 23 | * This class should not be instantiated directly, but instead you should create a {@link 24 | * UploadCompleteHandler} and register it via the {@link org.docstr.gwt.uploader.client 25 | * .Uploader#setUploadCompleteHandler(UploadCompleteHandler)} method in order to access uploader 26 | * complete events. 27 | *
28 | * Note that the 'uploadComplete' event is always fired at the end of an uploader cycle 29 | * (after uploadError or uploadSuccess). At this point the uploader is complete and another 30 | * uploader can be started. 31 | *
32 | * If you want the next uploader to start automatically this is a good place to call this 33 | * .uploadStart(). 34 | * Use caution when calling uploadStart inside the uploadComplete event if you also have code 35 | * that cancels all the uploads in a queue. 36 | * 37 | * @author delight.wjk@gmail.com 38 | */ 39 | public class UploadCompleteEvent extends UploadEvent { 40 | 41 | /** 42 | * This constructor is intended for internal use only. You should not create uploader complete 43 | * events directly, but instead should register a {@link UploadCompleteHandler}. 44 | * 45 | * @param file The native javascript object containing the details of the file being uploaded. 46 | */ 47 | public UploadCompleteEvent(File file) { 48 | super(file); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /gwt-uploader-demo/src/main/java/org/docstr/gwt/uploader/demo/client/SourceCodePopupPanel.java: -------------------------------------------------------------------------------- 1 | package org.docstr.gwt.uploader.demo.client; 2 | 3 | import com.google.gwt.event.dom.client.ClickEvent; 4 | import com.google.gwt.event.dom.client.ClickHandler; 5 | import com.google.gwt.user.client.Window; 6 | import com.google.gwt.user.client.ui.Button; 7 | import com.google.gwt.user.client.ui.DialogBox; 8 | import com.google.gwt.user.client.ui.HTML; 9 | import com.google.gwt.user.client.ui.HasHorizontalAlignment; 10 | import com.google.gwt.user.client.ui.PopupPanel; 11 | import com.google.gwt.user.client.ui.VerticalPanel; 12 | 13 | /** 14 | * @author jiakuanwang 15 | */ 16 | public class SourceCodePopupPanel extends DialogBox { 17 | 18 | private HTML html = new HTML(); 19 | 20 | public SourceCodePopupPanel() { 21 | // PopupPanel's constructor takes 'auto-hide' as its boolean parameter. 22 | // If this is set, the panel closes itself automatically when the user 23 | // clicks outside of it. 24 | super(true); 25 | // Set the dialog box's caption. 26 | setText("Source Code"); 27 | 28 | // Enable animation. 29 | setAnimationEnabled(true); 30 | 31 | // Enable glass background. 32 | setGlassEnabled(true); 33 | Button btnClose = new Button("Close"); 34 | btnClose.addClickHandler(new ClickHandler() { 35 | @Override 36 | public void onClick(ClickEvent event) { 37 | hide(); 38 | } 39 | }); 40 | VerticalPanel panel = new VerticalPanel(); 41 | panel.add(html); 42 | panel.add(btnClose); 43 | panel.setCellHorizontalAlignment(btnClose, HasHorizontalAlignment.ALIGN_RIGHT); 44 | setWidget(panel); 45 | } 46 | 47 | public void showSourceCode(String sourceCode) { 48 | int width = (Window.getClientWidth() - 200); 49 | int height = (Window.getClientHeight() - 200); 50 | html.setHTML( 51 | "
" 52 | + sourceCode + ""); 53 | setPopupPositionAndShow(new PopupPanel.PositionCallback() { 54 | public void setPosition(int offsetWidth, int offsetHeight) { 55 | int left = (Window.getClientWidth() - offsetWidth) / 2; 56 | int top = (Window.getClientHeight() - offsetHeight) / 2; 57 | setPopupPosition(left, top); 58 | } 59 | }); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/UploadSuccessHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Document Node Pty Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.docstr.gwt.uploader.client.events; 17 | 18 | /** 19 | * An interface that can be used as a callback handler when uploader success events are fired by 20 | * the Uploader component. General usage is as follows: 21 | *
22 | * uploader.setUploadSuccessHandler(new UploadSuccessHandler() {
23 | * public boolean onUploadSuccess(UploadSuccessEvent event) {
24 | * Window.alert("Successfully uploaded " + event.getFile().getName());
25 | * return true;
26 | * }
27 | * });
28 | *
29 | * 30 | * Note that 'uploadSuccess' is fired when the entire uploader has been transmitted and the server 31 | * returns a HTTP 200 status code. Any data outputted by the server is available in the server 32 | * data property. 33 | *
34 | * At this point the uploader is not yet complete. Another uploader cannot be started from 35 | * uploadSuccess. 36 | *
37 | * See the documentation on the {@link UploadSuccessEvent} class for more details on the data 38 | * available when an uploader success event occurs. 39 | * 40 | * @author delight.wjk@gmail.com 41 | */ 42 | public interface UploadSuccessHandler { 43 | 44 | /** 45 | * This method is fired whenever a uploader success event occurs in the Uploader component. See 46 | * the {@link UploadSuccessEvent} class for more details on the data available when this event 47 | * is fired. 48 | * 49 | * @param uploadSuccessEvent The details of the event that occurred. 50 | * @return The response to send back to the event handler function 51 | */ 52 | public boolean onUploadSuccess(UploadSuccessEvent uploadSuccessEvent); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/UploadErrorHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Document Node Pty Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.docstr.gwt.uploader.client.events; 17 | 18 | /** 19 | * An interface that can be used as a callback handler when uploader error events are fired by 20 | * the Uploader component. General usage is as follows: 21 | *
22 | * uploader.setUploadErrorHandler(new UploadErrorHandler() {
23 | * public boolean onUploadError(UploadErrorEvent event) {
24 | * Window.alert("Unable to uploader file " + event.getFile().getName());
25 | * return true;
26 | * }
27 | * });
28 | *
29 | * 30 | * Note that the 'uploadError' event is fired any time an uploader is interrupted or does not 31 | * complete successfully. The error code parameter indicates the type of error that occurred. 32 | *
33 | * Stopping, Cancelling or returning 'false' from uploadStart will cause uploadError to fire. 34 | * Uploader error will not fire for files that are cancelled but still waiting in the queue. 35 | *
36 | * See the documentation on the {@link UploadErrorEvent} class for more details on the data 37 | * available when an uploader error event occurs. 38 | * 39 | * @author delight.wjk@gmail.com 40 | */ 41 | public interface UploadErrorHandler { 42 | 43 | /** 44 | * This method is fired whenever a uploader error event occurs in the Uploader component. See 45 | * the {@link UploadErrorEvent} class for more details on the data available when this event is 46 | * fired. 47 | * 48 | * @param uploadErrorEvent The details of the event that occurred. 49 | * @return The response to send back to the event handler function 50 | */ 51 | public boolean onUploadError(UploadErrorEvent uploadErrorEvent); 52 | 53 | } 54 | -------------------------------------------------------------------------------- /gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/FileQueueErrorHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Document Node Pty Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.docstr.gwt.uploader.client.events; 17 | 18 | /** 19 | * An interface that can be used as a callback handler when file queue error events are fired by 20 | * the Uploader component. General usage is as follows: 21 | *
22 | * uploader.setFileQueueErrorEventHandler(new FileQueueErrorHandler() {
23 | * public boolean onFileQueueError(FileQueueErrorEvent event) {
24 | * Window.alert("File with name " + event.getFile().getName() + " failed in the queue due
25 | * to: " + event.getErrorCode().toString());
26 | * return true;
27 | * }
28 | * });
29 | *
30 | * Note that the 'fileQueueError' event is fired for each file that was not queued after the File
31 | * Selection Dialog window is closed. A file may not be queued for several reasons such as,
32 | * the file exceeds the file size, the file is empty or a file or queue limit has been exceeded.
33 | * 34 | * See the documentation on the {@link FileQueueErrorEvent} class for more details on the data 35 | * available when a file queue error event occurs. 36 | * 37 | * @author delight.wjk@gmail.com 38 | */ 39 | public interface FileQueueErrorHandler { 40 | 41 | /** 42 | * This method is fired whenever a file queue error event occurs in the Uploader component. See 43 | * the {@link org.docstr.gwt.uploader.client.events.FileQueueErrorEvent} class for more 44 | * details on the data available when this event is fired. 45 | * 46 | * @param fileQueueErrorEvent The details of the event that occurred. 47 | * @return The response to send back to the event handler function 48 | */ 49 | public boolean onFileQueueError(FileQueueErrorEvent fileQueueErrorEvent); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/UploadStartHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Document Node Pty Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.docstr.gwt.uploader.client.events; 17 | 18 | /** 19 | * An interface that can be used as a callback handler when uploader start events are fired by 20 | * the Uploader component. General usage is as follows: 21 | *
22 | * uploader.setUploadStartHandler(new UploadStartHandler() {
23 | * public boolean onUploadStart(UploadStartEvent event) {
24 | * Window.alert("Beginning uploader of " + event.getFile().getName());
25 | * return true;
26 | * }
27 | * });
28 | *
29 | * 30 | * Note that the 'uploadStart' event is called immediately before the file is uploaded. This event 31 | * provides an opportunity to perform any last minute validation, add post params or do any other 32 | * work before the file is uploaded. 33 | *
34 | * The uploader can be cancelled by returning 'false' from uploadStart in the handler. If you return 35 | * 'true' or do not return any value then the uploader proceeds. Returning 'false' will cause an 36 | * uploadError event to fired. 37 | *
38 | * See the documentation on the {@link UploadStartEvent} class for more details on the data 39 | * available when an uploader start event occurs. 40 | * 41 | * @author delight.wjk@gmail.com 42 | */ 43 | public interface UploadStartHandler { 44 | 45 | /** 46 | * This method is fired whenever a uploader start event occurs in the Uploader component. See 47 | * the {@link UploadStartEvent} class for more details on the data available when this event is 48 | * fired. 49 | * 50 | * @param uploadStartEvent The details of the event that occurred. 51 | * @return The response to send back to the event handler function 52 | */ 53 | public boolean onUploadStart(UploadStartEvent uploadStartEvent); 54 | 55 | } 56 | -------------------------------------------------------------------------------- /gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/UploadCompleteHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Document Node Pty Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.docstr.gwt.uploader.client.events; 17 | 18 | /** 19 | * An interface that can be used as a callback handler when uploader completion events are fired by 20 | * the Uploader component. General usage is as follows: 21 | *
22 | * uploader.setUploadCompleteHandler(new UploadCompleteHandler() {
23 | * public boolean onUploadComplete(UploadCompleteEvent event) {
24 | * Window.alert("Uploader complete for file " + event.getFile().getName());
25 | * return true;
26 | * }
27 | * });
28 | *
29 | * 30 | * Note that the 'uploadComplete' event is always fired at the end of an uploader cycle 31 | * (after uploadError or uploadSuccess). At this point the uploader is complete and another 32 | * uploader can be started. 33 | *
34 | * If you want the next uploader to start automatically this is a good place to call this 35 | * .uploadStart(). 36 | * Use caution when calling uploadStart inside the uploadComplete event if you also have code 37 | * that cancels all the uploads in a queue. 38 | *
39 | * See the documentation on the {@link UploadCompleteEvent} class for more details on the data 40 | * available when an uploader complete event occurs. 41 | * 42 | * @author delight.wjk@gmail.com 43 | */ 44 | public interface UploadCompleteHandler { 45 | 46 | /** 47 | * This method is fired whenever a uploader completion event occurs in the Uploader component. 48 | * See the {@link UploadCompleteEvent} class for more details on the data available when this 49 | * event is fired. 50 | * 51 | * @param uploadCompleteEvent The details of the event that occurred. 52 | * @return The response to send back to the event handler function 53 | */ 54 | public boolean onUploadComplete(UploadCompleteEvent uploadCompleteEvent); 55 | 56 | } 57 | -------------------------------------------------------------------------------- /gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/FileDialogCompleteHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Document Node Pty Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.docstr.gwt.uploader.client.events; 17 | 18 | /** 19 | * An interface that can be used as a callback handler when file dialog complete events are fired by 20 | * the Uploader component. General usage is as follows: 21 | *
22 | * uploader.setFileDialogCompleteHandler(new FileDialogCompleteHandler() {
23 | * public boolean onFileDialogComplete(FileDialogCompleteEvent event) {
24 | * Window.alert(event.getTotalFilesInQueue() + " are ready to uploader");
25 | * return true;
26 | * }
27 | * });
28 | *
29 | * Note that the 'fileDialogComplete' event fires after the File Selection Dialog window has been
30 | * closed and all the selected files have been processed. The 'number of files queued' property
31 | * indicates the number of files that were queued from the dialog selection (as opposed to the
32 | * number of files in the queue).
33 | * 34 | * If you want file uploading to begin automatically this is a good place to call {@link com 35 | * .jakecode.gwt.uploader.client.Uploader#startUpload()}. 36 | *
37 | * See the documentation on the {@link FileDialogCompleteEvent} class for more details on the data 38 | * available when a file dialog complete event occurs. 39 | * 40 | * @author delight.wjk@gmail.com 41 | */ 42 | public interface FileDialogCompleteHandler { 43 | 44 | /** 45 | * This method is fired whenever a file dialog complete event occurs in the Uploader component. 46 | * See the {@link FileDialogCompleteEvent} class for more details on the data available when 47 | * this event is fired. 48 | * 49 | * @param fileDialogCompleteEvent The details of the event that occurred. 50 | * @return The response to send back to the event handler function 51 | */ 52 | public boolean onFileDialogComplete(FileDialogCompleteEvent fileDialogCompleteEvent); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/UploadProgressEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Document Node Pty Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.docstr.gwt.uploader.client.events; 17 | 18 | import org.docstr.gwt.uploader.client.File; 19 | 20 | /** 21 | * Provides access to the raw information provided by Uploader when an 'uploader progress' event 22 | * occurs. 23 | * This class should not be instantiated directly, but instead you should create a 24 | * {@link UploadProgressHandler} and register it via the {@link org.docstr.gwt.uploader.client 25 | * .Uploader#setUploadProgressHandler(UploadProgressHandler)} method in order to access progress 26 | * events. 27 | *
28 | * Note that the 'uploadProgress' event is fired periodically by the control. This event is 29 | * useful for providing UI updates on the page. 30 | *
31 | *
32 | * @author delight.wjk@gmail.com
33 | */
34 | public class UploadProgressEvent extends UploadEvent {
35 |
36 | private long bytesComplete;
37 | private long bytesTotal;
38 |
39 | /**
40 | * This constructor is intended for internal use only. You should not create progress events
41 | * directly, but instead should register a {@link UploadProgressHandler}.
42 | *
43 | * @param file The native javascript object containing the details of the file being uploaded.
44 | * @param bytesComplete Bytes transferred since the uploader process began.
45 | * @param bytesTotal Total size of the file being uploaded.
46 | */
47 | public UploadProgressEvent(File file, long bytesComplete, long bytesTotal) {
48 | super(file);
49 | this.bytesComplete = bytesComplete;
50 | this.bytesTotal = bytesTotal;
51 | }
52 |
53 | /**
54 | * Return the bytes transferred since the uploader process began.
55 | * @return double
56 | */
57 | public long getBytesComplete() {
58 | return bytesComplete;
59 | }
60 |
61 | /**
62 | * Return the total size of the file being uploaded.
63 | * @return long
64 | */
65 | public long getBytesTotal() {
66 | return bytesTotal;
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/gwt-uploader-demo/src/main/java/org/docstr/gwt/uploader/demo/client/GwtUploaderDemo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Document Node Pty Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.docstr.gwt.uploader.demo.client;
18 |
19 | import com.google.gwt.core.client.EntryPoint;
20 | import com.google.gwt.dom.client.Style;
21 | import com.google.gwt.user.client.ui.Button;
22 | import com.google.gwt.user.client.ui.RootPanel;
23 | import com.google.gwt.user.client.ui.VerticalPanel;
24 | import com.google.gwt.user.client.ui.Widget;
25 |
26 | import java.util.HashMap;
27 | import java.util.Map;
28 |
29 | import static elemental2.dom.DomGlobal.console;
30 |
31 | /**
32 | * @author delight.wjk@gmail.com
33 | */
34 | public class GwtUploaderDemo implements EntryPoint {
35 |
36 | private Map
28 | * Note that 'uploadSuccess' is fired when the entire uploader has been transmitted and the server
29 | * returns a HTTP 200 status code. Any data outputted by the server is available in the server
30 | * data property.
31 | *
32 | * At this point the uploader is not yet complete. Another uploader cannot be started from
33 | * uploadSuccess.
34 | *
35 | * @author delight.wjk@gmail.com
36 | */
37 | public class UploadSuccessEvent extends UploadEvent {
38 |
39 | private String serverData;
40 | private String responseReceived;
41 |
42 | /**
43 | * This constructor is intended for internal use only. You should not create uploader success
44 | * events directly, but instead should register a {@link UploadSuccessHandler}.
45 | *
46 | * @param file The native javascript object containing the details of the file being uploaded.
47 | * @param serverData Any HTTP response data sent from the server at the completion of the
48 | * uploader.
49 | * @param responseReceived The HTTP response code sent from the server at the completion of the
50 | * uploader.
51 | */
52 | public UploadSuccessEvent(File file, String serverData, String responseReceived) {
53 | super(file);
54 | this.serverData = serverData;
55 | this.responseReceived = responseReceived;
56 | }
57 |
58 | /**
59 | * Return any HTTP response data sent from the server at the completion of the uploader.
60 | *
61 | * @return String
62 | */
63 | public String getServerData() {
64 | return serverData;
65 | }
66 |
67 | /**
68 | * Return the HTTP response code sent from the server at the completion of the uploader.
69 | *
70 | * @return String
71 | */
72 | public String getResponseReceived() {
73 | return responseReceived;
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/events/FileDialogCompleteEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Document Node Pty Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.docstr.gwt.uploader.client.events;
17 |
18 | /**
19 | * Provides access to the raw information provided by Uploader when a 'fileDialogComplete' event
20 | * occurs.
21 | * This class should not be instantiated directly, but instead you should create a {@link
22 | * FileDialogCompleteHandler} and
23 | * register it via the {@link org.docstr.gwt.uploader.client
24 | * .Uploader#setFileDialogCompleteHandler(FileDialogCompleteHandler)}
25 | * method in order to access file dialog complete events.
26 | *
27 | * Note that the 'fileDialogComplete' event fires after the File Selection Dialog window has been
28 | * closed and all the selected files have been processed. The 'number of files queued' property
29 | * indicates the number of files that were queued from the dialog selection (as opposed to the
30 | * number of files in the queue).
31 | *
32 | * If you want file uploading to begin automatically this is a good place to call {@link
33 | * org.docstr.gwt.uploader.client.Uploader#startUpload()}.
34 | *
35 | * @author delight.wjk@gmail.com
36 | */
37 | public class FileDialogCompleteEvent {
38 |
39 | private int numberOfFilesSelected;
40 | private int numberOfFilesQueued;
41 | private int totalFilesInQueue;
42 |
43 | /**
44 | * This constructor is intended for internal use only. You should not create file dialog
45 | * complete events directly, but instead should register a {@link FileDialogCompleteHandler}.
46 | *
47 | * @param numberOfFilesSelected The number of files selected in the dialog.
48 | * @param numberOfFilesQueued The number of files that were queued as a result of the dialog
49 | * selection.
50 | * @param totalFilesInQueue The total number of files now in the queue.
51 | */
52 | public FileDialogCompleteEvent(int numberOfFilesSelected, int numberOfFilesQueued,
53 | int totalFilesInQueue) {
54 | this.numberOfFilesSelected = numberOfFilesSelected;
55 | this.numberOfFilesQueued = numberOfFilesQueued;
56 | this.totalFilesInQueue = totalFilesInQueue;
57 | }
58 |
59 | /**
60 | * Return the number of files selected in the dialog.
61 | *
62 | * @return int
63 | */
64 | public int getNumberOfFilesQueued() {
65 | return numberOfFilesQueued;
66 | }
67 |
68 | /**
69 | * Return the number of files that were queued as a result of the dialog selection.
70 | *
71 | * @return int
72 | */
73 | public int getNumberOfFilesSelected() {
74 | return numberOfFilesSelected;
75 | }
76 |
77 | /**
78 | * Return the total number of files now in the queue.
79 | *
80 | * @return int
81 | */
82 | public int getTotalFilesInQueue() {
83 | return totalFilesInQueue;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/gwt-uploader-demo/src/main/java/org/docstr/gwt/uploader/demo/shared/HttpReq.java:
--------------------------------------------------------------------------------
1 | package org.docstr.gwt.uploader.demo.shared;
2 |
3 | import elemental2.core.JsError;
4 | import elemental2.dom.*;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | import static elemental2.dom.DomGlobal.console;
10 |
11 | public class HttpReq {
12 |
13 | public enum Method {
14 | GET,
15 | POST,
16 | PUT
17 | }
18 |
19 | public interface ResponseHandler {
20 |
21 | void onResult(Response response);
22 |
23 | void onError(JsError error);
24 | }
25 |
26 | private URLSearchParams queryParams = new URLSearchParams();
27 | private String[][] headers = new String[0][];
28 | private RequestInit requestInit = RequestInit.create();
29 | private ResponseHandler responseHandler;
30 |
31 | private final String url;
32 |
33 | private HttpReq(String url) {
34 | this.url = url;
35 | }
36 |
37 | public static HttpReq create(String url) {
38 | return new HttpReq(url);
39 | }
40 |
41 | public HttpReq setMethod(Method method) {
42 | requestInit.setMethod(method.name());
43 | return this;
44 | }
45 |
46 | public HttpReq addQueryParam(String name, String value) {
47 | queryParams.append(name, value);
48 | return this;
49 | }
50 |
51 | public HttpReq addHeader(String name, String value) {
52 | headers = mergeHeaders(headers, new String[][]{{name, value}});
53 | return this;
54 | }
55 |
56 | public HttpReq addHeaders(String[][] headers) {
57 | this.headers = mergeHeaders(this.headers, headers);
58 | return this;
59 | }
60 |
61 | public static String[][] mergeHeaders(
62 | String[][] headers1, String[][] headers2) {
63 | List
27 | * Note that the 'fileQueueError' event is fired for each file that was not queued after the File
28 | * Selection Dialog window is closed. A file may not be queued for several reasons such as,
29 | * the file exceeds the file size, the file is empty or a file or queue limit has been exceeded.
30 | *
31 | * The reason for the queue error is specified by the {@link #getErrorCode()} method.
32 | *
33 | * @author delight.wjk@gmail.com
34 | */
35 | public class FileQueueErrorEvent {
36 |
37 | /**
38 | * An enumeration of reported file queue error code types.
39 | */
40 | public enum ErrorCode {
41 |
42 | UNKNOWN(0),
43 | QUEUE_LIMIT_EXCEEDED(-100),
44 | FILE_EXCEEDS_SIZE_LIMIT(-110),
45 | ZERO_BYTE_FILE(-120),
46 | INVALID_FILETYPE(-130);
47 |
48 | private ErrorCode(int optionValue) {
49 | this.optionValue = optionValue;
50 | }
51 |
52 | private final int optionValue;
53 |
54 | public int toInt() {
55 | return optionValue;
56 | }
57 | }
58 |
59 | private File file;
60 | private int errorCode;
61 | private String message;
62 |
63 | /**
64 | * This constructor is intended for internal use only. You should not create file queued events
65 | * directly, but instead should register a {@link FileQueuedHandler}.
66 | *
67 | * @param file The file instance that experienced an error in the queue.
68 | * @param errorCode The error code returned by the Uploader component in the case of a file
69 | * queue failure.
70 | * @param message A human readable error message explaining the cause of the file queue failure.
71 | */
72 | public FileQueueErrorEvent(File file, int errorCode, String message) {
73 | this.file = file;
74 | this.errorCode = errorCode;
75 | this.message = message;
76 | }
77 |
78 | /**
79 | * Return the details of the file that experienced the error in the queue.
80 | *
81 | * @return File
82 | */
83 | public File getFile() {
84 | return file;
85 | }
86 |
87 | /**
88 | * The error code returned by the Uploader component in the case of a file queu failure,
89 | * conveniently converted to an enumeration type.
90 | *
91 | * @return ErrorCode
92 | */
93 | public ErrorCode getErrorCode() {
94 | if (errorCode == ErrorCode.QUEUE_LIMIT_EXCEEDED.toInt()) {
95 | return ErrorCode.QUEUE_LIMIT_EXCEEDED;
96 | } else if (errorCode == ErrorCode.FILE_EXCEEDS_SIZE_LIMIT.toInt()) {
97 | return ErrorCode.FILE_EXCEEDS_SIZE_LIMIT;
98 | } else if (errorCode == ErrorCode.ZERO_BYTE_FILE.toInt()) {
99 | return ErrorCode.ZERO_BYTE_FILE;
100 | } else if (errorCode == ErrorCode.INVALID_FILETYPE.toInt()) {
101 | return ErrorCode.INVALID_FILETYPE;
102 | } else {
103 | return ErrorCode.UNKNOWN;
104 | }
105 | }
106 |
107 | /**
108 | * The original numeric error code returned by the Uploader component in the case of a file
109 | * queue failure.
110 | *
111 | * @return int
112 | */
113 | public int getErrorCodeAsInt() {
114 | return errorCode;
115 | }
116 |
117 | /**
118 | * Return a human readable error message explaining the cause of the file queue failure.
119 | *
120 | * @return String
121 | */
122 | public String getMessage() {
123 | return message;
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GWT Uploader
2 |
3 | 
4 |
5 | An API to enable sophisticated file upload capabilities within a GWT application.
6 |
7 | The source code was forked from http://www.moxiegroup.com/moxieapps/gwt-uploader/ and applied a few fixes.
8 |
9 | Please see examples with source code here: [http://gwt-uploader.appspot.com/](http://gwt-uploader.appspot.com/)
10 |
11 | * For GWT 2.7.0, please use gwt-upload 1.1.x
12 | * For GWT 2.8.0+, please use gwt-upload 1.2.x
13 |
14 | ## What is it?
15 | GWT Uploader is a freely available open source GWT library that encapsulates the file upload capabilities provided by the File and XMLHttpRequest Level 2 APIs.
16 |
17 | Using GWT Uploader allows for enhanced file upload dialogs (multiple uploads, drag and drop, queues, parallel streams, etc.) and interactive interfaces (upload progress indicators, real-time throughput display, upload cancellation, etc.) within GWT applications using pure Java code that provides a consistent experience across all browsers.
18 |
19 | If the browser is capable of handling file uploads using a modern HTML5 approach, the upload is handled using pure DOM elements and Javascript events. In the case that the browser does not support the modern approach an error is shown.
20 |
21 | ## Key Features
22 | * **Simple**: Adds consistent file upload support to all modern browsers with a single implementation, while still supporting legacy browsers automatically.
23 | * **Pure Java**: The entire set of file upload capabilities are available via GWT powered Java methods, including clean interfaces for the various runtime callbacks (no need to write any JavaScript).
24 | * **Customizable Interfaces**: GWT Uploader exposes all the file upload capabilities as a GWT Widget, making it easy to create your own aesthetic for your upload controls or leave it simple and benefit from the multiple file selection and queued uploading. Convenient methods are also provided to enable file uploads via a familiar drag and drop approach.
25 | * **Clean Syntax**: The API is built using fluent methods that allow you to manage the configuration options of the the upload control using syntax that is nearly as tight as JSON.
26 | * **Dynamic**: GWT Uploader automatically includes the necessary plugin capabilities to expose various throughput and performance metrics of the uploads during and after an upload. Each File object has the following properties:
27 |
28 | * getAverageSpeed() -- Overall average upload speed, in bytes per second
29 | * getCurrentSpeed() -- String indicating the upload speed, in bytes per second
30 | * getMovingAverageSpeed() -- Speed over averaged over the last several measurements, in bytes per second
31 | * getPercentUploaded() -- Percentage of the file uploaded (0 to 100)
32 | * getSizeUploaded() -- Formatted size uploaded so far, bytes
33 | * getTimeElapsed() -- Number of seconds passed for this upload
34 | * getTimeRemaining() -- Estimated remaining upload time in seconds
35 | These metrics allow for dynamic updates to occur in your interface, whether it's progress bars or text labels, as data is transferred for one or more files.
36 | * **Documented**: Every class and method of the API is thoroughly documented, including numerous code and syntax examples throughout.
37 | * **Examples**: The demonstration examples provide several [basic examples](http://gwt-uploader.appspot.com/) of upload interfaces that demonstrate the flexibility and integration opportunities available, with each example including a convenient "View Source" button that will allow you to see the code behind each implementation.
38 |
39 | ## Configure Maven dependency
40 |
41 | GWT Uploader is available in Maven central repository:
42 |
43 | http://search.maven.org/#search%7Cga%7C1%7Cgwt-uploader
44 |
45 | To add the dependency to your `build.gradle` (for Gradle projects) or `pom.xml` (for Maven projects), use the following configuration:
46 |
47 | For Gradle projects:
48 |
49 | ```
50 | implementation 'org.docstr:gwt-uploader:1.2.5'
51 | ```
52 |
53 | For Maven projects:
54 |
55 | ```
56 |
28 | * Note that the 'uploadError' event is fired any time an uploader is interrupted or does not
29 | * complete successfully. The error code parameter indicates the type of error that occurred.
30 | *
31 | * Stopping, Cancelling or returning 'false' from uploadStart will cause uploadError to fire.
32 | * Uploader error will not fire for files that are cancelled but still waiting in the queue.
33 | *
34 | * @author delight.wjk@gmail.com
35 | */
36 | public class UploadErrorEvent extends UploadEvent {
37 |
38 | /**
39 | * An enumeration of reported uploaded error code types.
40 | */
41 | public enum ErrorCode {
42 |
43 | UNKNOWN(0),
44 | HTTP_ERROR(-200),
45 | MISSING_UPLOAD_URL(-210),
46 | IO_ERROR(-220),
47 | SECURITY_ERROR(-230),
48 | UPLOAD_LIMIT_EXCEEDED(-240),
49 | UPLOAD_FAILED(-250),
50 | SPECIFIED_FILE_ID_NOT_FOUND(-260),
51 | FILE_VALIDATION_FAILED(-270),
52 | FILE_CANCELLED(-280),
53 | UPLOAD_STOPPED(-290);
54 |
55 | private ErrorCode(int optionValue) {
56 | this.optionValue = optionValue;
57 | }
58 |
59 | private final int optionValue;
60 |
61 | public int toInt() {
62 | return optionValue;
63 | }
64 | }
65 |
66 | private int errorCode;
67 | private String message;
68 | private String serverData;
69 |
70 | /**
71 | * This constructor is intended for internal use only. You should not create uploader error
72 | * events directly, but instead should register a {@link UploadErrorHandler}.
73 | *
74 | * @param file The native javascript object containing the details of the file being
75 | * uploaded.
76 | * @param errorCode The error code returned by the Uploader component in the case of an
77 | * uploader failure.
78 | * @param message A human readable error message explaining the cause of the uploader failure.
79 | *
80 | * @param serverData Server response (if any).
81 | */
82 | public UploadErrorEvent(File file, int errorCode, String message, String serverData) {
83 | super(file);
84 | this.errorCode = errorCode;
85 | this.message = message;
86 | this.serverData = serverData;
87 | }
88 |
89 | /**
90 | * The error code returned by the Uploader component in the case of an uploader failure,
91 | * conveniently converted to an enumeration type.
92 | *
93 | * @return ErrorCode
94 | */
95 | public ErrorCode getErrorCode() {
96 | if (errorCode == ErrorCode.HTTP_ERROR.toInt()) {
97 | return ErrorCode.HTTP_ERROR;
98 | } else if (errorCode == ErrorCode.MISSING_UPLOAD_URL.toInt()) {
99 | return ErrorCode.MISSING_UPLOAD_URL;
100 | } else if (errorCode == ErrorCode.IO_ERROR.toInt()) {
101 | return ErrorCode.IO_ERROR;
102 | } else if (errorCode == ErrorCode.SECURITY_ERROR.toInt()) {
103 | return ErrorCode.SECURITY_ERROR;
104 | } else if (errorCode == ErrorCode.UPLOAD_LIMIT_EXCEEDED.toInt()) {
105 | return ErrorCode.UPLOAD_LIMIT_EXCEEDED;
106 | } else if (errorCode == ErrorCode.UPLOAD_FAILED.toInt()) {
107 | return ErrorCode.UPLOAD_FAILED;
108 | } else if (errorCode == ErrorCode.SPECIFIED_FILE_ID_NOT_FOUND.toInt()) {
109 | return ErrorCode.SPECIFIED_FILE_ID_NOT_FOUND;
110 | } else if (errorCode == ErrorCode.FILE_VALIDATION_FAILED.toInt()) {
111 | return ErrorCode.FILE_VALIDATION_FAILED;
112 | } else if (errorCode == ErrorCode.FILE_CANCELLED.toInt()) {
113 | return ErrorCode.FILE_CANCELLED;
114 | } else if (errorCode == ErrorCode.UPLOAD_STOPPED.toInt()) {
115 | return ErrorCode.UPLOAD_STOPPED;
116 | } else {
117 | return ErrorCode.UNKNOWN;
118 | }
119 | }
120 |
121 | /**
122 | * The original numeric error code returned by the Uploader component in the case of an
123 | * uploader failure.
124 | *
125 | * @return int
126 | */
127 | public int getErrorCodeAsInt() {
128 | return errorCode;
129 | }
130 |
131 | /**
132 | * Return a human readable error message explaining the cause of the uploader failure.
133 | *
134 | * @return String
135 | */
136 | public String getMessage() {
137 | return message;
138 | }
139 |
140 | /**
141 | * Return a server response (if any).
142 | *
143 | * @return String
144 | */
145 | public String getServerData() {
146 | return serverData;
147 | }
148 |
149 | }
150 |
--------------------------------------------------------------------------------
/gwt-uploader-demo/src/main/java/org/docstr/gwt/uploader/demo/client/TextButtonAndProgressText.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Document Node Pty Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.docstr.gwt.uploader.demo.client;
18 |
19 | import com.google.gwt.core.client.EntryPoint;
20 | import com.google.gwt.i18n.client.NumberFormat;
21 | import com.google.gwt.user.client.Window;
22 | import com.google.gwt.user.client.ui.*;
23 | import org.docstr.gwt.uploader.client.Uploader;
24 | import org.docstr.gwt.uploader.client.events.*;
25 |
26 | /**
27 | * Simple Text Link and Progress text label example of GWT Uploader.
28 | *
29 | * @author delight.wjk@gmail.com
30 | */
31 | public class TextButtonAndProgressText implements EntryPoint, UploaderSample {
32 |
33 | private Label progressLabel = new Label();
34 | private Uploader uploader = new Uploader();
35 |
36 | public void onModuleLoad() {
37 | //noinspection GwtToHtmlReferences
38 | RootPanel.get("TextButtonAndProgressText").add(getUploaderPanel());
39 | }
40 |
41 | @Override
42 | public Widget getUploaderPanel() {
43 | progressLabel.setStyleName("progressLabel");
44 | uploader.setUploadURL(UPLOAD_URL)
45 | .setButtonText("")
46 | .setButtonTextStyle(
47 | ".buttonText {font-family: Arial, sans-serif; font-size: 14px; color: #BB4B44}")
48 | .setFileSizeLimit("50 MB")
49 | .setButtonWidth(150)
50 | .setButtonHeight(22)
51 | .setButtonCursor(Uploader.Cursor.HAND)
52 | .setButtonAction(Uploader.ButtonAction.SELECT_FILE)
53 | .setUploadProgressHandler(new UploadProgressHandler() {
54 | public boolean onUploadProgress(UploadProgressEvent uploadProgressEvent) {
55 | progressLabel.setText(NumberFormat.getPercentFormat().format(
56 | (double) uploadProgressEvent.getBytesComplete() / (double) uploadProgressEvent
57 | .getBytesTotal()
58 | ));
59 | return true;
60 | }
61 | })
62 | .setUploadSuccessHandler(new UploadSuccessHandler() {
63 | public boolean onUploadSuccess(UploadSuccessEvent uploadSuccessEvent) {
64 | resetText();
65 | StringBuilder sb = new StringBuilder();
66 | sb.append("File ").append(uploadSuccessEvent.getFile().getName())
67 | .append(" (")
68 | .append(NumberFormat.getDecimalFormat()
69 | .format(uploadSuccessEvent.getFile().getSize() / 1024))
70 | .append(" KB)")
71 | .append(" uploaded successfully at ")
72 | .append(NumberFormat.getDecimalFormat().format(
73 | uploadSuccessEvent.getFile().getAverageSpeed() / 1024
74 | ))
75 | .append(" Kb/second");
76 | progressLabel.setText(sb.toString());
77 | return true;
78 | }
79 | })
80 | .setFileDialogCompleteHandler(new FileDialogCompleteHandler() {
81 | public boolean onFileDialogComplete(FileDialogCompleteEvent fileDialogCompleteEvent) {
82 | if (fileDialogCompleteEvent.getTotalFilesInQueue() > 0
83 | && uploader.getStats().getUploadsInProgress() <= 0) {
84 | progressLabel.setText("0%");
85 | uploader.setButtonText("");
86 | uploader.startUpload();
87 | }
88 | return true;
89 | }
90 | })
91 | .setFileQueueErrorHandler(new FileQueueErrorHandler() {
92 | public boolean onFileQueueError(FileQueueErrorEvent fileQueueErrorEvent) {
93 | resetText();
94 | Window.alert(
95 | "Upload of file " + fileQueueErrorEvent.getFile().getName() + " failed due to [" +
96 | fileQueueErrorEvent.getErrorCode().toString() + "]: " + fileQueueErrorEvent
97 | .getMessage()
98 | );
99 | return true;
100 | }
101 | })
102 | .setUploadErrorHandler(new UploadErrorHandler() {
103 | public boolean onUploadError(UploadErrorEvent uploadErrorEvent) {
104 | resetText();
105 | Window.alert(
106 | "Upload of file " + uploadErrorEvent.getFile().getName() + " failed due to [" +
107 | uploadErrorEvent.getErrorCode().toString() + "]: " + uploadErrorEvent.getMessage()
108 | );
109 | return true;
110 | }
111 | });
112 |
113 | VerticalPanel verticalPanel = new VerticalPanel();
114 | verticalPanel.add(uploader);
115 | verticalPanel.add(progressLabel);
116 | verticalPanel.setCellHorizontalAlignment(uploader, HorizontalPanel.ALIGN_LEFT);
117 | verticalPanel.setCellHorizontalAlignment(progressLabel, HorizontalPanel.ALIGN_LEFT);
118 | return verticalPanel;
119 | }
120 |
121 | private void resetText() {
122 | progressLabel.setText("");
123 | uploader.setButtonText("");
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/gwt-uploader-demo/src/main/java/org/docstr/gwt/uploader/demo/client/ImageButtonAndProgressBar.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Document Node Pty Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.docstr.gwt.uploader.demo.client;
18 |
19 | import com.google.gwt.core.client.EntryPoint;
20 | import com.google.gwt.event.dom.client.ClickEvent;
21 | import com.google.gwt.event.dom.client.ClickHandler;
22 | import com.google.gwt.user.client.Window;
23 | import com.google.gwt.user.client.ui.HorizontalPanel;
24 | import com.google.gwt.user.client.ui.Image;
25 | import com.google.gwt.user.client.ui.RootPanel;
26 | import com.google.gwt.user.client.ui.Widget;
27 | import org.docstr.gwt.uploader.client.Uploader;
28 | import org.docstr.gwt.uploader.client.events.*;
29 | import org.docstr.gwt.uploader.client.progress.ProgressBar;
30 |
31 | /**
32 | * Uploader Image Button and GWT Progress Bar example of GWT Uploader.
33 | *
34 | * @author delight.wjk@gmail.com
35 | */
36 | public class ImageButtonAndProgressBar implements EntryPoint, UploaderSample {
37 |
38 | final Uploader uploader = new Uploader();
39 | private ProgressBar progressBar =
40 | new ProgressBar(0.0, 1.0, 0.0, new CancelProgressBarTextFormatter());
41 | private Image cancelButton = new Image(AppResources.INSTANCE.cancel().getSafeUri().asString());
42 |
43 | public void onModuleLoad() {
44 | //noinspection GwtToHtmlReferences
45 | RootPanel.get("ImageButtonAndProgressBar").add(getUploaderPanel());
46 | }
47 |
48 | @Override
49 | public Widget getUploaderPanel() {
50 | final HorizontalPanel horizontalPanel = new HorizontalPanel();
51 |
52 | uploader.setUploadURL(UPLOAD_URL)
53 | .setButtonImageURL(AppResources.INSTANCE.upload().getSafeUri().asString())
54 | .setButtonWidth(133)
55 | .setButtonHeight(22)
56 | .setFileSizeLimit("50 MB")
57 | .setButtonCursor(Uploader.Cursor.HAND)
58 | .setButtonAction(Uploader.ButtonAction.SELECT_FILE)
59 | .setFileQueuedHandler(new FileQueuedHandler() {
60 | public boolean onFileQueued(final FileQueuedEvent fileQueuedEvent) {
61 | // Create a Progress Bar for this file
62 | progressBar.setTitle(fileQueuedEvent.getFile().getName());
63 | progressBar.setHeight("18px");
64 | progressBar.setWidth("200px");
65 |
66 | // Add Cancel Button Image
67 | cancelButton.setStyleName("cancelButton");
68 | cancelButton.addClickHandler(new ClickHandler() {
69 | public void onClick(ClickEvent event) {
70 | uploader.cancelUpload(fileQueuedEvent.getFile().getId(), false);
71 | progressBar.setProgress(-1.0d);
72 | cancelButton.removeFromParent();
73 | }
74 | });
75 |
76 | horizontalPanel.add(progressBar);
77 | horizontalPanel.add(cancelButton);
78 |
79 | return true;
80 | }
81 | })
82 | .setFileDialogStartHandler(new FileDialogStartHandler() {
83 | public boolean onFileDialogStartEvent(FileDialogStartEvent fileDialogStartEvent) {
84 | if (uploader.getStats().getUploadsInProgress() <= 0) {
85 | progressBar.removeFromParent();
86 | cancelButton.removeFromParent();
87 | }
88 | return true;
89 | }
90 | })
91 | .setUploadProgressHandler(new UploadProgressHandler() {
92 | public boolean onUploadProgress(UploadProgressEvent uploadProgressEvent) {
93 | progressBar.setProgress(
94 | (double) uploadProgressEvent.getBytesComplete() / uploadProgressEvent
95 | .getBytesTotal()
96 | );
97 | return true;
98 | }
99 | })
100 | .setUploadSuccessHandler(new UploadSuccessHandler() {
101 | public boolean onUploadSuccess(UploadSuccessEvent uploadSuccessEvent) {
102 | cancelButton.removeFromParent();
103 | return true;
104 | }
105 | })
106 | .setFileDialogCompleteHandler(new FileDialogCompleteHandler() {
107 | public boolean onFileDialogComplete(FileDialogCompleteEvent fileDialogCompleteEvent) {
108 | if (fileDialogCompleteEvent.getTotalFilesInQueue() > 0
109 | && uploader.getStats().getUploadsInProgress() <= 0) {
110 | progressBar.setProgress(0.0);
111 | uploader.startUpload();
112 | }
113 | return true;
114 | }
115 | })
116 | .setFileQueueErrorHandler(new FileQueueErrorHandler() {
117 | public boolean onFileQueueError(FileQueueErrorEvent fileQueueErrorEvent) {
118 | progressBar.setProgress(0.0);
119 | cancelButton.removeFromParent();
120 | Window.alert(
121 | "Upload of file " + fileQueueErrorEvent.getFile().getName() + " failed due to [" +
122 | fileQueueErrorEvent.getErrorCode().toString() + "]: " + fileQueueErrorEvent
123 | .getMessage()
124 | );
125 | return true;
126 | }
127 | })
128 | .setUploadErrorHandler(new UploadErrorHandler() {
129 | public boolean onUploadError(UploadErrorEvent uploadErrorEvent) {
130 | progressBar.setProgress(0.0);
131 | cancelButton.removeFromParent();
132 | Window
133 | .alert(
134 | "Upload of file " + uploadErrorEvent.getFile().getName() + " failed due to [" +
135 | uploadErrorEvent.getErrorCode().toString() + "]: " + uploadErrorEvent
136 | .getMessage()
137 | );
138 | return true;
139 | }
140 | });
141 |
142 | horizontalPanel.add(uploader);
143 | horizontalPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
144 | horizontalPanel.setCellHorizontalAlignment(uploader, HorizontalPanel.ALIGN_RIGHT);
145 | return horizontalPanel;
146 | }
147 |
148 | protected class CancelProgressBarTextFormatter extends ProgressBar.TextFormatter {
149 |
150 | @Override
151 | protected String getText(ProgressBar bar, double curProgress) {
152 | if (curProgress < 0) {
153 | return "Cancelled";
154 | }
155 | return ((int) (100 * bar.getPercent())) + "%";
156 | }
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/gwt-uploader/src/main/java/org/docstr/gwt/uploader/client/File.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Document Node Pty Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.docstr.gwt.uploader.client;
17 |
18 | import com.google.gwt.core.client.JavaScriptObject;
19 |
20 | import org.docstr.gwt.uploader.client.events.UploadProgressEvent;
21 |
22 | import java.util.Date;
23 |
24 | /**
25 | * A logical bean that provides access to the details of a file being uploaded. An instance
26 | * of this object is available on all uploader related event handlers, such as the
27 | * {@link org.docstr.gwt.uploader.client.events.UploadProgressHandler}.
28 | *
29 | *
30 | * @author delight.wjk@gmail.com
31 | */
32 | public final class File extends JavaScriptObject {
33 |
34 | /**
35 | * An enumeration of reported file status types, which can be determined during
36 | * any of the uploader events, such as {@link UploadProgressEvent#getFile()}.
37 | */
38 | public enum Status {
39 |
40 | UNKNOWN(0),
41 | QUEUED(-1),
42 | IN_PROGRESS(-2),
43 | ERROR(-3),
44 | COMPLETE(-4),
45 | CANCELLED(-5);
46 |
47 | private Status(int optionValue) {
48 | this.optionValue = optionValue;
49 | }
50 |
51 | private final int optionValue;
52 |
53 | public int toInt() {
54 | return optionValue;
55 | }
56 | }
57 |
58 | /**
59 | * Instances of the File object can not be created directly, but should instead
60 | * be obtained via an event handler.
61 | * E.g. {@link org.docstr.gwt.uploader.client.events.UploadProgressEvent#getFile()}.
62 | */
63 | protected File() {
64 | }
65 |
66 | /**
67 | * Return the unique id of the file instance as it is being maintained within the Uploader
68 | * component file queue.
69 | *
70 | * @return String
71 | */
72 | public native String getId() /*-{
73 | return this.id;
74 | }-*/;
75 |
76 | /**
77 | * Return the index of the file within the queue of files being uploaded by the
78 | * Uploader component.
79 | *
80 | * @return int
81 | */
82 | public native int getIndex() /*-{
83 | return this.index;
84 | }-*/;
85 |
86 | /**
87 | * Return the original name of the file being uploaded.
88 | *
89 | * @return String
90 | */
91 | public native String getName() /*-{
92 | return this.name;
93 | }-*/;
94 |
95 | /**
96 | * Return the original size of the file being uploaded (in bytes).
97 | *
98 | * @return long
99 | */
100 | public long getSize() {
101 | return (long) nativeGetSize();
102 | }
103 |
104 | /**
105 | * Return the mime type of the file being uploaded.
106 | *
107 | * @return String
108 | */
109 | public native String getType() /*-{
110 | return this.type;
111 | }-*/;
112 |
113 | /**
114 | * Return the date the file was last modified, as reported by the client machine, or null
115 | * if the browser or OS did not make the file's modification date available.
116 | *
117 | * @return Date
118 | */
119 | public Date getModificationDate() {
120 | long date = (long) nativeGetModificationDate();
121 | return date > 0 ? new Date(date) : null;
122 | }
123 |
124 | /**
125 | * Get the file's current status (see {@link Status} enumeration for possible values).
126 | *
127 | * @return Status
128 | */
129 | public Status getStatus() {
130 | switch (nativeGetStatus()) {
131 | case -1:
132 | return Status.QUEUED;
133 | case -2:
134 | return Status.IN_PROGRESS;
135 | case -3:
136 | return Status.ERROR;
137 | case -4:
138 | return Status.COMPLETE;
139 | case -5:
140 | return Status.CANCELLED;
141 | default:
142 | return Status.UNKNOWN;
143 | }
144 | }
145 |
146 | /**
147 | * Return a floating point number indicating the current uploader speed of
148 | * the file, in bits per second.
149 | *
150 | * @return double
151 | */
152 | public native double getCurrentSpeed() /*-{
153 | return this.currentSpeed ? this.currentSpeed : 0.0;
154 | }-*/;
155 |
156 | /**
157 | * Return a floating point number indicating the overall average uploader speed,
158 | * bytes per second, in bits per second.
159 | *
160 | * @return double
161 | */
162 | public native double getAverageSpeed() /*-{
163 | return this.averageSpeed ? this.averageSpeed : 0.0;
164 | }-*/;
165 |
166 | /**
167 | * Return a floating point number indicating the uploader speed averaged over the
168 | * last several measurements, in bits per second.
169 | *
170 | * @return double
171 | */
172 | public native double getMovingAverageSpeed() /*-{
173 | return this.movingAverageSpeed ? this.movingAverageSpeed : 0.0;
174 | }-*/;
175 |
176 | /**
177 | * Return a floating point number indicating the estimated remaining
178 | * uploader time, in seconds.
179 | *
180 | * @return double
181 | */
182 | public native double getTimeRemaining() /*-{
183 | return this.timeRemaining ? this.timeRemaining : 0.0;
184 | }-*/;
185 |
186 | /**
187 | * Return a floating point number indicating the number of seconds
188 | * passed so far for this uploader.
189 | *
190 | * @return double
191 | */
192 | public native double getTimeElapsed() /*-{
193 | return this.timeElapsed ? this.timeElapsed : 0.0;
194 | }-*/;
195 |
196 | /**
197 | * Return a floating point number indicating the percentage of the
198 | * file uploaded (0 to 100).
199 | *
200 | * @return double
201 | */
202 | public native double getPercentUploaded() /*-{
203 | return this.percentUploaded ? this.percentUploaded : 0.0;
204 | }-*/;
205 |
206 | /**
207 | * Return a floating point number indicating the size uploaded so far, in bytes.
208 | *
209 | * @return double
210 | */
211 | public native double getSizeUploaded() /*-{
212 | return this.sizeUploaded ? this.sizeUploaded : 0.0;
213 | }-*/;
214 |
215 | private native double nativeGetSize() /*-{
216 | return this.size ? this.size : 0.0;
217 | }-*/;
218 |
219 | private native double nativeGetModificationDate() /*-{
220 | return this.modificationdate != null ? this.modificationdate.getTime() : 0;
221 | }-*/;
222 |
223 | private native int nativeGetStatus() /*-{
224 | return this.filestatus ? this.filestatus : 0; // 0 == UNKNOWN
225 | }-*/;
226 |
227 | }
228 |
--------------------------------------------------------------------------------
/gwt-uploader-demo/src/main/java/org/docstr/gwt/uploader/demo/client/MultiUploadWithProgressBar.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Document Node Pty Ltd
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.docstr.gwt.uploader.demo.client;
18 |
19 | import com.google.gwt.core.client.EntryPoint;
20 | import com.google.gwt.event.dom.client.ClickEvent;
21 | import com.google.gwt.event.dom.client.ClickHandler;
22 | import com.google.gwt.user.client.Window;
23 | import com.google.gwt.user.client.ui.*;
24 | import org.docstr.gwt.uploader.client.Uploader;
25 | import org.docstr.gwt.uploader.client.events.*;
26 | import org.docstr.gwt.uploader.client.progress.ProgressBar;
27 |
28 | import java.util.LinkedHashMap;
29 | import java.util.Map;
30 |
31 | /**
32 | * Uploader Image Button with multiple file selection and GWT Progress Bars example of
33 | * GWT Uploader.
34 | *
35 | * @author delight.wjk@gmail.com
36 | */
37 | public class MultiUploadWithProgressBar implements EntryPoint, UploaderSample {
38 |
39 | private final Uploader uploader = new Uploader();
40 |
41 | public void onModuleLoad() {
42 | //noinspection GwtToHtmlReferences
43 | RootPanel.get("MultiUploadWithProgressBar").add(getUploaderPanel());
44 | }
45 |
46 | @Override
47 | public Widget getUploaderPanel() {
48 | final VerticalPanel progressBarPanel = new VerticalPanel();
49 | final MapCSS Style Rules
26 | *
27 | *
36 | */
37 | public class ProgressBar extends Widget implements ResizableWidget {
38 |
39 | private static final String DEFAULT_TEXT_CLASS_NAME =
40 | "gwt-ProgressBar-text";
41 |
42 | private String textClassName = DEFAULT_TEXT_CLASS_NAME;
43 | private String textFirstHalfClassName = DEFAULT_TEXT_CLASS_NAME + "-firstHalf";
44 | private String textSecondHalfClassName = DEFAULT_TEXT_CLASS_NAME + "-secondHalf";
45 |
46 | /**
47 | * A formatter used to format the text displayed in the progress bar widget.
48 | */
49 | public abstract static class TextFormatter {
50 |
51 | /**
52 | * Generate the text to display in the ProgressBar based on the current
53 | * value.
54 | *
55 | * Override this method to change the text displayed within the ProgressBar.
56 | *
57 | * @param bar the progress bar
58 | * @param curProgress the current progress
59 | * @return the text to display in the progress bar
60 | */
61 | protected abstract String getText(ProgressBar bar, double curProgress);
62 | }
63 |
64 | /**
65 | * The bar element that displays the progress.
66 | */
67 | private Element barElement;
68 |
69 | /**
70 | * The current progress.
71 | */
72 | private double curProgress;
73 |
74 | /**
75 | * The maximum progress.
76 | */
77 | private double maxProgress;
78 |
79 | /**
80 | * The minimum progress.
81 | */
82 | private double minProgress;
83 |
84 | /**
85 | * A boolean that determines if the text is visible.
86 | */
87 | private boolean textVisible = true;
88 |
89 | /**
90 | * The element that displays text on the page.
91 | */
92 | private Element textElement;
93 |
94 | /**
95 | * The current text formatter.
96 | */
97 | private TextFormatter textFormatter;
98 |
99 | /**
100 | * Create a progress bar with default range of 0 to 100.
101 | */
102 | public ProgressBar() {
103 | this(0.0, 100.0, 0.0);
104 | }
105 |
106 | /**
107 | * Create a progress bar with an initial progress and a default range of 0 to
108 | * 100.
109 | *
110 | * @param curProgress the current progress
111 | */
112 | public ProgressBar(double curProgress) {
113 | this(0.0, 100.0, curProgress);
114 | }
115 |
116 | /**
117 | * Create a progress bar within the given range.
118 | *
119 | * @param minProgress the minimum progress
120 | * @param maxProgress the maximum progress
121 | */
122 | public ProgressBar(double minProgress, double maxProgress) {
123 | this(minProgress, maxProgress, 0.0);
124 | }
125 |
126 | /**
127 | * Create a progress bar within the given range starting at the specified
128 | * progress amount.
129 | *
130 | * @param minProgress the minimum progress
131 | * @param maxProgress the maximum progress
132 | * @param curProgress the current progress
133 | */
134 | public ProgressBar(double minProgress, double maxProgress, double curProgress) {
135 | this(minProgress, maxProgress, curProgress, null);
136 | }
137 |
138 | /**
139 | * Create a progress bar within the given range starting at the specified
140 | * progress amount.
141 | *
142 | * @param minProgress the minimum progress
143 | * @param maxProgress the maximum progress
144 | * @param curProgress the current progress
145 | * @param textFormatter the text formatter
146 | */
147 | public ProgressBar(double minProgress, double maxProgress,
148 | double curProgress, TextFormatter textFormatter) {
149 | this.minProgress = minProgress;
150 | this.maxProgress = maxProgress;
151 | this.curProgress = curProgress;
152 | setTextFormatter(textFormatter);
153 |
154 | // Create the outer shell
155 | setElement(DOM.createDiv());
156 | DOM.setStyleAttribute(getElement(), "position", "relative");
157 | setStyleName("gwt-ProgressBar-shell");
158 |
159 | // Create the bar element
160 | barElement = DOM.createDiv();
161 | DOM.appendChild(getElement(), barElement);
162 | DOM.setStyleAttribute(barElement, "height", "100%");
163 | setBarStyleName("gwt-ProgressBar-bar");
164 |
165 | // Create the text element
166 | textElement = DOM.createDiv();
167 | DOM.appendChild(getElement(), textElement);
168 | DOM.setStyleAttribute(textElement, "position", "absolute");
169 | DOM.setStyleAttribute(textElement, "top", "0px");
170 |
171 | // Set the current progress
172 | setProgress(curProgress);
173 | }
174 |
175 | /**
176 | * Get the maximum progress.
177 | *
178 | * @return the maximum progress
179 | */
180 | public double getMaxProgress() {
181 | return maxProgress;
182 | }
183 |
184 | /**
185 | * Get the minimum progress.
186 | *
187 | * @return the minimum progress
188 | */
189 | public double getMinProgress() {
190 | return minProgress;
191 | }
192 |
193 | /**
194 | * Get the current percent complete, relative to the minimum and maximum
195 | * values. The percent will always be between 0.0 - 1.0.
196 | *
197 | * @return the current percent complete
198 | */
199 | public double getPercent() {
200 | // If we have no range
201 | if (maxProgress <= minProgress) {
202 | return 0.0;
203 | }
204 |
205 | // Calculate the relative progress
206 | double percent = (curProgress - minProgress) / (maxProgress - minProgress);
207 | return Math.max(0.0, Math.min(1.0, percent));
208 | }
209 |
210 | /**
211 | * Get the current progress.
212 | *
213 | * @return the current progress
214 | */
215 | public double getProgress() {
216 | return curProgress;
217 | }
218 |
219 | /**
220 | * Get the text formatter.
221 | *
222 | * @return the text formatter
223 | */
224 | public TextFormatter getTextFormatter() {
225 | return textFormatter;
226 | }
227 |
228 | /**
229 | * Check whether the text is visible or not.
230 | *
231 | * @return true if the text is visible
232 | */
233 | public boolean isTextVisible() {
234 | return textVisible;
235 | }
236 |
237 | /**
238 | * This method is called when the dimensions of the parent element change.
239 | * Subclasses should override this method as needed.
240 | *
241 | * Move the text to the center of the progress bar.
242 | *
243 | * @param width the new client width of the element
244 | * @param height the new client height of the element
245 | */
246 | public void onResize(int width, int height) {
247 | if (textVisible) {
248 | int textWidth = DOM.getElementPropertyInt(textElement, "offsetWidth");
249 | int left = (width / 2) - (textWidth / 2);
250 | DOM.setStyleAttribute(textElement, "left", left + "px");
251 | }
252 | }
253 |
254 | /**
255 | * Redraw the progress bar when something changes the layout.
256 | */
257 | public void redraw() {
258 | if (isAttached()) {
259 | int width = DOM.getElementPropertyInt(getElement(), "clientWidth");
260 | int height = DOM.getElementPropertyInt(getElement(), "clientHeight");
261 | onResize(width, height);
262 | }
263 | }
264 |
265 | public void setBarStyleName(String barClassName) {
266 | DOM.setElementProperty(barElement, "className", barClassName);
267 | }
268 |
269 | /**
270 | * Set the maximum progress. If the minimum progress is more than the current
271 | * progress, the current progress is adjusted to be within the new range.
272 | *
273 | * @param maxProgress the maximum progress
274 | */
275 | public void setMaxProgress(double maxProgress) {
276 | this.maxProgress = maxProgress;
277 | curProgress = Math.min(curProgress, maxProgress);
278 | resetProgress();
279 | }
280 |
281 | /**
282 | * Set the minimum progress. If the minimum progress is more than the current
283 | * progress, the current progress is adjusted to be within the new range.
284 | *
285 | * @param minProgress the minimum progress
286 | */
287 | public void setMinProgress(double minProgress) {
288 | this.minProgress = minProgress;
289 | curProgress = Math.max(curProgress, minProgress);
290 | resetProgress();
291 | }
292 |
293 | /**
294 | * Set the current progress.
295 | *
296 | * @param curProgress the current progress
297 | */
298 | public void setProgress(double curProgress) {
299 | this.curProgress = Math.max(minProgress, Math.min(maxProgress, curProgress));
300 |
301 | // Calculate percent complete
302 | int percent = (int) (100 * getPercent());
303 | DOM.setStyleAttribute(barElement, "width", percent + "%");
304 | DOM.setElementProperty(textElement, "innerHTML", generateText(curProgress));
305 | updateTextStyle(percent);
306 |
307 | // Realign the text
308 | redraw();
309 | }
310 |
311 | public void setTextFirstHalfStyleName(String textFirstHalfClassName) {
312 | this.textFirstHalfClassName = textFirstHalfClassName;
313 | onTextStyleChange();
314 | }
315 |
316 | /**
317 | * Set the text formatter.
318 | *
319 | * @param textFormatter the text formatter
320 | */
321 | public void setTextFormatter(TextFormatter textFormatter) {
322 | this.textFormatter = textFormatter;
323 | }
324 |
325 | public void setTextSecondHalfStyleName(String textSecondHalfClassName) {
326 | this.textSecondHalfClassName = textSecondHalfClassName;
327 | onTextStyleChange();
328 | }
329 |
330 | public void setTextStyleName(String textClassName) {
331 | this.textClassName = textClassName;
332 | onTextStyleChange();
333 | }
334 |
335 | /**
336 | * Sets whether the text is visible over the bar.
337 | *
338 | * @param textVisible True to show text, false to hide it
339 | */
340 | public void setTextVisible(boolean textVisible) {
341 | this.textVisible = textVisible;
342 | if (this.textVisible) {
343 | DOM.setStyleAttribute(textElement, "display", "");
344 | redraw();
345 | } else {
346 | DOM.setStyleAttribute(textElement, "display", "none");
347 | }
348 | }
349 |
350 | /**
351 | * Generate the text to display within the progress bar. Override this
352 | * function to change the default progress percent to a more informative
353 | * message, such as the number of kilobytes downloaded.
354 | *
355 | * @param curProgress the current progress
356 | * @return the text to display in the progress bar
357 | */
358 | protected String generateText(double curProgress) {
359 | if (textFormatter != null) {
360 | return textFormatter.getText(this, curProgress);
361 | } else {
362 | return (int) (100 * getPercent()) + "%";
363 | }
364 | }
365 |
366 | /**
367 | * Get the bar element.
368 | *
369 | * @return the bar element
370 | */
371 | protected Element getBarElement() {
372 | return barElement;
373 | }
374 |
375 | /**
376 | * Get the text element.
377 | *
378 | * @return the text element
379 | */
380 | protected Element getTextElement() {
381 | return textElement;
382 | }
383 |
384 | /**
385 | * This method is called immediately after a widget becomes attached to the
386 | * browser's document.
387 | */
388 | @Override
389 | protected void onLoad() {
390 | // Reset the position attribute of the parent element
391 | DOM.setStyleAttribute(getElement(), "position", "relative");
392 | ResizableWidgetCollection.get().add(this);
393 | redraw();
394 | }
395 |
396 | @Override
397 | protected void onUnload() {
398 | ResizableWidgetCollection.get().remove(this);
399 | }
400 |
401 | /**
402 | * Reset the progress text based on the current min and max progress range.
403 | */
404 | protected void resetProgress() {
405 | setProgress(getProgress());
406 | }
407 |
408 | private void onTextStyleChange() {
409 | int percent = (int) (100 * getPercent());
410 | updateTextStyle(percent);
411 | }
412 |
413 | private void updateTextStyle(int percent) {
414 | // Set the style depending on the size of the bar
415 | if (percent < 50) {
416 | DOM.setElementProperty(textElement, "className",
417 | textClassName + " " + textFirstHalfClassName);
418 | } else {
419 | DOM.setElementProperty(textElement, "className",
420 | textClassName + " " + textSecondHalfClassName);
421 | }
422 | }
423 | }
424 |
--------------------------------------------------------------------------------