[m-rev.] for review: add app engine sample

Ian MacLarty maclarty at csse.unimelb.edu.au
Fri Jul 8 14:17:32 AEST 2011


For post-commit review by Julien.

Estimated hours taken: 2
Branches: main

Add a simple Google App Engine sample (requested by Julien).
The sample implements a servlet that handles HTTP GET
requests by printing a message.

samples/README:
    Mention the new sample.

samples/appengine/Makefile:
    Rules to build, run and deploy the sample.

samples/appengine/README:
    Describe how to use the sample.

samples/appengine/servlet.m:
    The servlet implementation.

samples/appengine/war/WEB-INF/appengine-web.xml:
    App config file.

samples/appengine/war/WEB-INF/web.xml:
    Deployment descriptor.

Index: samples/README
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/README,v
retrieving revision 1.12
diff -u -r1.12 README
--- samples/README	7 Jan 2011 16:45:20 -0000	1.12
+++ samples/README	8 Jul 2011 04:03:22 -0000
@@ -50,6 +50,8 @@
 There are also some sub-directories which contain examples of multi-module
 Mercury programs:
 
+appengine               A simple Google App Engine servlet.
+
 diff                    This directory contains an implementation of a
 			simple version of the standard UNIX utility
 			`diff', which prints the differences between
Index: samples/appengine/Makefile
===================================================================
RCS file: samples/appengine/Makefile
diff -N samples/appengine/Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ samples/appengine/Makefile	8 Jul 2011 04:04:19 -0000
@@ -0,0 +1,26 @@
+MMC_DIR=$(shell dirname `which mmc`)
+MMC_JARS_DIR=$(MMC_DIR)/../lib/mercury/lib/java
+WEBINF=war/WEB-INF
+
+.PHONY: servlet.jar
+servlet.jar: wardirs
+	mmc --grade java --make libservlet
+	mv servlet.jar $(WEBINF)/lib/
+
+.PHONY: wardirs
+wardirs:
+	mkdir -p $(WEBINF)/lib
+	mkdir -p $(WEBINF)/classes
+
+.PHONY: install_mer_jars
+install_mer_jars: wardirs
+	cp $(MMC_JARS_DIR)/mer_std.jar $(WEBINF)/lib/
+	cp $(MMC_JARS_DIR)/mer_rt.jar $(WEBINF)/lib/
+
+.PHONY: run
+run: install_mer_jars servlet.jar
+	dev_appserver.sh war
+
+.PHONY: deploy
+deploy: install_mer_jars servlet.jar
+	appcfg.sh update war
Index: samples/appengine/README
===================================================================
RCS file: samples/appengine/README
diff -N samples/appengine/README
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ samples/appengine/README	8 Jul 2011 04:03:22 -0000
@@ -0,0 +1,35 @@
+This is a very simple demo of how to deploy Mercury code to Google App Engine
+using the Java backend.
+
+The code should also work with any other servlet container.
+
+The file servlet.m contains a simple request handler written in Mercury.  It
+also contains some Java foreign code that defines a subclass of
+javax.servlet.http.HttpServlet.
+
+To run this sample, first download the Google App Engine SDK from
+http://code.google.com/appengine/.
+
+After unzipping the SDK, add the file lib/shared/servlet-api.jar to your
+CLASSPATH.  Also add the SDK's bin directory to your PATH.
+
+Make sure you have a recent Mercury compiler with the java grade installed and
+that mmc is in your PATH.
+
+To build the servlet do:
+    
+    make
+
+To run the servlet locally do:
+
+    make run
+
+Then point your browser to http://localhost:8080/.
+
+To deploy the servlet to Google App Engine, first edit the file
+war/WEB-INF/appengine-web.xml and change the application id one you've created.
+You can create a new application at https://appengine.google.com/.  Then do:
+
+    make deploy
+
+The sample is currently deployed to http://imlmertest.appspot.com/.
Index: samples/appengine/servlet.m
===================================================================
RCS file: samples/appengine/servlet.m
diff -N samples/appengine/servlet.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ samples/appengine/servlet.m	8 Jul 2011 04:07:03 -0000
@@ -0,0 +1,88 @@
+% A sample Mercury servlet.
+:- module servlet.
+
+:- interface.
+
+:- import_module io.
+
+:- type request.
+:- type response.
+
+:- pred handle_get(request::in, response::in, io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module list.
+:- import_module string.
+
+handle_get(Request, Response, !IO) :-
+    get_request_uri(Request, URI, !IO),
+    set_content_type(Response, "text/html", !IO),
+    Msg = string.append_list([
+        "<html>\n",
+        "<head>\n",
+        "<title>Mercury App Engine Sample</title>\n",
+        "</head>\n",
+        "<body>\n",
+        "<h2>You requested the URL: ", URI, "</h2>\n",
+        "</body>\n",
+        "</html>\n"]),
+    write_response(Response, Msg, !IO).
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_decl("Java", "
+import java.io.IOException;
+import javax.servlet.http.*;
+").
+
+:- pragma foreign_code("Java", "
+public static class Servlet extends HttpServlet {
+    public void doGet(HttpServletRequest req, HttpServletResponse resp)
+            throws IOException {
+        jmercury.servlet.handle_get(req, resp);
+    }
+}
+").
+
+:- pragma foreign_export("Java", handle_get(in, in, di, uo), "handle_get").
+
+:- pragma foreign_type("Java", request,
+    "javax.servlet.http.HttpServletRequest").
+
+:- pragma foreign_type("Java", response,
+    "javax.servlet.http.HttpServletResponse").
+
+:- pred write_response(response::in, string::in, io::di, io::uo) is det.
+
+:- pragma foreign_proc("Java",
+    write_response(Response::in, Str::in, _IO0::di, _IO::uo),
+    [promise_pure, will_not_call_mercury],
+"
+    try {
+        Response.getWriter().print(Str);
+    }
+    catch (Exception e) {
+        throw new RuntimeException(e);
+    }
+").
+
+:- pred set_content_type(response::in, string::in, io::di, io::uo) is det.
+
+:- pragma foreign_proc("Java",
+    set_content_type(Response::in, ContentType::in, _IO0::di, _IO::uo),
+    [promise_pure, will_not_call_mercury],
+"
+    Response.setContentType(ContentType);
+").
+
+:- pred get_request_uri(request::in, string::out, io::di, io::uo) is det.
+
+:- pragma foreign_proc("Java",
+    get_request_uri(Request::in, URI::out, _IO0::di, _IO::uo),
+    [promise_pure, will_not_call_mercury],
+"
+    URI = Request.getRequestURI();
+").
+
+:- end_module servlet.
Index: samples/appengine/war/WEB-INF/appengine-web.xml
===================================================================
RCS file: samples/appengine/war/WEB-INF/appengine-web.xml
diff -N samples/appengine/war/WEB-INF/appengine-web.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ samples/appengine/war/WEB-INF/appengine-web.xml	8 Jul 2011 04:03:22 -0000
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
+  <application>imlmertest</application>
+  <version>1</version>
+</appengine-web-app>
Index: samples/appengine/war/WEB-INF/web.xml
===================================================================
RCS file: samples/appengine/war/WEB-INF/web.xml
diff -N samples/appengine/war/WEB-INF/web.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ samples/appengine/war/WEB-INF/web.xml	8 Jul 2011 04:03:22 -0000
@@ -0,0 +1,10 @@
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
+    <servlet>
+        <servlet-name>merservlet</servlet-name>
+        <servlet-class>jmercury.servlet$Servlet</servlet-class>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>merservlet</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+</web-app>
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list