From 32728cd641d4ec394264f47b781e8526014a1eea Mon Sep 17 00:00:00 2001 From: Massimiliano Assante Date: Mon, 26 Sep 2022 15:32:59 +0200 Subject: [PATCH] cccc --- .classpath | 44 +++ .gitignore | 1 + .project | 59 ++++ .settings/.jsdtscope | 15 + .../com.google.appengine.eclipse.core.prefs | 3 + .settings/com.google.gdt.eclipse.core.prefs | 5 + .settings/com.google.gwt.eclipse.core.prefs | 5 + .settings/org.eclipse.core.resources.prefs | 6 + .settings/org.eclipse.jdt.core.prefs | 11 + .settings/org.eclipse.m2e.core.prefs | 4 + .settings/org.eclipse.wst.common.component | 23 ++ ....eclipse.wst.common.project.facet.core.xml | 7 + ...rg.eclipse.wst.jsdt.ui.superType.container | 1 + .settings/org.eclipse.wst.validation.prefs | 2 + .settings/org.maven.ide.eclipse.prefs | 9 + CHANGELOG.md | 27 ++ FUNDING.md | 26 ++ LICENSE.md | 311 ++++++++++++++++++ pom.xml | 146 ++++++++ .../widgets/fileupload/FileUpload.gwt.xml | 17 + .../widgets/fileupload/client/FileUpload.java | 96 ++++++ .../client/UploadProgressService.java | 16 + .../client/UploadProgressServiceAsync.java | 12 + .../fileupload/client/bundle/FileUpload.css | 95 ++++++ .../client/bundle/PanelFileUpload.css | 95 ++++++ .../bundle/ProgressBarCssAndImages.java | 36 ++ .../fileupload/client/bundle/error.png | Bin 0 -> 1053 bytes .../widgets/fileupload/client/bundle/ok.png | Bin 0 -> 3315 bytes .../fileupload/client/bundle/progress.png | Bin 0 -> 130 bytes .../fileupload/client/bundle/spinning.gif | Bin 0 -> 5667 bytes .../client/controller/ProgressController.java | 94 ++++++ .../client/events/FileTooLargeEvent.java | 22 ++ .../events/FileTooLargeEventHandler.java | 12 + .../events/FileUploadCompleteEvent.java | 32 ++ .../FileUploadCompleteEventHandler.java | 7 + .../events/FileUploadSelectedEvent.java | 30 ++ .../FileUploadSelectedEventHandler.java | 7 + .../client/state/AbstractState.java | 37 +++ .../fileupload/client/state/State.java | 17 + .../client/state/UploadProgressState.java | 24 ++ .../fileupload/client/view/FileSubmit.java | 176 ++++++++++ .../fileupload/client/view/ProgressBar.java | 37 +++ .../fileupload/client/view/ProgressBar.ui.xml | 13 + .../client/view/UploadProgress.java | 65 ++++ .../client/view/UploadProgressDialog.java | 129 ++++++++ .../client/view/UploadProgressPanel.java | 71 ++++ .../client/view/UploadProgressView.java | 43 +++ .../client/view/UploadProgressView.ui.xml | 10 + .../fileupload/server/UploadProgress.java | 42 +++ .../server/UploadProgressInputStream.java | 69 ++++ .../server/UploadProgressListener.java | 42 +++ .../server/UploadProgressServlet.java | 51 +++ .../fileupload/server/UploadServlet.java | 98 ++++++ .../fileupload/shared/FieldVerifier.java | 42 +++ .../fileupload/shared/dto/FileDto.java | 60 ++++ .../fileupload/shared/event/Event.java | 4 + .../event/UploadProgressChangeEvent.java | 51 +++ src/main/resources/clientlog4j.properties | 17 + src/main/webapp/FileUpload.html | 41 +++ src/main/webapp/WEB-INF/.gitignore | 1 + src/main/webapp/WEB-INF/web.xml | 35 ++ src/main/webapp/images/progress.png | Bin 0 -> 130 bytes .../fileupload/FileUploadJUnit.gwt.xml | 9 + 63 files changed, 2460 insertions(+) create mode 100644 .classpath create mode 100644 .gitignore create mode 100644 .project create mode 100644 .settings/.jsdtscope create mode 100644 .settings/com.google.appengine.eclipse.core.prefs create mode 100644 .settings/com.google.gdt.eclipse.core.prefs create mode 100644 .settings/com.google.gwt.eclipse.core.prefs create mode 100644 .settings/org.eclipse.core.resources.prefs create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 .settings/org.eclipse.wst.common.component create mode 100644 .settings/org.eclipse.wst.common.project.facet.core.xml create mode 100644 .settings/org.eclipse.wst.jsdt.ui.superType.container create mode 100644 .settings/org.eclipse.wst.validation.prefs create mode 100644 .settings/org.maven.ide.eclipse.prefs create mode 100644 CHANGELOG.md create mode 100644 FUNDING.md create mode 100644 LICENSE.md create mode 100644 pom.xml create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/FileUpload.gwt.xml create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/FileUpload.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/UploadProgressService.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/UploadProgressServiceAsync.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/FileUpload.css create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/PanelFileUpload.css create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/ProgressBarCssAndImages.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/error.png create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/ok.png create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/progress.png create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/spinning.gif create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/controller/ProgressController.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileTooLargeEvent.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileTooLargeEventHandler.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadCompleteEvent.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadCompleteEventHandler.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadSelectedEvent.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadSelectedEventHandler.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/state/AbstractState.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/state/State.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/state/UploadProgressState.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/view/FileSubmit.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/view/ProgressBar.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/view/ProgressBar.ui.xml create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgress.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressDialog.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressPanel.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressView.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressView.ui.xml create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgress.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgressInputStream.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgressListener.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgressServlet.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadServlet.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/shared/FieldVerifier.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/shared/dto/FileDto.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/shared/event/Event.java create mode 100644 src/main/java/org/gcube/portlets/widgets/fileupload/shared/event/UploadProgressChangeEvent.java create mode 100644 src/main/resources/clientlog4j.properties create mode 100644 src/main/webapp/FileUpload.html create mode 100644 src/main/webapp/WEB-INF/.gitignore create mode 100644 src/main/webapp/WEB-INF/web.xml create mode 100644 src/main/webapp/images/progress.png create mode 100644 src/test/resources/org/gcube/portlets/widgets/fileupload/FileUploadJUnit.gwt.xml diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..dea48a9 --- /dev/null +++ b/.classpath @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/.project b/.project new file mode 100644 index 0000000..2dd0993 --- /dev/null +++ b/.project @@ -0,0 +1,59 @@ + + + fileupload-progress-bar + fileupload-progress-bar project + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.maven.ide.eclipse.maven2Builder + + + + + com.google.gdt.eclipse.core.webAppProjectValidator + + + + + com.google.gwt.eclipse.core.gwtProjectValidator + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.maven.ide.eclipse.maven2Nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.jsdt.core.jsNature + com.google.gwt.eclipse.core.gwtNature + + diff --git a/.settings/.jsdtscope b/.settings/.jsdtscope new file mode 100644 index 0000000..ba3c245 --- /dev/null +++ b/.settings/.jsdtscope @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/.settings/com.google.appengine.eclipse.core.prefs b/.settings/com.google.appengine.eclipse.core.prefs new file mode 100644 index 0000000..a60576c --- /dev/null +++ b/.settings/com.google.appengine.eclipse.core.prefs @@ -0,0 +1,3 @@ +#Thu Jun 16 10:18:26 CEST 2011 +eclipse.preferences.version=1 +filesCopiedToWebInfLib= diff --git a/.settings/com.google.gdt.eclipse.core.prefs b/.settings/com.google.gdt.eclipse.core.prefs new file mode 100644 index 0000000..9ee1742 --- /dev/null +++ b/.settings/com.google.gdt.eclipse.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +jarsExcludedFromWebInfLib= +lastWarOutDir=/home/costantino/workspace/fileupload-progress-bar/target/fileupload-progress-bar-1.3.0-SNAPSHOT +warSrcDir=src/main/webapp +warSrcDirIsOutput=false diff --git a/.settings/com.google.gwt.eclipse.core.prefs b/.settings/com.google.gwt.eclipse.core.prefs new file mode 100644 index 0000000..c803c44 --- /dev/null +++ b/.settings/com.google.gwt.eclipse.core.prefs @@ -0,0 +1,5 @@ +#Thu Jun 16 11:14:17 CEST 2011 +eclipse.preferences.version=1 +entryPointModules= +filesCopiedToWebInfLib=gwt-servlet.jar +gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgc3JjL21haW4vd2ViYXBwXV0+PC9leHRyYS1hcmdzPjx2bS1hcmdzPjwhW0NEQVRBWy1YbXg1MTJtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLmNvbXBhbnkuU29tZU1vZHVsZTwvZW50cnktcG9pbnQtbW9kdWxlPjwvZ3d0LWNvbXBpbGUtc2V0dGluZ3M+ diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..29abf99 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..cac0df4 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..b110c95 --- /dev/null +++ b/.settings/org.eclipse.wst.common.component @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..4045d87 --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.container b/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 0000000..3bd5d0a --- /dev/null +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/.settings/org.eclipse.wst.validation.prefs b/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 0000000..04cad8c --- /dev/null +++ b/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,2 @@ +disabled=06target +eclipse.preferences.version=1 diff --git a/.settings/org.maven.ide.eclipse.prefs b/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 0000000..dae95d4 --- /dev/null +++ b/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Thu Sep 02 10:42:12 CEST 2010 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\\:testResources +skipCompilerPlugin=true +version=1 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d471ab2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,27 @@ + +# Changelog for File Upload Progress bar widget + +All notable changes to this project will be documented in this file. +This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v2.0.0-SNAPSHOT] - 2022-06-15 + +- Ported to git +- Ported to GWT 2.9 + +## [v1.4.1] - 2016-01-27 + +- added support to drag and drop mechanism in share-updates + +## [v1.2.0] - 014-07-17" + +- Fixed upload File fails if file name contains chars like (à ù ò) + +## [v1.1.0] - 2014-04-22 + +- Fixed gets stuck after 4/5 uploads in a row bug +- Fixed gets stuck if file size greater than 2GB + +## [v1.0.0] - 2014-01-30 + +- First release diff --git a/FUNDING.md b/FUNDING.md new file mode 100644 index 0000000..6fa9eac --- /dev/null +++ b/FUNDING.md @@ -0,0 +1,26 @@ +# Acknowledgments + +The projects leading to this software have received funding from a series of European Union programmes including: + +- the Sixth Framework Programme for Research and Technological Development + - [DILIGENT](https://cordis.europa.eu/project/id/004260) (grant no. 004260). +- the Seventh Framework Programme for research, technological development and demonstration + - [D4Science](https://cordis.europa.eu/project/id/212488) (grant no. 212488); + - [D4Science-II](https://cordis.europa.eu/project/id/239019) (grant no.239019); + - [ENVRI](https://cordis.europa.eu/project/id/283465) (grant no. 283465); + - [iMarine](https://cordis.europa.eu/project/id/283644) (grant no. 283644); + - [EUBrazilOpenBio](https://cordis.europa.eu/project/id/288754) (grant no. 288754). +- the H2020 research and innovation programme + - [SoBigData](https://cordis.europa.eu/project/id/654024) (grant no. 654024); + - [PARTHENOS](https://cordis.europa.eu/project/id/654119) (grant no. 654119); + - [EGI-Engage](https://cordis.europa.eu/project/id/654142) (grant no. 654142); + - [ENVRI PLUS](https://cordis.europa.eu/project/id/654182) (grant no. 654182); + - [BlueBRIDGE](https://cordis.europa.eu/project/id/675680) (grant no. 675680); + - [PerformFISH](https://cordis.europa.eu/project/id/727610) (grant no. 727610); + - [AGINFRA PLUS](https://cordis.europa.eu/project/id/731001) (grant no. 731001); + - [DESIRA](https://cordis.europa.eu/project/id/818194) (grant no. 818194); + - [ARIADNEplus](https://cordis.europa.eu/project/id/823914) (grant no. 823914); + - [RISIS 2](https://cordis.europa.eu/project/id/824091) (grant no. 824091); + - [EOSC-Pillar](https://cordis.europa.eu/project/id/857650) (grant no. 857650); + - [Blue Cloud](https://cordis.europa.eu/project/id/862409) (grant no. 862409); + - [SoBigData-PlusPlus](https://cordis.europa.eu/project/id/871042) (grant no. 871042); \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..c25566d --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,311 @@ +#European Union Public Licence V.1.1 + +##*EUPL © the European Community 2007* + + +This **European Union Public Licence** (the **“EUPL”**) applies to the Work or Software +(as defined below) which is provided under the terms of this Licence. Any use of +the Work, other than as authorised under this Licence is prohibited (to the +extent such use is covered by a right of the copyright holder of the Work). + +The Original Work is provided under the terms of this Licence when the Licensor +(as defined below) has placed the following notice immediately following the +copyright notice for the Original Work: + +**Licensed under the EUPL V.1.1** + +or has expressed by any other mean his willingness to license under the EUPL. + + + +##1. Definitions + +In this Licence, the following terms have the following meaning: + +- The Licence: this Licence. + +- The Original Work or the Software: the software distributed and/or + communicated by the Licensor under this Licence, available as Source Code and + also as Executable Code as the case may be. + +- Derivative Works: the works or software that could be created by the Licensee, + based upon the Original Work or modifications thereof. This Licence does not + define the extent of modification or dependence on the Original Work required + in order to classify a work as a Derivative Work; this extent is determined by + copyright law applicable in the country mentioned in Article 15. + +- The Work: the Original Work and/or its Derivative Works. + +- The Source Code: the human-readable form of the Work which is the most + convenient for people to study and modify. + +- The Executable Code: any code which has generally been compiled and which is + meant to be interpreted by a computer as a program. + +- The Licensor: the natural or legal person that distributes and/or communicates + the Work under the Licence. + +- Contributor(s): any natural or legal person who modifies the Work under the + Licence, or otherwise contributes to the creation of a Derivative Work. + +- The Licensee or “You”: any natural or legal person who makes any usage of the + Software under the terms of the Licence. + +- Distribution and/or Communication: any act of selling, giving, lending, + renting, distributing, communicating, transmitting, or otherwise making + available, on-line or off-line, copies of the Work or providing access to its + essential functionalities at the disposal of any other natural or legal + person. + + + +##2. Scope of the rights granted by the Licence + +The Licensor hereby grants You a world-wide, royalty-free, non-exclusive, +sub-licensable licence to do the following, for the duration of copyright vested +in the Original Work: + +- use the Work in any circumstance and for all usage, reproduce the Work, modify +- the Original Work, and make Derivative Works based upon the Work, communicate +- to the public, including the right to make available or display the Work or +- copies thereof to the public and perform publicly, as the case may be, the +- Work, distribute the Work or copies thereof, lend and rent the Work or copies +- thereof, sub-license rights in the Work or copies thereof. + +Those rights can be exercised on any media, supports and formats, whether now +known or later invented, as far as the applicable law permits so. + +In the countries where moral rights apply, the Licensor waives his right to +exercise his moral right to the extent allowed by law in order to make effective +the licence of the economic rights here above listed. + +The Licensor grants to the Licensee royalty-free, non exclusive usage rights to +any patents held by the Licensor, to the extent necessary to make use of the +rights granted on the Work under this Licence. + + + +##3. Communication of the Source Code + +The Licensor may provide the Work either in its Source Code form, or as +Executable Code. If the Work is provided as Executable Code, the Licensor +provides in addition a machine-readable copy of the Source Code of the Work +along with each copy of the Work that the Licensor distributes or indicates, in +a notice following the copyright notice attached to the Work, a repository where +the Source Code is easily and freely accessible for as long as the Licensor +continues to distribute and/or communicate the Work. + + + +##4. Limitations on copyright + +Nothing in this Licence is intended to deprive the Licensee of the benefits from +any exception or limitation to the exclusive rights of the rights owners in the +Original Work or Software, of the exhaustion of those rights or of other +applicable limitations thereto. + + + +##5. Obligations of the Licensee + +The grant of the rights mentioned above is subject to some restrictions and +obligations imposed on the Licensee. Those obligations are the following: + +Attribution right: the Licensee shall keep intact all copyright, patent or +trademarks notices and all notices that refer to the Licence and to the +disclaimer of warranties. The Licensee must include a copy of such notices and a +copy of the Licence with every copy of the Work he/she distributes and/or +communicates. The Licensee must cause any Derivative Work to carry prominent +notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes and/or communicates copies of the +Original Works or Derivative Works based upon the Original Work, this +Distribution and/or Communication will be done under the terms of this Licence +or of a later version of this Licence unless the Original Work is expressly +distributed only under this version of the Licence. The Licensee (becoming +Licensor) cannot offer or impose any additional terms or conditions on the Work +or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes and/or Communicates Derivative +Works or copies thereof based upon both the Original Work and another work +licensed under a Compatible Licence, this Distribution and/or Communication can +be done under the terms of this Compatible Licence. For the sake of this clause, +“Compatible Licence” refers to the licences listed in the appendix attached to +this Licence. Should the Licensee’s obligations under the Compatible Licence +conflict with his/her obligations under this Licence, the obligations of the +Compatible Licence shall prevail. + +Provision of Source Code: When distributing and/or communicating copies of the +Work, the Licensee will provide a machine-readable copy of the Source Code or +indicate a repository where this Source will be easily and freely available for +as long as the Licensee continues to distribute and/or communicate the Work. + +Legal Protection: This Licence does not grant permission to use the trade names, +trademarks, service marks, or names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + + + +##6. Chain of Authorship + +The original Licensor warrants that the copyright in the Original Work granted +hereunder is owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each Contributor warrants that the copyright in the modifications he/she brings +to the Work are owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each time You accept the Licence, the original Licensor and subsequent +Contributors grant You a licence to their contributions to the Work, under the +terms of this Licence. + + + +##7. Disclaimer of Warranty + +The Work is a work in progress, which is continuously improved by numerous +contributors. It is not a finished work and may therefore contain defects or +“bugs” inherent to this type of software development. + +For the above reason, the Work is provided under the Licence on an “as is” basis +and without warranties of any kind concerning the Work, including without +limitation merchantability, fitness for a particular purpose, absence of defects +or errors, accuracy, non-infringement of intellectual property rights other than +copyright as stated in Article 6 of this Licence. + +This disclaimer of warranty is an essential part of the Licence and a condition +for the grant of any rights to the Work. + + + +##8. Disclaimer of Liability + +Except in the cases of wilful misconduct or damages directly caused to natural +persons, the Licensor will in no event be liable for any direct or indirect, +material or moral, damages of any kind, arising out of the Licence or of the use +of the Work, including without limitation, damages for loss of goodwill, work +stoppage, computer failure or malfunction, loss of data or any commercial +damage, even if the Licensor has been advised of the possibility of such +damage. However, the Licensor will be liable under statutory product liability +laws as far such laws apply to the Work. + + + +##9. Additional agreements + +While distributing the Original Work or Derivative Works, You may choose to +conclude an additional agreement to offer, and charge a fee for, acceptance of +support, warranty, indemnity, or other liability obligations and/or services +consistent with this Licence. However, in accepting such obligations, You may +act only on your own behalf and on your sole responsibility, not on behalf of +the original Licensor or any other Contributor, and only if You agree to +indemnify, defend, and hold each Contributor harmless for any liability incurred +by, or claims asserted against such Contributor by the fact You have accepted +any such warranty or additional liability. + + + +##10. Acceptance of the Licence + +The provisions of this Licence can be accepted by clicking on an icon “I agree” +placed under the bottom of a window displaying the text of this Licence or by +affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable +acceptance of this Licence and all of its terms and conditions. + +Similarly, you irrevocably accept this Licence and all of its terms and +conditions by exercising any rights granted to You by Article 2 of this Licence, +such as the use of the Work, the creation by You of a Derivative Work or the +Distribution and/or Communication by You of the Work or copies thereof. + + + +##11. Information to the public + +In case of any Distribution and/or Communication of the Work by means of +electronic communication by You (for example, by offering to download the Work +from a remote location) the distribution channel or media (for example, a +website) must at least provide to the public the information requested by the +applicable law regarding the Licensor, the Licence and the way it may be +accessible, concluded, stored and reproduced by the Licensee. + + + +##12. Termination of the Licence + +The Licence and the rights granted hereunder will terminate automatically upon +any breach by the Licensee of the terms of the Licence. + +Such a termination will not terminate the licences of any person who has +received the Work from the Licensee under the Licence, provided such persons +remain in full compliance with the Licence. + + + +##13. Miscellaneous + +Without prejudice of Article 9 above, the Licence represents the complete +agreement between the Parties as to the Work licensed hereunder. + +If any provision of the Licence is invalid or unenforceable under applicable +law, this will not affect the validity or enforceability of the Licence as a +whole. Such provision will be construed and/or reformed so as necessary to make +it valid and enforceable. + +The European Commission may publish other linguistic versions and/or new +versions of this Licence, so far this is required and reasonable, without +reducing the scope of the rights granted by the Licence. New versions of the +Licence will be published with a unique version number. + +All linguistic versions of this Licence, approved by the European Commission, +have identical value. Parties can take advantage of the linguistic version of +their choice. + + + +##14. Jurisdiction + +Any litigation resulting from the interpretation of this License, arising +between the European Commission, as a Licensor, and any Licensee, will be +subject to the jurisdiction of the Court of Justice of the European Communities, +as laid down in article 238 of the Treaty establishing the European Community. + +Any litigation arising between Parties, other than the European Commission, and +resulting from the interpretation of this License, will be subject to the +exclusive jurisdiction of the competent court where the Licensor resides or +conducts its primary business. + + + +##15. Applicable Law + +This Licence shall be governed by the law of the European Union country where +the Licensor resides or has his registered office. + +This licence shall be governed by the Belgian law if: + +- a litigation arises between the European Commission, as a Licensor, and any +- Licensee; the Licensor, other than the European Commission, has no residence +- or registered office inside a European Union country. + + +--- + + +##Appendix + + +**“Compatible Licences”** according to article 5 EUPL are: + + +- GNU General Public License (GNU GPL) v. 2 + +- Open Software License (OSL) v. 2.1, v. 3.0 + +- Common Public License v. 1.0 + +- Eclipse Public License v. 1.0 + +- Cecill v. 2.0 \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..efbd119 --- /dev/null +++ b/pom.xml @@ -0,0 +1,146 @@ + + + + 4.0.0 + + maven-parent + org.gcube.tools + 1.1.0 + + + + org.gcube.portlets.widgets + fileupload-progress-bar + jar + 2.0.0-SNAPSHOT + + gCube File Upload Progress Bar Widget + + gCube File Upload Progress Bar Widget + + + scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git + scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git + https://code-repo.d4science.org/gCubeSystem/${project.artifactId} + + + + 2.9.0 + ${project.build.directory}/${project.build.finalName} + UTF-8 + UTF-8 + + + + + org.gcube.distribution + maven-portal-bom + 3.6.4 + pom + import + + + + + + com.google.gwt + gwt-user + ${gwtVersion} + provided + + + com.google.gwt + gwt-servlet + ${gwtVersion} + provided + + + com.google.gwt + gwt-dev + ${gwtVersion} + provided + + + org.gcube.portlets.user + gcube-widgets + provided + + + commons-fileupload + commons-fileupload + compile + + + commons-io + commons-io + compile + + + + com.liferay.portal + portal-service + provided + + + javax.portlet + portlet-api + provided + + + org.slf4j + slf4j-log4j12 + + + org.slf4j + slf4j-api + + + + + ${webappDirectory}/WEB-INF/classes + + + src/main/java + + **/*.* + + + + src/main/resources + + **/*.* + + + + + + + org.codehaus.mojo + gwt-maven-plugin + ${gwtVersion} + + + + compile + + + + + + + FileUpload.html + ${webappDirectory} + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/FileUpload.gwt.xml b/src/main/java/org/gcube/portlets/widgets/fileupload/FileUpload.gwt.xml new file mode 100644 index 0000000..b23d86f --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/FileUpload.gwt.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/FileUpload.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/FileUpload.java new file mode 100644 index 0000000..aa97017 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/FileUpload.java @@ -0,0 +1,96 @@ +package org.gcube.portlets.widgets.fileupload.client; + +import org.gcube.portlets.widgets.fileupload.client.events.FileUploadCompleteEvent; +import org.gcube.portlets.widgets.fileupload.client.events.FileUploadCompleteEventHandler; +import org.gcube.portlets.widgets.fileupload.client.events.FileUploadSelectedEvent; +import org.gcube.portlets.widgets.fileupload.client.events.FileUploadSelectedEventHandler; +import org.gcube.portlets.widgets.fileupload.client.view.UploadProgressDialog; + +import com.google.gwt.core.client.EntryPoint; +import com.google.gwt.core.shared.GWT; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.user.client.Timer; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.RootPanel; +/** + * + * @author Massimiliano Assante, ISTI-CNR + * + * Use this widget to display a dialog containing the possibility to upload a file on server with an actual progress of the current uploaded file in percentage; + * uncomment //showSample() in the onModuleLoad() to see it working + * + * To get to know which file was uploaded listen for the {@link FileUploadCompleteEvent} on the {@link HandlerManager} instance you pass to this widget. + * + */ +public class FileUpload implements EntryPoint { + + @Override + public void onModuleLoad() { +// Button showDlg = new Button("Open Dialog"); +// showDlg.addClickHandler(new ClickHandler() { +// @Override +// public void onClick(ClickEvent event) { +// showSample(); +// } +// }); +// RootPanel.get().add(showDlg); + } + + private void showSample() { + HandlerManager eventBus = new HandlerManager(null); + + final UploadProgressDialog dlg = new UploadProgressDialog("Share File", eventBus, true); + dlg.center(); + dlg.show(); + + eventBus.addHandler(FileUploadSelectedEvent.TYPE, new FileUploadSelectedEventHandler() { + + @Override + public void onFileSelected(FileUploadSelectedEvent event) { + String fileName = event.getSelectedFileName(); + GWT.log("selected file name: " + fileName); + //pretend you do sth with the uploaded file, wait 3 seconds + Timer t = new Timer() { + + @Override + public void run() { + try { + dlg.submitForm(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + t.schedule(1000); + } + }); + + + /** + * get the uploaded file result + */ + eventBus.addHandler(FileUploadCompleteEvent.TYPE, new FileUploadCompleteEventHandler() { + + @Override + public void onUploadComplete(FileUploadCompleteEvent event) { + + //the filename and its path on server are returned to the client + String fileName = event.getUploadedFileInfo().getFilename(); + String absolutePathOnServer = event.getUploadedFileInfo().getAbsolutePath(); + GWT.log(fileName + " uploaded on Server here: " + absolutePathOnServer); + //pretend you do sth with the uploaded file, wait 3 seconds + Timer t = new Timer() { + + @Override + public void run() { + dlg.showRegisteringResult(true); //or false if an error occurred + } + }; + t.schedule(3000); + } + }); + + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/UploadProgressService.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/UploadProgressService.java new file mode 100644 index 0000000..a805259 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/UploadProgressService.java @@ -0,0 +1,16 @@ +package org.gcube.portlets.widgets.fileupload.client; + +import java.util.List; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +import org.gcube.portlets.widgets.fileupload.shared.event.*; +import org.gcube.portlets.widgets.fileupload.shared.dto.*; + +@RemoteServiceRelativePath("uploadprogress") +public interface UploadProgressService extends RemoteService { + void initialise(); + + List getEvents(); +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/UploadProgressServiceAsync.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/UploadProgressServiceAsync.java new file mode 100644 index 0000000..4e0a6b2 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/UploadProgressServiceAsync.java @@ -0,0 +1,12 @@ +package org.gcube.portlets.widgets.fileupload.client; + +import java.util.List; + +import org.gcube.portlets.widgets.fileupload.shared.event.Event; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +public interface UploadProgressServiceAsync { + void initialise(AsyncCallback asyncCallback); + void getEvents(AsyncCallback> asyncCallback); +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/FileUpload.css b/src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/FileUpload.css new file mode 100644 index 0000000..18069de --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/FileUpload.css @@ -0,0 +1,95 @@ +@external progressContainer, progressBarContainer, FileSubmit, bar-container, progress, blue, myBackground; + +.progressContainer { + text-align: center; + width: 100%; + margin: 0px; +} + +.progressBarContainer { + text-align: center; + width: 100%; + margin: 10px 0 0 -3px; + +} + +.FileSubmit input { + font-family: 'Lucida Grande', Verdana, 'Bitstream Vera Sans', Arial, + sans-serif; + font-size: 13px; + color: #464646; + border: 1px solid #BBB; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + background-color: #F2F2F2; + cursor: pointer; + cursor: hand; + margin-top: 10px; + padding: 10px 15px; + width: 350px; +} + +/* Progress Bar Styles */ + +.bar-container { + font: 13px/20px 'Lucida Grande', Tahoma, Verdana, sans-serif; + color: #404040; + margin: 0px auto; + width: 382px; +} + +.bar-container > div { + margin: 2px; +} + +.progress { + height: 25px; + border-radius: 6px; +} + +.progress > span { + position: relative; + float: left; + margin: 0 -1px; + min-width: 30px; + height: 18px; + line-height: 16px; + text-align: right; + background-color: #DDD; + border: 1px solid; + border-color: #FFF; + border-radius: 6px; +} + +.progress>span>span { + padding: 0 8px; + font-size: 11px; + font-weight: bold; + color: #404040; + color: rgba(0, 0, 0, 0.7); + text-shadow: 0 1px rgba(255, 255, 255, 0.4); +} + +@sprite .myBackground>span:before { + gwt-image: "progressTexture"; + other: repeat-x; + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: 1; + height: 18px; + border-radius: 6px; +} + +.progress .blue { + background: #5aaadb; + border-color: #7bbbe2; + background-image: -webkit-linear-gradient(top, #aed5ed, #7bbbe2 70%, #5aaadb); + background-image: -moz-linear-gradient(top, #aed5ed, #7bbbe2 70%, #5aaadb); + background-image: -o-linear-gradient(top, #aed5ed, #7bbbe2 70%, #5aaadb); + background-image: linear-gradient(to bottom, #aed5ed, #7bbbe2 70%, #5aaadb); +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/PanelFileUpload.css b/src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/PanelFileUpload.css new file mode 100644 index 0000000..396e498 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/PanelFileUpload.css @@ -0,0 +1,95 @@ +@external progressContainer, progressBarContainer, FileSubmit, bar-container, progress, blue, myBackground; + +.progressContainer { + text-align: center; + width: 100%; + margin: 0px; +} + +.progressBarContainer { + text-align: center; + width: 100%; + margin: 10px 0 0 -3px; + +} + +.FileSubmit input { + font-family: 'Lucida Grande', Verdana, 'Bitstream Vera Sans', Arial, + sans-serif; + font-size: 13px; + color: #464646; + border: 1px solid #BBB; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + background-color: #F2F2F2; + cursor: pointer; + cursor: hand; + margin-top: 10px; + padding: 10px 15px; + width: 565px; +} + +/* Progress Bar Styles */ + +.bar-container { + font: 13px/20px 'Lucida Grande', Tahoma, Verdana, sans-serif; + color: #404040; + margin: 1px; + width: 100%; +} + +.bar-container > div { + margin: 2px; +} + +.progress { + height: 25px; + border-radius: 6px; +} + +.progress > span { + position: relative; + float: left; + margin: 0 -1px; + min-width: 30px; + height: 18px; + line-height: 16px; + text-align: right; + background-color: #DDD; + border: 1px solid; + border-color: #FFF; + border-radius: 6px; +} + +.progress>span>span { + padding: 0 8px; + font-size: 11px; + font-weight: bold; + color: #404040; + color: rgba(0, 0, 0, 0.7); + text-shadow: 0 1px rgba(255, 255, 255, 0.4); +} + +@sprite .myBackground>span:before { + gwt-image: "progressTexture"; + other: repeat-x; + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: 1; + height: 18px; + border-radius: 6px; +} + +.progress .blue { + background: #5aaadb; + border-color: #7bbbe2; + background-image: -webkit-linear-gradient(top, #aed5ed, #7bbbe2 70%, #5aaadb); + background-image: -moz-linear-gradient(top, #aed5ed, #7bbbe2 70%, #5aaadb); + background-image: -o-linear-gradient(top, #aed5ed, #7bbbe2 70%, #5aaadb); + background-image: linear-gradient(to bottom, #aed5ed, #7bbbe2 70%, #5aaadb); +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/ProgressBarCssAndImages.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/ProgressBarCssAndImages.java new file mode 100644 index 0000000..19b0771 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/ProgressBarCssAndImages.java @@ -0,0 +1,36 @@ +package org.gcube.portlets.widgets.fileupload.client.bundle; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.resources.client.ClientBundle; +import com.google.gwt.resources.client.CssResource; +import com.google.gwt.resources.client.ImageResource; +import com.google.gwt.resources.client.ImageResource.ImageOptions; +import com.google.gwt.resources.client.ImageResource.RepeatStyle; + +public interface ProgressBarCssAndImages extends ClientBundle { + + public static final ProgressBarCssAndImages INSTANCE = GWT.create(ProgressBarCssAndImages.class); + + @Source("FileUpload.css") + public CssResource css(); + + @Source("PanelFileUpload.css") + public CssResource panelCss(); + + @Source("spinning.gif") + ImageResource spinner(); + + @Source("error.png") + ImageResource error(); + + @Source("ok.png") + ImageResource ok(); + + @ImageOptions(repeatStyle = RepeatStyle.Horizontal) + @Source("progress.png") + ImageResource progressTexture(); + + interface MyCssResource extends CssResource { + String myBackground(); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/error.png b/src/main/java/org/gcube/portlets/widgets/fileupload/client/bundle/error.png new file mode 100644 index 0000000000000000000000000000000000000000..0168ec103cbb4104a655c79f3c8007b0662e5e9f GIT binary patch literal 1053 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 { + + @Override + public void onFailure(final Throwable t) { + GWT.log("error get events", t); + } + + @Override + public void onSuccess(final List events) { + + for (Event event : events) { + handleEvent(event); + } + SERVICE.getEvents(this); + } + + private void handleEvent(final Event event) { + + if (event instanceof UploadProgressChangeEvent) { + UploadProgressChangeEvent uploadPercentChangeEvent = (UploadProgressChangeEvent) event; + String fileName = uploadPercentChangeEvent.getFilename(); + Integer percentage = uploadPercentChangeEvent.getPercentage(); + + UploadProgressState.INSTANCE.setUploadProgress(fileName, percentage); + if (percentage == 100) { + uploadCompleted(uploadPercentChangeEvent); + } + } + } + }); + } + + private void initialize(HandlerManager eventBus) { + + SERVICE.initialise(new AsyncCallback() { + + @Override + public void onFailure(final Throwable t) { + GWT.log("error initialise", t); + } + + @Override + public void onSuccess(final Void result) { + getEvents(); + } + }); + } + + /** + * here we fire the finished uploadedFile event + * @param uploadedFile + */ + private void uploadCompleted(UploadProgressChangeEvent uploadedFile) { + GWT.log("Finito"); + eventBus.fireEvent(new FileUploadCompleteEvent(uploadedFile)); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileTooLargeEvent.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileTooLargeEvent.java new file mode 100644 index 0000000..f0bbeb6 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileTooLargeEvent.java @@ -0,0 +1,22 @@ +package org.gcube.portlets.widgets.fileupload.client.events; + +import com.google.gwt.event.shared.GwtEvent; + +/** + * Event thrown when the user tries to upload a too large file. + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + */ +public class FileTooLargeEvent extends GwtEvent { + public static Type TYPE = new Type(); + + @Override + public Type getAssociatedType() { + return TYPE; + } + + @Override + protected void dispatch(FileTooLargeEventHandler handler) { + handler.onFileTooLargeEvent(this); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileTooLargeEventHandler.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileTooLargeEventHandler.java new file mode 100644 index 0000000..1e4a843 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileTooLargeEventHandler.java @@ -0,0 +1,12 @@ +package org.gcube.portlets.widgets.fileupload.client.events; + +import com.google.gwt.event.shared.EventHandler; + +/** + * Handler linked to @{FileTooLargeEvent} event class. + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + */ +public interface FileTooLargeEventHandler extends EventHandler{ + void onFileTooLargeEvent(FileTooLargeEvent fileTooLargeEvent); +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadCompleteEvent.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadCompleteEvent.java new file mode 100644 index 0000000..c11b5cc --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadCompleteEvent.java @@ -0,0 +1,32 @@ +package org.gcube.portlets.widgets.fileupload.client.events; + +import org.gcube.portlets.widgets.fileupload.shared.event.UploadProgressChangeEvent; + +import com.google.gwt.event.shared.GwtEvent; + + + +public class FileUploadCompleteEvent extends GwtEvent { + public static Type TYPE = new Type(); + + private UploadProgressChangeEvent uploadedFile; + + + public UploadProgressChangeEvent getUploadedFileInfo() { + return uploadedFile; + } + + public FileUploadCompleteEvent(UploadProgressChangeEvent uploadedFile) { + this.uploadedFile = uploadedFile; + } + + @Override + public Type getAssociatedType() { + return TYPE; + } + + @Override + protected void dispatch(FileUploadCompleteEventHandler handler) { + handler.onUploadComplete(this); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadCompleteEventHandler.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadCompleteEventHandler.java new file mode 100644 index 0000000..8e3a3d8 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadCompleteEventHandler.java @@ -0,0 +1,7 @@ +package org.gcube.portlets.widgets.fileupload.client.events; + +import com.google.gwt.event.shared.EventHandler; + +public interface FileUploadCompleteEventHandler extends EventHandler { + void onUploadComplete(FileUploadCompleteEvent event); +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadSelectedEvent.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadSelectedEvent.java new file mode 100644 index 0000000..9847a80 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadSelectedEvent.java @@ -0,0 +1,30 @@ +package org.gcube.portlets.widgets.fileupload.client.events; + +import com.google.gwt.event.shared.GwtEvent; + + + +public class FileUploadSelectedEvent extends GwtEvent { + public static Type TYPE = new Type(); + + private String filename; + + + public String getSelectedFileName() { + return filename; + } + + public FileUploadSelectedEvent(String filename) { + this.filename = filename; + } + + @Override + public Type getAssociatedType() { + return TYPE; + } + + @Override + protected void dispatch(FileUploadSelectedEventHandler handler) { + handler.onFileSelected(this); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadSelectedEventHandler.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadSelectedEventHandler.java new file mode 100644 index 0000000..c820e10 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/events/FileUploadSelectedEventHandler.java @@ -0,0 +1,7 @@ +package org.gcube.portlets.widgets.fileupload.client.events; + +import com.google.gwt.event.shared.EventHandler; + +public interface FileUploadSelectedEventHandler extends EventHandler { + void onFileSelected(FileUploadSelectedEvent event); +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/state/AbstractState.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/state/AbstractState.java new file mode 100644 index 0000000..7ffb892 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/state/AbstractState.java @@ -0,0 +1,37 @@ +package org.gcube.portlets.widgets.fileupload.client.state; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +public abstract class AbstractState implements State { + + private transient PropertyChangeSupport changes = new PropertyChangeSupport(this); + + @Override + public final void addPropertyChangeListener(final PropertyChangeListener l) { + changes.addPropertyChangeListener(l); + } + + @Override + public final void addPropertyChangeListener(final String propertyName, + final PropertyChangeListener l) { + changes.addPropertyChangeListener(propertyName, l); + } + + @Override + public final void firePropertyChange(final String propertyName, + final Object oldValue, final Object newValue) { + changes.firePropertyChange(propertyName, oldValue, newValue); + } + + @Override + public final void removePropertyChangeListener(final PropertyChangeListener l) { + changes.removePropertyChangeListener(l); + } + + @Override + public final void removePropertyChangeListener(final String propertyName, + final PropertyChangeListener l) { + changes.removePropertyChangeListener(propertyName, l); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/state/State.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/state/State.java new file mode 100644 index 0000000..f7f67fd --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/state/State.java @@ -0,0 +1,17 @@ +package org.gcube.portlets.widgets.fileupload.client.state; + +import java.beans.PropertyChangeListener; + +interface State { + + void addPropertyChangeListener(PropertyChangeListener l); + + void addPropertyChangeListener(String propertyName, PropertyChangeListener l); + + void firePropertyChange(String propertyName, Object oldValue, Object newValue); + + void removePropertyChangeListener(PropertyChangeListener l); + + void removePropertyChangeListener(String propertyName, + PropertyChangeListener l); +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/state/UploadProgressState.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/state/UploadProgressState.java new file mode 100644 index 0000000..89f81eb --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/state/UploadProgressState.java @@ -0,0 +1,24 @@ +package org.gcube.portlets.widgets.fileupload.client.state; + +import java.util.HashMap; +import java.util.Map; + +public final class UploadProgressState extends AbstractState { + + public static final UploadProgressState INSTANCE = new UploadProgressState(); + private Map uploadProgress; + + private UploadProgressState() { + uploadProgress = new HashMap(); + } + + public Integer getUploadProgress(final String filename) { + return uploadProgress.get(filename); + } + + public void setUploadProgress(final String filename, final Integer percentage) { + Integer old = this.uploadProgress.get(filename); + uploadProgress.put(filename, percentage); + firePropertyChange("uploadProgress", old, uploadProgress); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/FileSubmit.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/FileSubmit.java new file mode 100644 index 0000000..70b4482 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/FileSubmit.java @@ -0,0 +1,176 @@ +package org.gcube.portlets.widgets.fileupload.client.view; + +import org.gcube.portlets.widgets.fileupload.client.bundle.ProgressBarCssAndImages; +import org.gcube.portlets.widgets.fileupload.client.controller.ProgressController; +import org.gcube.portlets.widgets.fileupload.client.events.FileTooLargeEvent; +import org.gcube.portlets.widgets.fileupload.client.events.FileUploadSelectedEvent; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Element; +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FileUpload; +import com.google.gwt.user.client.ui.FormPanel; +import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent; +import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Panel; +import com.google.gwt.user.client.ui.SimplePanel; +/** + * + * @author Massimiliano Assante, ISTI-CNR + * + */ +public final class FileSubmit extends Composite { + /** + * VERY IMPORTANT, must be the same in web.xml + */ + public static final String URL = GWT.getModuleBaseURL()+"../FileUpload/upload"; + + ProgressBarCssAndImages images = GWT.create(ProgressBarCssAndImages.class); + + // maximum size of a file that can be attached in MB + public static final int MAX_SIZE_ATTACHED_FILE_MB = 50; + + // too large file selected + private static final String TOO_LARGE_FILE_ERROR = "The chosen file can't be uploaded since it is too large! Sorry..."; + + private HTML registeringLabel = new HTML("" + + "Applying required operations, please wait ... "); + + private FileUpload fileUpload; + private FormPanel form; + private Panel uploadPanel = new SimplePanel(); + private UploadProgressDialog dlg; + private HandlerRegistration submitHandler; + private HandlerManager eventBus; + + /** + * Constructor + * @param eventBus + * @param isDND if the file has to be loaded through DND + */ + public FileSubmit(HandlerManager eventBus, boolean isDND) { + + // save the event bus + this.eventBus = eventBus; + + if(!isDND){ + + ProgressController.start(eventBus); + + fileUpload = new FileUpload(); + fileUpload.setName("fileUpload"); + fileUpload.setTitle("select a file to upload"); + + + uploadPanel.setStyleName("FileSubmit"); + uploadPanel.add(fileUpload); + + + form = new FormPanel(); + form.setEncoding(FormPanel.ENCODING_MULTIPART); + form.setMethod(FormPanel.METHOD_POST); + form.getElement().setAttribute("acceptcharset", "UTF-8"); + form.setAction(URL); + form.setWidget(uploadPanel); + + this.initWidget(form); + + //triggered on selected file form user + submitHandler = fileUpload.addChangeHandler(new FormSubmitChangeHandler()); + + form.addSubmitCompleteHandler(new FormSubmitCompleteHandler()); + + }else{ + + ProgressController.start(eventBus); + initWidget(new SimplePanel()); + } + + } + + public FileSubmit(UploadProgressDialog dlg, final HandlerManager eventBus) { + this(eventBus, false); + this.dlg = dlg; + if (dlg.isFormSubmitHandled()) { + submitHandler.removeHandler(); + fileUpload.addChangeHandler(new ChangeHandler() { + @Override + public void onChange(ChangeEvent event) { + eventBus.fireEvent(new FileUploadSelectedEvent(fileUpload.getFilename())); + } + }); + } + + } + + protected void showRegisteringResult(boolean success, String customLabel) { + if (customLabel == null || customLabel.compareTo("") == 0) { + customLabel = success ? "Operation Completed Successfully" : "Sorry, an error occurred in the Server"; + } + uploadPanel.clear(); + if (success) + uploadPanel.add( new HTML("" + + customLabel + " ")); + else + uploadPanel.add( new HTML("" + + customLabel + " ")); + if (dlg != null) //if dialog mode + dlg.showFinalCloseButton(); + } + + + private class FormSubmitCompleteHandler implements SubmitCompleteHandler { + + @Override + public void onSubmitComplete(final SubmitCompleteEvent event) { + //form.reset(); + uploadPanel.remove(fileUpload); + if (dlg != null) { //if dialog mode + uploadPanel.add(registeringLabel); + dlg.hideCloseButton(); + } + } + } + + private class FormSubmitChangeHandler implements ChangeHandler { + @Override + public void onChange(ChangeEvent event) { + + // check the size of the chosen file + GWT.log("SIZE is " + getChosenFileSize(fileUpload.getElement())); + + if(getChosenFileSize(fileUpload.getElement()) > MAX_SIZE_ATTACHED_FILE_MB){ + // signal the error + Window.alert(TOO_LARGE_FILE_ERROR); + + // throw the event + eventBus.fireEvent(new FileTooLargeEvent()); + + return; + } + + form.submit(); + } + } + + protected FileUpload getFileUpload() { + return fileUpload; + } + + protected void submitForm() { + form.submit(); + } + + private static native int getChosenFileSize(final Element data) /*-{ + + // convert from bytes to MB + return (data.files[0].size / 1024 / 1024); + }-*/; + +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/ProgressBar.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/ProgressBar.java new file mode 100644 index 0000000..f6eb4cb --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/ProgressBar.java @@ -0,0 +1,37 @@ +package org.gcube.portlets.widgets.fileupload.client.view; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Widget; + +public class ProgressBar extends Composite { + + private static final double COMPLETE_PERECENTAGE = 100d; + private static final double START_PERECENTAGE = 0d; + + private static ProgressBarUiBinder uiBinder = GWT + .create(ProgressBarUiBinder.class); + + interface ProgressBarUiBinder extends UiBinder { } + + @UiField HTML progressBarContainer; + + public ProgressBar() { + initWidget(uiBinder.createAndBindUi(this)); + } + + public void update(int percentage) { + if (percentage > 100) + percentage = 100; + if (percentage < START_PERECENTAGE || percentage > COMPLETE_PERECENTAGE) { + throw new IllegalArgumentException("invalid value for percentage " + percentage); + } else { //cannot use DOM getElemById cus the second time you open the popup it fails + progressBarContainer.getElement().setAttribute("style", "width: "+percentage+"%"); + progressBarContainer.getElement().getFirstChildElement().getFirstChildElement().setInnerText(percentage+"%"); + } + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/ProgressBar.ui.xml b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/ProgressBar.ui.xml new file mode 100644 index 0000000..6fd613c --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/ProgressBar.ui.xml @@ -0,0 +1,13 @@ + + + +
+ + + 0% + + +
+
+
\ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgress.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgress.java new file mode 100644 index 0000000..6cc2b46 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgress.java @@ -0,0 +1,65 @@ +package org.gcube.portlets.widgets.fileupload.client.view; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Map; + +import org.gcube.portlets.widgets.fileupload.client.state.UploadProgressState; + +import com.google.gwt.user.client.Timer; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Panel; +import com.google.gwt.user.client.ui.VerticalPanel; + + +public final class UploadProgress extends Composite { + + private Panel panel; + + private ProgressBar bar = new ProgressBar(); + /** + * + */ + public UploadProgress() { + + panel = new VerticalPanel(); + panel.setStyleName("progressBarContainer"); + this.initWidget(panel); + + UploadProgressState.INSTANCE.addPropertyChangeListener("uploadProgress", new UploadProgressListener()); + } + + private final class UploadProgressListener implements PropertyChangeListener { + + private static final int COMPLETE_PERECENTAGE = 100; + private static final int REMOVE_DELAY = 3000; + + @Override + public void propertyChange(final PropertyChangeEvent event) { + + Map uploadPercentage = (Map) event.getNewValue(); + + for (Map.Entry entry : uploadPercentage.entrySet()) { + String file = entry.getKey(); + Integer percentage = entry.getValue(); + + panel.add(bar); + + bar.update(percentage); + + if (percentage == COMPLETE_PERECENTAGE) { + Timer timer = new Timer() { + + @Override + public void run() { + panel.remove(bar); + } + }; + //timer.schedule(REMOVE_DELAY); + } + } + } + } + +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressDialog.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressDialog.java new file mode 100644 index 0000000..10108d8 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressDialog.java @@ -0,0 +1,129 @@ +package org.gcube.portlets.widgets.fileupload.client.view; + +import org.gcube.portlets.user.gcubewidgets.client.popup.GCubeDialog; +import org.gcube.portlets.widgets.fileupload.client.bundle.ProgressBarCssAndImages; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.CellPanel; +import com.google.gwt.user.client.ui.HasAlignment; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.VerticalPanel; +/** + * @author Massimiliano Assante, ISTI-CNR + * + */ +public class UploadProgressDialog extends GCubeDialog { + + private static final int WIDTH = 400; + + static { + ProgressBarCssAndImages.INSTANCE.css().ensureInjected(); + } + + private CellPanel mainPanel = new VerticalPanel(); + private HorizontalPanel bottomPanel = new HorizontalPanel(); + private UploadProgressView uploadView ; + private boolean handleFormSubmit = false; + /** + * regular constructor + * + * @param headerText + * @param eventBus + */ + public UploadProgressDialog(String headerText, HandlerManager eventBus) { + setText(headerText); + + this.uploadView = new UploadProgressView(this, eventBus); + + mainPanel.setPixelSize(WIDTH, 80); + bottomPanel.setPixelSize(WIDTH, 25); + + mainPanel.add(uploadView); + mainPanel.add(bottomPanel); + + bottomPanel.setHorizontalAlignment(HasAlignment.ALIGN_RIGHT); + Button close = new Button("Cancel"); + bottomPanel.add(close); + close.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + hide(); + } + }); + mainPanel.setCellHeight(bottomPanel, "25px"); + setWidget(mainPanel); + } + /** + * to be used if you want to handle form submit + * + * @param headerText + * @param eventBus + * @param handleFormSubmit + */ + public UploadProgressDialog(String headerText, HandlerManager eventBus, boolean handleFormSubmit) { + setText(headerText); + this.handleFormSubmit = handleFormSubmit; + this.uploadView = new UploadProgressView(this, eventBus); + + mainPanel.setPixelSize(WIDTH, 80); + bottomPanel.setPixelSize(WIDTH, 25); + + mainPanel.add(uploadView); + mainPanel.add(bottomPanel); + + bottomPanel.setHorizontalAlignment(HasAlignment.ALIGN_RIGHT); + Button close = new Button("Cancel"); + bottomPanel.add(close); + close.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + hide(); + } + }); + mainPanel.setCellHeight(bottomPanel, "25px"); + setWidget(mainPanel); + + } + + public void showRegisteringResult(boolean result) { + uploadView.showRegisteringResult(result, null); + } + + public void showRegisteringResult(boolean result, String customFeedback) { + uploadView.showRegisteringResult(result, customFeedback); + } + + /** + * to call when handle + * @throws Exception + */ + public void submitForm() throws Exception { + if (handleFormSubmit) + uploadView.submitForm(); + else + throw new Exception("You must set this widget to handleFormSubmit"); + } + + protected void hideCloseButton() { + bottomPanel.clear(); + } + + protected boolean isFormSubmitHandled() { + return handleFormSubmit; + } + + protected void showFinalCloseButton() { + bottomPanel.clear(); + Button close = new Button("Close"); + bottomPanel.add(close); + close.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + hide(); + } + }); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressPanel.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressPanel.java new file mode 100644 index 0000000..7ecce7d --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressPanel.java @@ -0,0 +1,71 @@ +package org.gcube.portlets.widgets.fileupload.client.view; + +import org.gcube.portlets.widgets.fileupload.client.bundle.ProgressBarCssAndImages; + +import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FileUpload; +import com.google.gwt.user.client.ui.VerticalPanel; +/** + * + * @author Massimiliano Assante, ISTI-CNR + * + */ +public final class UploadProgressPanel extends Composite { + + static { + ProgressBarCssAndImages.INSTANCE.panelCss().ensureInjected(); + } + + private HandlerManager eventBus; + + private FileSubmit fileSubmit; + + private VerticalPanel mainPanel = new VerticalPanel(); + + /** + * as a Panel + * @param eventBus + */ + public UploadProgressPanel(HandlerManager eventBus) { + this.eventBus = eventBus; + mainPanel.setStyleName("progressContainer"); + initWidget(mainPanel); + } + + /** + * Used when attaching files via button + * @return + */ + public FileUpload initialize() { + mainPanel.clear(); + fileSubmit = new FileSubmit(eventBus, false); + mainPanel.add(fileSubmit); + mainPanel.add(new UploadProgress()); + //return the fileupload so that you cane set it hidden + return fileSubmit.getFileUpload(); + } + + /** + * Used when attaching files via dnd + * @return + */ + public void initializeDND(){ + mainPanel.clear(); + fileSubmit = new FileSubmit(eventBus, true); + mainPanel.add(fileSubmit); + mainPanel.add(new UploadProgress()); + } + + public void showRegisteringResult(boolean result) { + fileSubmit.showRegisteringResult(result, null); + } + + public void showRegisteringResult(boolean result, String customFeedback) { + fileSubmit.showRegisteringResult(result, customFeedback); + } + + public FileUpload getFileUpload() { + return fileSubmit.getFileUpload(); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressView.java b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressView.java new file mode 100644 index 0000000..dc985e7 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressView.java @@ -0,0 +1,43 @@ +package org.gcube.portlets.widgets.fileupload.client.view; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiFactory; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.Widget; + +public final class UploadProgressView extends Composite { + + interface UploadProgressViewUiBinder extends UiBinder { + } + private static UploadProgressViewUiBinder uiBinder = GWT.create(UploadProgressViewUiBinder.class); + private HandlerManager eventBus; + + @UiField + FileSubmit fileSubmit; + @UiField + UploadProgress uploadProgress; + UploadProgressDialog dlg; + + protected UploadProgressView(UploadProgressDialog dlg, HandlerManager eventBus) { + this.eventBus = eventBus; + this.dlg = dlg; + initWidget(uiBinder.createAndBindUi(this)); + } + + /** Used by UiBinder to instantiate FileSubmit */ + @UiFactory + FileSubmit makeFileSubmit() { + return new FileSubmit(dlg, eventBus); + } + + protected void showRegisteringResult(boolean result, String customFeedback) { + fileSubmit.showRegisteringResult(result, customFeedback); + } + + protected void submitForm() { + fileSubmit.submitForm(); + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressView.ui.xml b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressView.ui.xml new file mode 100644 index 0000000..e69ee4d --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/client/view/UploadProgressView.ui.xml @@ -0,0 +1,10 @@ + + + +
+ + +
+
+
\ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgress.java b/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgress.java new file mode 100644 index 0000000..1314209 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgress.java @@ -0,0 +1,42 @@ +package org.gcube.portlets.widgets.fileupload.server; + +import java.util.ArrayList; +import java.util.List; +import javax.servlet.http.HttpSession; +import org.gcube.portlets.widgets.fileupload.shared.event.*; + +public final class UploadProgress { + + private static final String SESSION_KEY = "uploadProgress"; + private List events = new ArrayList(); + + private UploadProgress() { + } + + public List getEvents() { + + return events; + } + + public void add(final Event event) { + events.add(event); + } + + public void clear() { + events = new ArrayList(); + } + + public boolean isEmpty() { + return events.isEmpty(); + } + + public static UploadProgress getUploadProgress(final HttpSession session) { + Object attribute = session.getAttribute(SESSION_KEY); + if (null == attribute) { + attribute = new UploadProgress(); + session.setAttribute(SESSION_KEY, attribute); + } + + return null == attribute ? null : (UploadProgress) attribute; + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgressInputStream.java b/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgressInputStream.java new file mode 100644 index 0000000..c5425d4 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgressInputStream.java @@ -0,0 +1,69 @@ +package org.gcube.portlets.widgets.fileupload.server; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.fileupload.ProgressListener; + +public final class UploadProgressInputStream extends FilterInputStream { + + private List listeners; + private long bytesRead = 0; + private long totalBytes = 0; + + public UploadProgressInputStream(final InputStream in, final long totalBytes) { + super(in); + + this.totalBytes = totalBytes; + + listeners = new ArrayList(); + } + + public void addListener(final ProgressListener listener) { + listeners.add(listener); + } + + @Override + public int read() throws IOException { + int b = super.read(); + + this.bytesRead++; + + updateListeners(bytesRead, totalBytes); + + return b; + } + + @Override + public int read(final byte b[]) throws IOException { + return read(b, 0, b.length); + } + + @Override + public int read(final byte b[], final int off, final int len) throws IOException { + int bytesRead = in.read(b, off, len); + + this.bytesRead = this.bytesRead + bytesRead; + + updateListeners(this.bytesRead, totalBytes); + + return bytesRead; + } + + @Override + public void close() throws IOException { + super.close(); + + updateListeners(totalBytes, totalBytes); + } + + private void updateListeners(final long bytesRead, final long totalBytes) { + + for (ProgressListener listener : listeners) { + + listener.update(bytesRead, totalBytes, listeners.size()); + } + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgressListener.java b/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgressListener.java new file mode 100644 index 0000000..b2b79a7 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgressListener.java @@ -0,0 +1,42 @@ +package org.gcube.portlets.widgets.fileupload.server; + + +import org.apache.commons.fileupload.ProgressListener; +import org.gcube.portlets.widgets.fileupload.shared.event.UploadProgressChangeEvent; + +public final class UploadProgressListener implements ProgressListener { + + private static final double COMPLETE_PERECENTAGE = 100d; + private int percentage = -1; + private String fileName; + private String absolutePath; + private UploadProgress uploadProgress; + + public UploadProgressListener(final String fileName, final UploadProgress uploadProgress, final String absolutePath) { + this.fileName = fileName; + this.uploadProgress = uploadProgress; + this.absolutePath = absolutePath; + } + + @Override + public void update(final long bytesRead, final long totalBytes, final int items) { + + int percentage = (int) Math.floor(((double) bytesRead / (double) totalBytes) * COMPLETE_PERECENTAGE); + + if (this.percentage == percentage) { + return; + } + + this.percentage = percentage; + + UploadProgressChangeEvent event = new UploadProgressChangeEvent(); + event.setFilename(this.fileName); + event.setPercentage(percentage); + event.setAbsolutePath(this.absolutePath); + + synchronized (this.uploadProgress) { + this.uploadProgress.add(event); + this.uploadProgress.notifyAll(); + } + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgressServlet.java b/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgressServlet.java new file mode 100644 index 0000000..9560d02 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadProgressServlet.java @@ -0,0 +1,51 @@ +package org.gcube.portlets.widgets.fileupload.server; + +import java.util.List; + +import javax.servlet.http.HttpSession; + +import org.gcube.portlets.widgets.fileupload.client.UploadProgressService; +import org.gcube.portlets.widgets.fileupload.shared.event.Event; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gwt.user.server.rpc.RemoteServiceServlet; + +@SuppressWarnings("serial") +public final class UploadProgressServlet extends RemoteServiceServlet implements UploadProgressService { + + private static final int EVENT_WAIT = 30 * 1000; + private static final Logger _log = LoggerFactory.getLogger(UploadProgressServlet.class); + + @Override + public void initialise() { + getThreadLocalRequest().getSession(true); + } + + @Override + public List getEvents() { + + HttpSession session = getThreadLocalRequest().getSession(); + UploadProgress uploadProgress = UploadProgress.getUploadProgress(session); + + List events = null; + if (null != uploadProgress) { + if (uploadProgress.isEmpty()) { + try { + synchronized (uploadProgress) { + _log.debug("waiting..."); + uploadProgress.wait(EVENT_WAIT); + } + } catch (final InterruptedException ie) { + _log.debug("interrupted..."); + } + } + + synchronized (uploadProgress) { + events = uploadProgress.getEvents(); + uploadProgress.clear(); + } + } + return events; + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadServlet.java b/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadServlet.java new file mode 100644 index 0000000..5d6f120 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/server/UploadServlet.java @@ -0,0 +1,98 @@ +package org.gcube.portlets.widgets.fileupload.server; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.Normalizer; +import java.util.UUID; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.fileupload.FileItemFactory; +import org.apache.commons.fileupload.FileItemIterator; +import org.apache.commons.fileupload.FileItemStream; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.fileupload.util.Streams; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +/** + * + * @author Massimiliano Assante, ISTI-CNR + * + */ +@SuppressWarnings("serial") +public final class UploadServlet extends HttpServlet { + + private static final Logger _log = LoggerFactory.getLogger(UploadServlet.class); + + /** + * use tomcat temp as base upload folder + */ + private static String UPLOAD_LOCATION = System.getProperty("java.io.tmpdir"); + + public void init() { + if (System.getenv("CATALINA_TMPDIR") != null && System.getenv("CATALINA_TMPDIR").compareTo("") != 0) { + UPLOAD_LOCATION = System.getenv("CATALINA_TMPDIR"); + } + } + + @Override + protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { + try { + uploadFile(request); + } catch (FileUploadException fue) { + throw new ServletException(fue); + } + } + + private void uploadFile(final HttpServletRequest request) throws FileUploadException, IOException { + + if (!ServletFileUpload.isMultipartContent(request)) { + throw new FileUploadException("ERROR: multipart request not found"); + } + + FileItemFactory fileItemFactory = new DiskFileItemFactory(); + ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory); + + FileItemIterator fileItemIterator = servletFileUpload.getItemIterator(request); + + HttpSession session = request.getSession(); + UploadProgress uploadProgress = UploadProgress.getUploadProgress(session); + + while (fileItemIterator.hasNext()) { + FileItemStream fileItemStream = fileItemIterator.next(); + + String filePath = fileItemStream.getName(); + String fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1); + + String normalizedString = Normalizer.normalize(fileName, Normalizer.Form.NFD); + String sanitizedFileName = normalizedString.replaceAll("[^\\x00-\\x7F]", ""); + //generate the random dir + File theRandomDir = new File(UPLOAD_LOCATION + File.separator + UUID.randomUUID().toString()); + theRandomDir.mkdir(); + _log.debug("Created temp upload directory in: " + theRandomDir); + + //create the file + File file = new File(theRandomDir, sanitizedFileName); + Long size = Long.parseLong(request.getHeader("Content-Length")); + _log.debug("size: " + size + " bytes sanitized File name="+sanitizedFileName); + _log.debug("path: " + file.getAbsolutePath()); + + //instanciate the progress listener + UploadProgressListener uploadProgressListener = new UploadProgressListener(sanitizedFileName, uploadProgress, file.getAbsolutePath()); + UploadProgressInputStream inputStream = new UploadProgressInputStream(fileItemStream.openStream(), size); + inputStream.addListener(uploadProgressListener); + + //actually copying + Streams.copy(inputStream, new FileOutputStream(file), true); + //finished + _log.info("uploaded file " + file.getAbsolutePath()); + } + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/shared/FieldVerifier.java b/src/main/java/org/gcube/portlets/widgets/fileupload/shared/FieldVerifier.java new file mode 100644 index 0000000..3f1f35d --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/shared/FieldVerifier.java @@ -0,0 +1,42 @@ +package org.gcube.portlets.widgets.fileupload.shared; + +/** + *

+ * FieldVerifier validates that the name the user enters is valid. + *

+ *

+ * This class is in the shared packing because we use it in both + * the client code and on the server. On the client, we verify that the name is + * valid before sending an RPC request so the user doesn't have to wait for a + * network round trip to get feedback. On the server, we verify that the name is + * correct to ensure that the input is correct regardless of where the RPC + * originates. + *

+ *

+ * When creating a class that is used on both the client and the server, be sure + * that all code is translatable and does not use native JavaScript. Code that + * is note translatable (such as code that interacts with a database or the file + * system) cannot be compiled into client side JavaScript. Code that uses native + * JavaScript (such as Widgets) cannot be run on the server. + *

+ */ +public class FieldVerifier { + + /** + * Verifies that the specified name is valid for our service. + * + * In this example, we only require that the name is at least four + * characters. In your application, you can use more complex checks to ensure + * that usernames, passwords, email addresses, URLs, and other fields have the + * proper syntax. + * + * @param name the name to validate + * @return true if valid, false if invalid + */ + public static boolean isValidName(String name) { + if (name == null) { + return false; + } + return name.length() > 3; + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/shared/dto/FileDto.java b/src/main/java/org/gcube/portlets/widgets/fileupload/shared/dto/FileDto.java new file mode 100644 index 0000000..ac33eca --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/shared/dto/FileDto.java @@ -0,0 +1,60 @@ +package org.gcube.portlets.widgets.fileupload.shared.dto; + +import java.io.Serializable; +import java.util.Date; + +public final class FileDto implements Serializable { + + private String filename; + private Date dateUploaded; + + public FileDto() { + } + + public Date getDateUploaded() { + return dateUploaded; + } + + public void setDateUploaded(final Date dateUploaded) { + this.dateUploaded = dateUploaded; + } + + public String getFilename() { + return filename; + } + + public void setFilename(final String filename) { + this.filename = filename; + } + + @Override + public String toString() { + return filename + " - " + dateUploaded; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final FileDto other = (FileDto) obj; + if ((this.filename == null) ? (other.filename != null) : !this.filename.equals(other.filename)) { + return false; + } + if (this.dateUploaded != other.dateUploaded && (this.dateUploaded == null || !this.dateUploaded.equals(other.dateUploaded))) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 67 * hash + (this.filename != null ? this.filename.hashCode() : 0); + hash = 67 * hash + (this.dateUploaded != null ? this.dateUploaded.hashCode() : 0); + return hash; + } +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/shared/event/Event.java b/src/main/java/org/gcube/portlets/widgets/fileupload/shared/event/Event.java new file mode 100644 index 0000000..cd305c1 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/shared/event/Event.java @@ -0,0 +1,4 @@ +package org.gcube.portlets.widgets.fileupload.shared.event; + +public interface Event { +} diff --git a/src/main/java/org/gcube/portlets/widgets/fileupload/shared/event/UploadProgressChangeEvent.java b/src/main/java/org/gcube/portlets/widgets/fileupload/shared/event/UploadProgressChangeEvent.java new file mode 100644 index 0000000..e3d3015 --- /dev/null +++ b/src/main/java/org/gcube/portlets/widgets/fileupload/shared/event/UploadProgressChangeEvent.java @@ -0,0 +1,51 @@ +package org.gcube.portlets.widgets.fileupload.shared.event; + +import java.io.Serializable; + +@SuppressWarnings("serial") +public final class UploadProgressChangeEvent implements Event, Serializable { + /** + * the file name + */ + private String filename; + /** + * the path of the uploaded file + */ + private String absolutePath; + /** + * the current percentage + */ + private Integer percentage; + + public UploadProgressChangeEvent() { + } + + public String getFilename() { + return filename; + } + + public void setFilename(final String filename) { + this.filename = filename; + } + + public Integer getPercentage() { + return percentage; + } + + public void setPercentage(final Integer percentage) { + this.percentage = percentage; + } + + public String getAbsolutePath() { + return absolutePath; + } + + public void setAbsolutePath(String absolutePath) { + this.absolutePath = absolutePath; + } + + @Override + public String toString() { + return filename + " - " + percentage + " path="+absolutePath; + } +} diff --git a/src/main/resources/clientlog4j.properties b/src/main/resources/clientlog4j.properties new file mode 100644 index 0000000..2248fe1 --- /dev/null +++ b/src/main/resources/clientlog4j.properties @@ -0,0 +1,17 @@ +log4j.rootLogger=DEBUG, A1 +log4j.appender.A1=org.apache.log4j.ConsoleAppender +log4j.appender.A1.layout=org.apache.log4j.PatternLayout + +# Print the date in ISO 8601 format +log4j.appender.A1.layout.ConversionPattern=%d %-5p %c - %m%n + +# Print only messages of level TRACE or above in the package org.gcube +log4j.logger.org.gcube=TRACE +log4j.logger.org.gcube.application.framework.core.session=INFO +log4j.logger.org.gcube.contentmanager=ERROR +log4j.logger.org.gcube.common.scope=ERROR +log4j.logger.org.gcube.contentmanagement=ERROR +log4j.logger.org.gcube.resources.discovery.icclient=ERROR +log4j.logger.org.gcube.common.clients=ERROR +log4j.logger.org.gcube.common.homelibrary.jcr=ERROR +log4j.logger.org.gcube.application.framework.accesslogger=ERROR diff --git a/src/main/webapp/FileUpload.html b/src/main/webapp/FileUpload.html new file mode 100644 index 0000000..c163b28 --- /dev/null +++ b/src/main/webapp/FileUpload.html @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + File Upload Widget + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/.gitignore b/src/main/webapp/WEB-INF/.gitignore new file mode 100644 index 0000000..840e7d3 --- /dev/null +++ b/src/main/webapp/WEB-INF/.gitignore @@ -0,0 +1 @@ +/classes/ diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..508570d --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,35 @@ + + + + + + + uploadprogress + org.gcube.portlets.widgets.fileupload.server.UploadProgressServlet + + + + + uploadprogress + /FileUpload/uploadprogress + + + + upload + org.gcube.portlets.widgets.fileupload.server.UploadServlet + + + + + upload + /FileUpload/upload + + + + + + + FileUpload.html + + + diff --git a/src/main/webapp/images/progress.png b/src/main/webapp/images/progress.png new file mode 100644 index 0000000000000000000000000000000000000000..13e45943f029f2646e071a0f203fce96e0924f9e GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|Pfr)e5R2Zo7Y+FiC=wS^82E0kg)r)@pUCUkXf&6kI^dp5IVI-VA|GQ;xww;PO&o0yw)jGy1DTO*qt dulO(bEz`k7V~32&!cd^044$rjF6*2UngA + + + + + + + +