commit be650924452d9dca12a91688e5a00bd6458b7f7b Author: francesco Date: Wed Oct 7 17:04:13 2020 +0200 project created diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..0ca36d1 --- /dev/null +++ b/.classpath @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..017b8e4 --- /dev/null +++ b/.project @@ -0,0 +1,46 @@ + + + geoportal-data-entry-app + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + com.gwtplugins.gdt.eclipse.core.webAppProjectValidator + + + + + com.gwtplugins.gwt.eclipse.core.gwtProjectValidator + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.m2e.core.maven2Nature + com.gwtplugins.gwt.eclipse.core.gwtNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + + diff --git a/.settings/com.gwtplugins.gdt.eclipse.core.prefs b/.settings/com.gwtplugins.gdt.eclipse.core.prefs new file mode 100644 index 0000000..5d35668 --- /dev/null +++ b/.settings/com.gwtplugins.gdt.eclipse.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +lastWarOutDir=/home/francesco/git/geoportal-data-entry-app/target/geoportal-data-entry-app-1.0.0-SNAPSHOT +warSrcDir=src/main/webapp +warSrcDirIsOutput=false 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..43c8195 --- /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.7 +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.7 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..acdfd58 --- /dev/null +++ b/.settings/org.eclipse.wst.common.component @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..265a820 --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,6 @@ + + + + + + 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/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f80ad6f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ + +# Changelog + +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). + +## [v1.0.0-SNAPSHOT] - 2020-10-07 + +First release diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..1932b4c --- /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 diff --git a/README.md b/README.md new file mode 100644 index 0000000..c5195e3 --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# GeoPortal Data Entry App + +The GeoPortal Data Entry App is an application to build the web forms for data entries needed to GeoNa project + +## Built With + +* [OpenJDK](https://openjdk.java.net/) - The JDK used +* [Maven](https://maven.apache.org/) - Dependency Management + +## Documentation + +N/A + +## Change log + +See the [Releases](https://code-repo.d4science.org/gCubeSystem/geoportal-data-entry-app/releases) + +## Authors + +* **Francesco Mangiacrapa** ([ORCID](https://orcid.org/0000-0002-6528-664X)) Computer Scientist at [ISTI-CNR Infrascience Group](http://nemis.isti.cnr.it/groups/infrascience) + +## License + +This project is licensed under the EUPL V.1.1 License - see the [LICENSE.md](LICENSE.md) file for details. + + +## About the gCube Framework +This software is part of the [gCubeFramework](https://www.gcube-system.org/ "gCubeFramework"): an +open-source software toolkit used for building and operating Hybrid Data +Infrastructures enabling the dynamic deployment of Virtual Research Environments +by favouring the realisation of reuse oriented policies. + +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 (grant no. 004260). +- the Seventh Framework Programme for research, technological development and demonstration + - D4Science (grant no. 212488); + - D4Science-II (grant no.239019); + - ENVRI (grant no. 283465); + - EUBrazilOpenBio (grant no. 288754); + - iMarine(grant no. 283644). +- the H2020 research and innovation programme + - BlueBRIDGE (grant no. 675680); + - EGIEngage (grant no. 654142); + - ENVRIplus (grant no. 654182); + - PARTHENOS (grant no. 654119); + - SoBigData (grant no. 654024); + - DESIRA (grant no. 818194); + - ARIADNEplus (grant no. 823914); + - RISIS2 (grant no. 824091); + - PerformFish (grant no. 727610); + - AGINFRAplus (grant no. 731001). + + diff --git a/descriptor.xml b/descriptor.xml new file mode 100644 index 0000000..0487853 --- /dev/null +++ b/descriptor.xml @@ -0,0 +1,30 @@ + + servicearchive + + tar.gz + + / + + + / + true + + README.md + LICENSE.md + profile.xml + CHANGELOG.md + + 755 + true + + + + + target/${build.finalName}.${project.packaging} + /${artifactId} + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..0adc461 --- /dev/null +++ b/pom.xml @@ -0,0 +1,260 @@ + + + + 4.0.0 + + maven-parent + org.gcube.tools + 1.1.0 + + + + org.gcube.portlets.user + geoportal-data-entry-app + war + 1.0.0-SNAPSHOT + GeoPortal Data Entry App + The GeoPortal Data Entry App is an application to build the web forms for data entries needed to GeoNa project + + 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.7.0 + + ${project.build.directory}/${project.build.finalName} + UTF-8 + UTF-8 + 1.7 + 1.8 + + + + + Francesco Mangiacrapa + francesco.mangiacrapa@isti.cnr.it + CNR Pisa, Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" + + architect + developer + + + + + + + + org.gcube.distribution + maven-portal-bom + 3.6.0 + pom + import + + + + + + + com.google.gwt + gwt-user + ${gwtVersion} + provided + + + com.google.gwt + gwt-dev + ${gwtVersion} + provided + + + com.github.gwtbootstrap + gwt-bootstrap + 2.3.2.0 + compile + + + org.gcube.portlets.widgets + openlayer-basic-widgets + [1.0.0, 2.0.0-SNAPSHOT) + compile + + + + org.gcube.common + authorization-client + provided + + + org.gcube.resources.discovery + ic-client + provided + + + org.gcube.core + common-scope-maps + compile + + + org.gcube.portal + client-context-library + [1.0.0, 2.0.0-SNAPSHOT) + compile + + + + org.gcube.common + metadata-profile-discovery + [0.0.1, 1.0.0-SNAPSHOT) + + + org.gcube.portlets.user + gcube-widgets + compile + + + org.gcube.dvos + usermanagement-core + provided + + + org.gcube.portal + custom-portal-handler + provided + + + org.gcube.common.portal + portal-manager + provided + + + + com.liferay.portal + portal-service + provided + + + javax.portlet + portlet-api + provided + + + + org.slf4j + slf4j-log4j12 + provided + + + org.slf4j + slf4j-api + provided + + + junit + junit + 4.11 + test + + + + + + ${webappDirectory}/WEB-INF/classes + + + + + + org.codehaus.mojo + gwt-maven-plugin + ${gwtVersion} + + + + compile + + + + + + GeoPortalDataEntryApp.html + ${webappDirectory} + + + + + org.apache.maven.plugins + maven-war-plugin + + + compile + + exploded + + + + + ${webappDirectory} + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.apache.maven.plugins + maven-assembly-plugin + + + descriptor.xml + + + + + servicearchive + install + + single + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.5 + + + copy-profile + install + + copy-resources + + + target + + + + ${project.basedir} + true + + profile.xml + + + + + + + + + + + diff --git a/profile.xml b/profile.xml new file mode 100644 index 0000000..27ebd5a --- /dev/null +++ b/profile.xml @@ -0,0 +1,25 @@ + + + + Portlet + + ${project.description} + PortletsUser + ${project.artifactId} + 1.0.0 + + + ${project.artifactId} + ${project.description} + + ${project.groupId} + ${project.artifactId} + ${project.version} + + + ${project.build.finalName}.${project.packaging} + + + + + diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml b/src/main/java/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml new file mode 100644 index 0000000..1f291f1 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoPortalDataEntryApp.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoPortalDataEntryApp.java new file mode 100644 index 0000000..3bedcd1 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GeoPortalDataEntryApp.java @@ -0,0 +1,150 @@ +package org.gcube.portlets.user.geoportaldataentry.client; + +import org.gcube.portlets.user.geoportaldataentry.shared.FieldVerifier; + +import com.google.gwt.core.client.EntryPoint; +import com.google.gwt.core.client.GWT; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.event.dom.client.KeyUpEvent; +import com.google.gwt.event.dom.client.KeyUpHandler; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.TextBox; +import com.google.gwt.user.client.ui.VerticalPanel; + +/** + * Entry point classes define onModuleLoad(). + */ +public class GeoPortalDataEntryApp implements EntryPoint { + /** + * The message displayed to the user when the server cannot be reached or + * returns an error. + */ + private static final String SERVER_ERROR = "An error occurred while " + + "attempting to contact the server. Please check your network " + + "connection and try again."; + + /** + * Create a remote service proxy to talk to the server-side Greeting service. + */ + private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class); + + private final Messages messages = GWT.create(Messages.class); + + /** + * This is the entry point method. + */ + public void onModuleLoad() { + final Button sendButton = new Button( messages.sendButton() ); + final TextBox nameField = new TextBox(); + nameField.setText( messages.nameField() ); + final Label errorLabel = new Label(); + + // We can add style names to widgets + sendButton.addStyleName("sendButton"); + + // Add the nameField and sendButton to the RootPanel + // Use RootPanel.get() to get the entire body element + RootPanel.get("nameFieldContainer").add(nameField); + RootPanel.get("sendButtonContainer").add(sendButton); + RootPanel.get("errorLabelContainer").add(errorLabel); + + // Focus the cursor on the name field when the app loads + nameField.setFocus(true); + nameField.selectAll(); + + // Create the popup dialog box + final DialogBox dialogBox = new DialogBox(); + dialogBox.setText("Remote Procedure Call"); + dialogBox.setAnimationEnabled(true); + final Button closeButton = new Button("Close"); + // We can set the id of a widget by accessing its Element + closeButton.getElement().setId("closeButton"); + final Label textToServerLabel = new Label(); + final HTML serverResponseLabel = new HTML(); + VerticalPanel dialogVPanel = new VerticalPanel(); + dialogVPanel.addStyleName("dialogVPanel"); + dialogVPanel.add(new HTML("Sending name to the server:")); + dialogVPanel.add(textToServerLabel); + dialogVPanel.add(new HTML("
Server replies:")); + dialogVPanel.add(serverResponseLabel); + dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT); + dialogVPanel.add(closeButton); + dialogBox.setWidget(dialogVPanel); + + // Add a handler to close the DialogBox + closeButton.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + dialogBox.hide(); + sendButton.setEnabled(true); + sendButton.setFocus(true); + } + }); + + // Create a handler for the sendButton and nameField + class MyHandler implements ClickHandler, KeyUpHandler { + /** + * Fired when the user clicks on the sendButton. + */ + public void onClick(ClickEvent event) { + sendNameToServer(); + } + + /** + * Fired when the user types in the nameField. + */ + public void onKeyUp(KeyUpEvent event) { + if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { + sendNameToServer(); + } + } + + /** + * Send the name from the nameField to the server and wait for a response. + */ + private void sendNameToServer() { + // First, we validate the input. + errorLabel.setText(""); + String textToServer = nameField.getText(); + if (!FieldVerifier.isValidName(textToServer)) { + errorLabel.setText("Please enter at least four characters"); + return; + } + + // Then, we send the input to the server. + sendButton.setEnabled(false); + textToServerLabel.setText(textToServer); + serverResponseLabel.setText(""); + greetingService.greetServer(textToServer, new AsyncCallback() { + public void onFailure(Throwable caught) { + // Show the RPC error message to the user + dialogBox.setText("Remote Procedure Call - Failure"); + serverResponseLabel.addStyleName("serverResponseLabelError"); + serverResponseLabel.setHTML(SERVER_ERROR); + dialogBox.center(); + closeButton.setFocus(true); + } + + public void onSuccess(String result) { + dialogBox.setText("Remote Procedure Call"); + serverResponseLabel.removeStyleName("serverResponseLabelError"); + serverResponseLabel.setHTML(result); + dialogBox.center(); + closeButton.setFocus(true); + } + }); + } + } + + // Add a handler to send the name to the server + MyHandler handler = new MyHandler(); + sendButton.addClickHandler(handler); + nameField.addKeyUpHandler(handler); + } +} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GreetingService.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GreetingService.java new file mode 100644 index 0000000..d180c24 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GreetingService.java @@ -0,0 +1,12 @@ +package org.gcube.portlets.user.geoportaldataentry.client; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +/** + * The client side stub for the RPC service. + */ +@RemoteServiceRelativePath("greet") +public interface GreetingService extends RemoteService { + String greetServer(String name) throws IllegalArgumentException; +} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GreetingServiceAsync.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GreetingServiceAsync.java new file mode 100644 index 0000000..b249913 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/GreetingServiceAsync.java @@ -0,0 +1,37 @@ +package org.gcube.portlets.user.geoportaldataentry.client; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.rpc.AsyncCallback; + +public interface GreetingServiceAsync +{ + + /** + * GWT-RPC service asynchronous (client-side) interface + * @see org.gcube.portlets.user.geoportaldataentry.client.GreetingService + */ + void greetServer( java.lang.String name, AsyncCallback callback ); + + + /** + * Utility class to get the RPC Async interface from client-side code + */ + public static final class Util + { + private static GreetingServiceAsync instance; + + public static final GreetingServiceAsync getInstance() + { + if ( instance == null ) + { + instance = (GreetingServiceAsync) GWT.create( GreetingService.class ); + } + return instance; + } + + private Util() + { + // Utility class should not be instantiated + } + } +} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/Messages.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/Messages.java new file mode 100644 index 0000000..51bd2d4 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/client/Messages.java @@ -0,0 +1,13 @@ +package org.gcube.portlets.user.geoportaldataentry.client; + +import com.google.gwt.i18n.client.LocalizableResource.Generate; + +@Generate(format = "com.google.gwt.i18n.server.PropertyCatalogFactory") +public interface Messages extends com.google.gwt.i18n.client.Messages { + + @DefaultMessage("Enter your name") + String nameField(); + + @DefaultMessage("Send") + String sendButton(); +} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/GreetingServiceImpl.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/GreetingServiceImpl.java new file mode 100644 index 0000000..e13a9c6 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/server/GreetingServiceImpl.java @@ -0,0 +1,49 @@ +package org.gcube.portlets.user.geoportaldataentry.server; + +import org.gcube.portlets.user.geoportaldataentry.client.GreetingService; +import org.gcube.portlets.user.geoportaldataentry.shared.FieldVerifier; + +import com.google.gwt.user.server.rpc.RemoteServiceServlet; + +/** + * The server side implementation of the RPC service. + */ +@SuppressWarnings("serial") +public class GreetingServiceImpl extends RemoteServiceServlet implements + GreetingService { + + public String greetServer(String input) throws IllegalArgumentException { + // Verify that the input is valid. + if (!FieldVerifier.isValidName(input)) { + // If the input is not valid, throw an IllegalArgumentException back to + // the client. + throw new IllegalArgumentException( + "Name must be at least 4 characters long"); + } + + String serverInfo = getServletContext().getServerInfo(); + String userAgent = getThreadLocalRequest().getHeader("User-Agent"); + + // Escape data from the client to avoid cross-site script vulnerabilities. + input = escapeHtml(input); + userAgent = escapeHtml(userAgent); + + return "Hello, " + input + "!

