commit 13011b536ae947f164846282ea098a937d298b0a Author: Michael Mandl Date: Tue Dec 15 12:52:47 2015 +0100 Initial (generated) project diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..a77e904 --- /dev/null +++ b/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..751bd89 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/test-classes/ diff --git a/.project b/.project new file mode 100644 index 0000000..131e0f2 --- /dev/null +++ b/.project @@ -0,0 +1,34 @@ + + + FotoStream + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.google.gdt.eclipse.core.webAppProjectValidator + + + + + com.google.gwt.eclipse.core.gwtProjectValidator + + + + + + org.eclipse.jdt.core.javanature + com.google.gwt.eclipse.core.gwtNature + org.eclipse.wst.common.project.facet.core.nature + + diff --git a/.settings/com.google.gdt.eclipse.core.prefs b/.settings/com.google.gdt.eclipse.core.prefs new file mode 100644 index 0000000..cc6cb35 --- /dev/null +++ b/.settings/com.google.gdt.eclipse.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +warSrcDir=war +warSrcDirIsOutput=true diff --git a/.settings/com.google.gwt.eclipse.core.prefs b/.settings/com.google.gwt.eclipse.core.prefs new file mode 100644 index 0000000..077314c --- /dev/null +++ b/.settings/com.google.gwt.eclipse.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +filesCopiedToWebInfLib=gwt-servlet.jar diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..0c68a61 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +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.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 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..f4ef8aa --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ + + + + diff --git a/src/net/molez/mandlm/fotostream/FotoStream.gwt.xml b/src/net/molez/mandlm/fotostream/FotoStream.gwt.xml new file mode 100644 index 0000000..2fa540a --- /dev/null +++ b/src/net/molez/mandlm/fotostream/FotoStream.gwt.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/net/molez/mandlm/fotostream/client/FotoStream.java b/src/net/molez/mandlm/fotostream/client/FotoStream.java new file mode 100644 index 0000000..2bc237e --- /dev/null +++ b/src/net/molez/mandlm/fotostream/client/FotoStream.java @@ -0,0 +1,146 @@ +package net.molez.mandlm.fotostream.client; + +import net.molez.mandlm.fotostream.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 FotoStream 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); + + /** + * This is the entry point method. + */ + public void onModuleLoad() { + final Button sendButton = new Button("Send"); + final TextBox nameField = new TextBox(); + nameField.setText("GWT User"); + 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/net/molez/mandlm/fotostream/client/GreetingService.java b/src/net/molez/mandlm/fotostream/client/GreetingService.java new file mode 100644 index 0000000..efce9e8 --- /dev/null +++ b/src/net/molez/mandlm/fotostream/client/GreetingService.java @@ -0,0 +1,12 @@ +package net.molez.mandlm.fotostream.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/net/molez/mandlm/fotostream/client/GreetingServiceAsync.java b/src/net/molez/mandlm/fotostream/client/GreetingServiceAsync.java new file mode 100644 index 0000000..357a190 --- /dev/null +++ b/src/net/molez/mandlm/fotostream/client/GreetingServiceAsync.java @@ -0,0 +1,10 @@ +package net.molez.mandlm.fotostream.client; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +/** + * The async counterpart of GreetingService. + */ +public interface GreetingServiceAsync { + void greetServer(String input, AsyncCallback callback) throws IllegalArgumentException; +} diff --git a/src/net/molez/mandlm/fotostream/server/GreetingServiceImpl.java b/src/net/molez/mandlm/fotostream/server/GreetingServiceImpl.java new file mode 100644 index 0000000..a06279d --- /dev/null +++ b/src/net/molez/mandlm/fotostream/server/GreetingServiceImpl.java @@ -0,0 +1,45 @@ +package net.molez.mandlm.fotostream.server; + +import net.molez.mandlm.fotostream.client.GreetingService; +import net.molez.mandlm.fotostream.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/net/molez/mandlm/fotostream/shared/FieldVerifier.java b/src/net/molez/mandlm/fotostream/shared/FieldVerifier.java new file mode 100644 index 0000000..2a84d17 --- /dev/null +++ b/src/net/molez/mandlm/fotostream/shared/FieldVerifier.java @@ -0,0 +1,42 @@ +package net.molez.mandlm.fotostream.shared; + +/** + *

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

+ *

+ * This class is in the shared package 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 not 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/war/FotoStream.css b/war/FotoStream.css new file mode 100644 index 0000000..7aca7ac --- /dev/null +++ b/war/FotoStream.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/war/FotoStream.html b/war/FotoStream.html new file mode 100644 index 0000000..3924eba --- /dev/null +++ b/war/FotoStream.html @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + Web Application Starter Project + + + + + + + + + + + + + + + + + + + + + + +

Web Application Starter Project

+ + + + + + + + + + + + +
Please enter your name:
+ + diff --git a/war/WEB-INF/.gitignore b/war/WEB-INF/.gitignore new file mode 100644 index 0000000..840e7d3 --- /dev/null +++ b/war/WEB-INF/.gitignore @@ -0,0 +1 @@ +/classes/ diff --git a/war/WEB-INF/lib/gwt-servlet.jar b/war/WEB-INF/lib/gwt-servlet.jar new file mode 100644 index 0000000..2e85a1a Binary files /dev/null and b/war/WEB-INF/lib/gwt-servlet.jar differ diff --git a/war/WEB-INF/web.xml b/war/WEB-INF/web.xml new file mode 100644 index 0000000..1cc5293 --- /dev/null +++ b/war/WEB-INF/web.xml @@ -0,0 +1,24 @@ + + + + + + greetServlet + net.molez.mandlm.fotostream.server.GreetingServiceImpl + + + + greetServlet + /fotostream/greet + + + + + FotoStream.html + + + diff --git a/war/favicon.ico b/war/favicon.ico new file mode 100644 index 0000000..858a707 Binary files /dev/null and b/war/favicon.ico differ