CMSC 433, Spring 2006

Programming Language Technologies and Paradigms

Project 1


Due February 13th, 2006, 6pm

Notes and Updates:


The API documentation contains most of the details for this project. Here you will find a general overview.

For this project, you will write a simple web server in Java. Your web sever will execute Servlets that create web pages on-the-fly. When users connect to your web server, they will indicate which Servlet(s) to run as part of the URL. Your web server will create and invoke those Servlet(s) and produce a response.

There are several tasks to complete for this project, all described below in this writeup:

  1. Write a simple (web) server to accept requests on a port and process those requests
  2. Write a Servlet factory class to "manage" Servlets
  3. Create a GoogleQuery Servlet
  4. Create a Browse Servlet
  5. Create a Cache Servlet decorator
You may find it useful to read some background on how web servers work. As you read through the writeup below, you find it helpful to refer to the following class diagram, to understand how the pieces fit together.

WebServer

For this project, you will write a web server that listens on a particular port and produces a response. Your web server will be invoked from the command line. Because we may have multiple students running on the same machine, we can't have everyone using port 80 for their web server. So to avoid any conflicts, your web server should listen on port 33xxx, where xxx is the last three digits of your class account number. For example, if your account is cs433014, your server should listen on port 33014. Your WebServer should also accept an override port as a command-line argument, e.g.

java WebServer 44014

The WebServer class that we have provided is currently implemented to echo back the received HTTP command. You will have to change this to invoke Servlets instead, as described more below. Please refer to the API documentation for the WebServer's runWebServer method for details on the HTTP request format. As an example, given the following HTTP request

  GET /MyServlet/A/Path?Option1+Option2 HTTP/1.0
Invoking findRequestURL will return
  /MyServlet/A/Path?Option1+Option2
and with this example URL, MyServlet is the servlet name, A/Path is the path, and Option1+Option2 is the option.

One subtlety is that the option argument to a Servlet's doGet method must be decoded using the java.net.URLDecoder.decode method found in the Java API. Further details can be found in the API documentation for the Servlet interface.

ServletFactory

After parsing the HTTP request, your web server will obtain an instance of the appropriate Servlet from the ServletFactory class -- specifically by invoking the getServlet method with the servlet name as an argument. The ServletFactory should implement the Singleton design pattern. In particular, the constructor of the factory should be private, and the static method getInstance should be invoked to return an instance of of ServletFactory. Every time this method is called, it should return the same instance (i.e., it shouldn't create a new instance with each call).

The ServletFactory class manages Servlet creation so that every unique servlet name has one and only one instance ever created for it. So if a client requests the servlet HelloWorld twice, the first time ServletFactory will create a new instance, but the second time ServletFactory should return the same instance it created before. Be careful: Cache:Browse and Cache:Cache:Browse are two different servlets.

Servlets

Your web server will invoke the doGet method (see the Servlet interface) of the Servlet it receives from the ServletFactory to create a web page on-the-fly. Some Servlets, e.g. HelloWorld and Quit are provided for you.

You must implement three new Servlets:

StudentTests

The PublicTests we have provided are written using JUnit. This can be executed easily from within Eclipse to test your classes.

You must also write test cases to turn in as part of your project. These should be stored in the class StudentTests, whose skeleton we have provided. You should write tests that exercise the functionality not already covered by the PublicTests. The aim is for you to get used to writing formal test cases when you program.

To evaluate the quality of your test cases, we will use the Clover code coverage tool. The higher the coverage of your test cases, the better your grade. In particular, the points awarded on the submit server for Public and Release tests total to 96 points. The remaining 4 points are assigned based on code coverage and quality of the unit tests that you provide in StudentTests.

FindBugs

This project employs annotations, a new Java 5.0 feature (see the file package-info.java). These annotations instruct FindBugs to check that all method arguments for the cmsc433.p1 package are non-null. As such, you must develop this project with Java 5.0.

Valid HTML 4.01!