I am running " + serverInfo + + ".

It looks like you are using:
" + userAgent; + } + + /** + * Escape an html string. Escaping data received from the client helps to + * prevent cross-site script vulnerabilities. + * + * @param html the html string to escape + * @return the escaped string + */ + private String escapeHtml(String html) { + if (html == null) { + return null; + } + return html.replaceAll("&", "&").replaceAll("<", "<").replaceAll( + ">", ">"); + } +} diff --git a/src/main/java/org/gcube/portlets/user/geoportaldataentry/shared/FieldVerifier.java b/src/main/java/org/gcube/portlets/user/geoportaldataentry/shared/FieldVerifier.java new file mode 100644 index 0000000..ef1ed3c --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/geoportaldataentry/shared/FieldVerifier.java @@ -0,0 +1,42 @@ +package org.gcube.portlets.user.geoportaldataentry.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/resources/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml b/src/main/resources/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml new file mode 100644 index 0000000..1f291f1 --- /dev/null +++ b/src/main/resources/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryApp.gwt.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/org/gcube/portlets/user/geoportaldataentry/client/Messages_fr.properties b/src/main/resources/org/gcube/portlets/user/geoportaldataentry/client/Messages_fr.properties new file mode 100644 index 0000000..b4a7627 --- /dev/null +++ b/src/main/resources/org/gcube/portlets/user/geoportaldataentry/client/Messages_fr.properties @@ -0,0 +1,2 @@ +sendButton = Envoyer +nameField = Entrez votre nom \ No newline at end of file diff --git a/src/main/webapp/GeoPortalDataEntryApp.css b/src/main/webapp/GeoPortalDataEntryApp.css new file mode 100644 index 0000000..7aca7ac --- /dev/null +++ b/src/main/webapp/GeoPortalDataEntryApp.css @@ -0,0 +1,34 @@ +/** Add css rules here for your application. */ + + +/** Example rules used by the template application (remove for your app) */ +h1 { + font-size: 2em; + font-weight: bold; + color: #777777; + margin: 40px 0px 70px; + text-align: center; +} + +.sendButton { + display: block; + font-size: 16pt; +} + +/** Most GWT widgets already have a style name defined */ +.gwt-DialogBox { + width: 400px; +} + +.dialogVPanel { + margin: 5px; +} + +.serverResponseLabelError { + color: red; +} + +/** Set ids using widget.getElement().setId("idOfElement") */ +#closeButton { + margin: 15px 6px 6px; +} diff --git a/src/main/webapp/GeoPortalDataEntryApp.html b/src/main/webapp/GeoPortalDataEntryApp.html new file mode 100644 index 0000000..c69ee13 --- /dev/null +++ b/src/main/webapp/GeoPortalDataEntryApp.html @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + Web Application Starter Project + + + + + + + + + + + + + + + + + + + + + + +

Web Application Starter Project

+ + + + + + + + + + + + +
Please enter your name:
+ + diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..edb7928 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,24 @@ + + + + + + + + greetServlet + org.gcube.portlets.user.geoportaldataentry.server.GreetingServiceImpl + + + + greetServlet + /GeoPortalDataEntryApp/greet + + + + + GeoPortalDataEntryApp.html + + + diff --git a/src/test/java/org/gcube/portlets/user/geoportaldataentry/client/GwtTestGeoPortalDataEntryApp.java b/src/test/java/org/gcube/portlets/user/geoportaldataentry/client/GwtTestGeoPortalDataEntryApp.java new file mode 100644 index 0000000..fdded9b --- /dev/null +++ b/src/test/java/org/gcube/portlets/user/geoportaldataentry/client/GwtTestGeoPortalDataEntryApp.java @@ -0,0 +1,75 @@ +package org.gcube.portlets.user.geoportaldataentry.client; + +import org.gcube.portlets.user.geoportaldataentry.shared.FieldVerifier; +import com.google.gwt.core.client.GWT; +import com.google.gwt.junit.client.GWTTestCase; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.rpc.ServiceDefTarget; + +/** + * GWT JUnit integration tests must extend GWTTestCase. + * Using "GwtTest*" naming pattern exclude them from running with + * surefire during the test phase. + * + * If you run the tests using the Maven command line, you will have to + * navigate with your browser to a specific url given by Maven. + * See https://gwt-maven-plugin.github.io/gwt-maven-plugin/user-guide/testing.html + * for details. + */ +public class GwtTestGeoPortalDataEntryApp extends GWTTestCase { + + /** + * Must refer to a valid module that sources this class. + */ + public String getModuleName() { + return "org.gcube.portlets.user.geoportaldataentry.GeoPortalDataEntryAppJUnit"; + } + + /** + * Tests the FieldVerifier. + */ + public void testFieldVerifier() { + assertFalse(FieldVerifier.isValidName(null)); + assertFalse(FieldVerifier.isValidName("")); + assertFalse(FieldVerifier.isValidName("a")); + assertFalse(FieldVerifier.isValidName("ab")); + assertFalse(FieldVerifier.isValidName("abc")); + assertTrue(FieldVerifier.isValidName("abcd")); + } + + /** + * This test will send a request to the server using the greetServer method in + * GreetingService and verify the response. + */ + public void testGreetingService() { + // Create the service that we will test. + GreetingServiceAsync greetingService = GWT.create(GreetingService.class); + ServiceDefTarget target = (ServiceDefTarget) greetingService; + target.setServiceEntryPoint(GWT.getModuleBaseURL() + "GeoPortalDataEntryApp/greet"); + + // Since RPC calls are asynchronous, we will need to wait for a response + // after this test method returns. This line tells the test runner to wait + // up to 10 seconds before timing out. + delayTestFinish(10000); + + // Send a request to the server. + greetingService.greetServer("GWT User", new AsyncCallback() { + public void onFailure(Throwable caught) { + // The request resulted in an unexpected error. + fail("Request failure: " + caught.getMessage()); + } + + public void onSuccess(String result) { + // Verify that the response is correct. + assertTrue(result.startsWith("Hello, GWT User!")); + + // Now that we have received a response, we need to tell the test runner + // that the test is complete. You must call finishTest() after an + // asynchronous test finishes successfully, or the test will time out. + finishTest(); + } + }); + } + + +} diff --git a/src/test/resources/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryAppJUnit.gwt.xml b/src/test/resources/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryAppJUnit.gwt.xml new file mode 100644 index 0000000..3b3e30f --- /dev/null +++ b/src/test/resources/org/gcube/portlets/user/geoportaldataentry/GeoPortalDataEntryAppJUnit.gwt.xml @@ -0,0 +1,9 @@ + + + + + + + + +