aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/uk/org/ury/client/Client.java2
-rw-r--r--src/uk/org/ury/library/LibraryRequestHandler.java279
-rw-r--r--src/uk/org/ury/library/viewer/LibraryViewer.java2
-rw-r--r--src/uk/org/ury/server/AbstractRequestHandler.java254
-rw-r--r--src/uk/org/ury/server/HttpHandler.java154
-rw-r--r--src/uk/org/ury/server/HttpListenerThread.java38
-rw-r--r--src/uk/org/ury/server/RequestHandler.java43
-rw-r--r--src/uk/org/ury/server/ServerProtocol.java37
-rw-r--r--src/uk/org/ury/server/exceptions/UnknownFunctionException.java37
-rw-r--r--src/uk/org/ury/server/protocol/DecodeFailureException.java31
-rw-r--r--src/uk/org/ury/server/protocol/Directive.java18
-rw-r--r--src/uk/org/ury/server/protocol/ProtocolUtils.java67
-rw-r--r--src/uk/org/ury/server/protocol/Status.java17
13 files changed, 481 insertions, 498 deletions
diff --git a/src/uk/org/ury/client/Client.java b/src/uk/org/ury/client/Client.java
index 69a095a..5b8be62 100644
--- a/src/uk/org/ury/client/Client.java
+++ b/src/uk/org/ury/client/Client.java
@@ -22,10 +22,10 @@ public class Client {
* server.
*
* @return The response from the server, as a key-value map.
+ *
* @throws DecodeFailureException
* if the decode failed.
*/
-
public Map<?, ?> get(String file) throws DecodeFailureException {
URL url = null;
URLConnection uc = null;
diff --git a/src/uk/org/ury/library/LibraryRequestHandler.java b/src/uk/org/ury/library/LibraryRequestHandler.java
index 1c4ad96..a81851d 100644
--- a/src/uk/org/ury/library/LibraryRequestHandler.java
+++ b/src/uk/org/ury/library/LibraryRequestHandler.java
@@ -3,11 +3,21 @@
*/
package uk.org.ury.library;
+import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.protocol.HttpContext;
+import org.json.simple.JSONValue;
+
import uk.org.ury.database.DatabaseDriver;
import uk.org.ury.database.UserClass;
import uk.org.ury.database.exceptions.ConnectionFailureException;
@@ -16,132 +26,163 @@ import uk.org.ury.database.exceptions.QueryFailureException;
import uk.org.ury.library.exceptions.EmptySearchException;
import uk.org.ury.library.item.LibraryItem;
import uk.org.ury.protocol.Directive;
+import uk.org.ury.protocol.Status;
+import uk.org.ury.server.AbstractRequestHandler;
import uk.org.ury.server.Server;
-import uk.org.ury.server.ApiRequestHandler;
+import uk.org.ury.server.exceptions.BadRequestException;
import uk.org.ury.server.exceptions.HandleFailureException;
-
+import uk.org.ury.server.exceptions.HandlerNotFoundException;
+import uk.org.ury.server.exceptions.HandlerSetupFailureException;
+import uk.org.ury.server.exceptions.NotAHandlerException;
+import uk.org.ury.server.exceptions.UnknownFunctionException;
/**
* A request handler for library queries.
*
* @author Matt Windsor
*/
+public class LibraryRequestHandler extends AbstractRequestHandler {
+ /**
+ * Construct a new LibraryRequestHandler.
+ *
+ * @param server
+ * The instance of the URY server responsible for the request.
+ *
+ * @param mount
+ * The directory to which this handler is to be mounted.
+ */
+ public LibraryRequestHandler(Server server, String mount) {
+ super(server, mount);
+ }
+
+ /**
+ * Perform a library search, populating the response list.
+ *
+ * @param parameters
+ * A key-value map of parameters supplied with the server
+ * request. Typically, the function parameter will detail the
+ * function that the request handler is expected to perform.
+ *
+ * @param response
+ * The response list to populate.
+ *
+ * @param server
+ * The server providing database resources.
+ *
+ * @throws HandleFailureException
+ * if an error occurs that thwarts the handling of the request.
+ */
+
+ private void doSearch(Map<String, String> parameters,
+ Map<String, Object> response, Server server)
+ throws HandleFailureException {
+ if (parameters.containsKey("search") == false)
+ throw new HandleFailureException("Search term is missing.");
+ else if (parameters.get("search") == null)
+ throw new HandleFailureException("Search term is null.");
+
+ String search = parameters.get("search");
+ DatabaseDriver dd = null;
+
+ try {
+ dd = server.getDatabaseConnection(UserClass.READ_ONLY);
+ } catch (MissingCredentialsException e) {
+ throw new HandleFailureException(e.getMessage());
+ } catch (ConnectionFailureException e) {
+ throw new HandleFailureException(e.getMessage());
+ }
+
+ try {
+ List<Map<String, String>> itemArray = new ArrayList<Map<String, String>>();
+
+ for (LibraryItem li : LibraryUtils.search(dd, search)) {
+ itemArray.add(li.asResponse());
+ }
+
+ response.put(Directive.ITEMS.toString(), itemArray);
+ } catch (QueryFailureException e) {
+ throw new HandleFailureException(e.getMessage());
+ } catch (EmptySearchException e) {
+ throw new HandleFailureException(e.getMessage());
+ }
+ }
+
+ /**
+ * Handle a HTTP GET request.
+ *
+ * @param request
+ * The HTTP request.
+ *
+ * @param response
+ * The response that the handler will populate during the
+ * handling of the request.
+ *
+ * @param context
+ * The HTTP context.
+ *
+ * @throws HandlerNotFoundException
+ * if the client requested a request handler that could not be
+ * found on the class path.
+ *
+ * @throws HandlerSetupFailureException
+ * if the handler was found but could not be set up (eg does not
+ * implement appropriate interface or cannot be instantiated).
+ *
+ * @throws HandleFailureException
+ * if an appropriate handler was contacted, but it failed to
+ * process the request.
+ *
+ * @throws BadRequestException
+ * if the request was malformed or invalid.
+ *
+ * @throws NotAHandlerException
+ * if the class requested to handle the request is not a
+ * handler.
+ *
+ * @throws UnknownFunctionException
+ * if the request is for a path that does not correspond to one
+ * of this handler's functions.
+ */
+ @Override
+ public void handleGet(HttpRequest request, HttpResponse response,
+ HttpContext context) throws HandlerNotFoundException,
+ HandlerSetupFailureException, HandleFailureException,
+ BadRequestException, NotAHandlerException, UnknownFunctionException {
+ String path;
+ String uri = request.getRequestLine().getUri();
+ String query = getQueryString(uri);
+
+ if (query == null)
+ path = uri.toLowerCase(Locale.ENGLISH);
+ else
+ path = uri.split("\\?" + query)[0].toLowerCase(Locale.ENGLISH);
+
+ Map<String, Object> content = new HashMap<String, Object>();
+
+ if (path.equals("/library/tracks")) {
+ try {
+ doSearch(parseQueryString(query), content, server);
+ } catch (UnsupportedEncodingException e) {
+ throw new HandleFailureException(e.getMessage());
+ }
+ } else {
+ throw new UnknownFunctionException(path);
+ }
+
+ response.setStatusLine(request.getProtocolVersion(), HttpStatus.SC_OK,
+ "OK");
+
+ content.put(Directive.STATUS.toString(), Status.OK.toString());
+
+ StringEntity entity = null;
+
+ try {
+ entity = new StringEntity(JSONValue.toJSONString(content));
+ } catch (UnsupportedEncodingException e) {
+ throw new HandlerSetupFailureException(getClass().getName(), e);
+ }
-public class LibraryRequestHandler implements ApiRequestHandler
-{
- /**
- * Handle a server GET request (that is, a request for data
- * output).
- *
- * @param parameters A key-value map of parameters supplied with
- * the server request. Typically, the function
- * parameter will detail the function that the
- * request handler is expected to perform.
- *
- * @param server The server from which the request originated.
- * This will be able to provide the handler with
- * pooled resources, for example the database.
- *
- * @return A list of lines to return in the body of the
- * server's response to the client.
- *
- * @throws HandleFailureException if the handler cannot
- * handle the request.
- */
-
- @Override
- public Map<String, Object>
- handleGetRequest (Map<String, String> parameters, Server server)
- throws HandleFailureException
- {
- Map<String, Object> response = new HashMap<String, Object>();
-
- if (parameters.containsKey ("function"))
- {
- String function = parameters.get ("function");
-
- if (function.equals ("search"))
- {
- doSearch (parameters, response, server);
- }
- else if (function.equals ("help"))
- {
- response.put (Directive.INFO.toString (),
- "Available functions:");
- response.put (Directive.INFO.toString (), "search (string) - search library for string.");
- }
- else
- throw new HandleFailureException ("Unknown function: "
- + function + ". (Try 'function=help'.)");
-
- }
- else
- throw new HandleFailureException ("No function provided. (Try 'function=help'.)");
-
- return response;
- }
-
-
- /**
- * Perform a library search, populating the response list.
- *
- * @param parameters A key-value map of parameters supplied with
- * the server request. Typically, the function
- * parameter will detail the function that the
- * request handler is expected to perform.
- *
- * @param response The response list to populate.
- *
- * @param server The server providing database resources.
- *
- * @throws HandleFailureException if an error occurs
- * that thwarts the handling of the request.
- */
-
- private void
- doSearch (Map<String, String> parameters,
- Map<String, Object> response, Server server)
- throws HandleFailureException
- {
- if (parameters.containsKey ("search") == false)
- throw new HandleFailureException ("Search term is missing.");
- else if (parameters.get ("search") == null)
- throw new HandleFailureException ("Search term is null.");
-
- String search = parameters.get ("search");
- DatabaseDriver dd = null;
-
- try
- {
- dd = server.getDatabaseConnection (UserClass.READ_ONLY);
- }
- catch (MissingCredentialsException e)
- {
- throw new HandleFailureException (e.getMessage ());
- }
- catch (ConnectionFailureException e)
- {
- throw new HandleFailureException (e.getMessage ());
- }
-
- try
- {
- List<Map<String, String>> itemArray = new ArrayList<Map<String, String>> ();
-
- for (LibraryItem li : LibraryUtils.search (dd, search))
- {
- itemArray.add (li.asResponse ());
- }
-
- response.put (Directive.ITEMS.toString (), itemArray);
- }
- catch (QueryFailureException e)
- {
- throw new HandleFailureException (e.getMessage ());
- }
- catch (EmptySearchException e)
- {
- throw new HandleFailureException (e.getMessage ());
- }
- }
+ entity.setContentType(HTTP.PLAIN_TEXT_TYPE);
+ response.setEntity(entity);
+ }
}
diff --git a/src/uk/org/ury/library/viewer/LibraryViewer.java b/src/uk/org/ury/library/viewer/LibraryViewer.java
index 11496cb..810bf7e 100644
--- a/src/uk/org/ury/library/viewer/LibraryViewer.java
+++ b/src/uk/org/ury/library/viewer/LibraryViewer.java
@@ -94,7 +94,7 @@ public class LibraryViewer extends AbstractFrontendModule {
try {
response = cl
- .get("/library/LibraryRequestHandler?function=search&search="
+ .get("/library/tracks?search="
+ search);
} catch (DecodeFailureException e) {
throw new InvalidMessageException(e.getMessage());
diff --git a/src/uk/org/ury/server/AbstractRequestHandler.java b/src/uk/org/ury/server/AbstractRequestHandler.java
new file mode 100644
index 0000000..9682bec
--- /dev/null
+++ b/src/uk/org/ury/server/AbstractRequestHandler.java
@@ -0,0 +1,254 @@
+/**
+ *
+ */
+package uk.org.ury.server;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.json.simple.JSONValue;
+
+import uk.org.ury.protocol.Directive;
+import uk.org.ury.protocol.Status;
+import uk.org.ury.server.exceptions.BadRequestException;
+import uk.org.ury.server.exceptions.HandleFailureException;
+import uk.org.ury.server.exceptions.HandlerNotFoundException;
+import uk.org.ury.server.exceptions.HandlerSetupFailureException;
+import uk.org.ury.server.exceptions.HandlingException;
+import uk.org.ury.server.exceptions.NotAHandlerException;
+import uk.org.ury.server.exceptions.UnknownFunctionException;
+
+/**
+ * An abstract request handler for HttpCore, providing basic functionality such
+ * as uniform error response.
+ *
+ * @author Matt Windsor
+ */
+public abstract class AbstractRequestHandler implements HttpRequestHandler {
+ protected Server server;
+ protected String mount;
+
+ /**
+ * Construct a new AbstractRequestHandler.
+ *
+ * Obviously, this class cannot be instantiated directly.
+ *
+ * @param server
+ * The instance of the URY server responsible for the request.
+ *
+ * @param mount
+ * The directory to which this handler is to be mounted.
+ */
+ public AbstractRequestHandler(Server server, String mount) {
+ this.server = server;
+ this.mount = mount;
+ }
+
+ /**
+ * Begins handling of a HTTP request.
+ *
+ * @param request
+ * The HTTP request.
+ *
+ * @param response
+ * The response that the handler will populate during the
+ * handling of the request.
+ *
+ * @param context
+ * The HTTP context.
+ */
+ @Override
+ public void handle(HttpRequest request, HttpResponse response,
+ HttpContext context) throws HttpException, IOException {
+ String method = request.getRequestLine().getMethod()
+ .toUpperCase(Locale.ENGLISH);
+
+ if (method.equals("GET")) {
+ try {
+ handleGet(request, response, context);
+ } catch (HandlerNotFoundException e) {
+ // TODO: log
+ serveError(request, response, HttpStatus.SC_NOT_FOUND,
+ e.getMessage());
+ } catch (BadRequestException e) {
+ // TODO: log
+ serveError(request, response, HttpStatus.SC_BAD_REQUEST,
+ e.getMessage());
+ } catch (HandlingException e) {
+ serveError(request, response,
+ HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+ }
+ } else {
+ serveError(request, response, HttpStatus.SC_NOT_IMPLEMENTED,
+ "Method not implemented.");
+ }
+ }
+
+ /**
+ * Serve a HTTP plain-text error as the HTTP response for a request.
+ *
+ * @param request
+ * The request that is being responded to.
+ *
+ * @param response
+ * The response to populate with the error message.
+ *
+ * @param code
+ * HTTP status code to use.
+ *
+ * @param reason
+ * The reason to display to the client.
+ */
+ protected void serveError(HttpRequest request, HttpResponse response,
+ int code, String reason) {
+ // Get the reason string to put in the error response.
+ String statusReason = "";
+
+ switch (code) {
+ case HttpStatus.SC_BAD_REQUEST:
+ statusReason = "Bad Request";
+ break;
+ case HttpStatus.SC_NOT_FOUND:
+ statusReason = "Not Found";
+ break;
+ default:
+ case HttpStatus.SC_INTERNAL_SERVER_ERROR:
+ statusReason = "Internal Server Error";
+ break;
+ }
+
+ response.setStatusLine(request.getProtocolVersion(), code, statusReason);
+ StringEntity entity = null;
+
+ try {
+ Map<String, Object> content = new HashMap<String, Object>();
+
+ content.put(Directive.STATUS.toString(), Status.ERROR.toString());
+ content.put(Directive.REASON.toString(), reason);
+
+ entity = new StringEntity(JSONValue.toJSONString(content));
+ } catch (UnsupportedEncodingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ if (entity != null) {
+ entity.setContentType(HTTP.PLAIN_TEXT_TYPE);
+ response.setEntity(entity);
+ }
+ }
+
+ /**
+ * Handle a HTTP GET request.
+ *
+ * @param request
+ * The HTTP request.
+ *
+ * @param response
+ * The response that the handler will populate during the
+ * handling of the request.
+ *
+ * @param context
+ * The HTTP context.
+ *
+ * @throws HandlerNotFoundException
+ * if the client requested a request handler that could not be
+ * found on the class path.
+ *
+ * @throws HandlerSetupFailureException
+ * if the handler was found but could not be set up (eg does not
+ * implement appropriate interface or cannot be instantiated).
+ *
+ * @throws HandleFailureException
+ * if an appropriate handler was contacted, but it failed to
+ * process the request.
+ *
+ * @throws BadRequestException
+ * if the request was malformed or invalid.
+ *
+ * @throws NotAHandlerException
+ * if the class requested to handle the request is not a
+ * handler.
+ *
+ * @throws UnknownFunctionException
+ * if the request is for a path that does not correspond to one
+ * of this handler's functions.
+ */
+ protected abstract void handleGet(HttpRequest request,
+ HttpResponse response, HttpContext context)
+ throws HandlerNotFoundException, HandlerSetupFailureException,
+ HandleFailureException, BadRequestException, NotAHandlerException,
+ UnknownFunctionException;
+
+ /**
+ * Parse a query string, populating a key-value map of the URL-unescaped
+ * results.
+ *
+ * @param query
+ * The query string to parse.
+ *
+ * @return A map associating parameter keys and values.
+ *
+ * @throws UnsupportedEncodingException
+ * if the URL decoder fails.
+ */
+ protected final Map<String, String> parseQueryString(String query)
+ throws UnsupportedEncodingException {
+ Map<String, String> params = new HashMap<String, String>();
+
+ // At least one parameter
+ if (query != null && query.endsWith("&") == false) {
+ String[] qsplit = { query };
+
+ // More than one parameter - split the query.
+ if (query.contains("&"))
+ qsplit = query.split("&");
+
+ for (String param : qsplit) {
+ // Has a value
+ if (param.contains("=") && param.endsWith("=") == false) {
+ String[] paramsplit = param.split("=");
+ params.put(URLDecoder.decode(paramsplit[0], "UTF-8"),
+ URLDecoder.decode(paramsplit[1], "UTF-8"));
+ }
+ // Doesn't have a value
+ else if (param.contains("=") == false) {
+ params.put(URLDecoder.decode(param, "UTF-8"), null);
+ }
+ }
+ }
+
+ return params;
+ }
+
+ /**
+ * Get the query string element of a
+ *
+ * @param uri
+ * The Uniform Resource Indicator whose query string should be
+ * extracted.
+ *
+ * @return The query string, or null if it does not exist.
+ */
+ protected final String getQueryString(String uri) {
+ String result = null;
+
+ if (uri.contains("?") && uri.endsWith("?") == false) {
+ result = uri.split("\\?")[1];
+ }
+
+ return result;
+ }
+} \ No newline at end of file
diff --git a/src/uk/org/ury/server/HttpHandler.java b/src/uk/org/ury/server/HttpHandler.java
index 41b4dc4..948e03a 100644
--- a/src/uk/org/ury/server/HttpHandler.java
+++ b/src/uk/org/ury/server/HttpHandler.java
@@ -39,16 +39,11 @@
package uk.org.ury.server;
-import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
-import java.net.URLDecoder;
-import java.util.HashMap;
-import java.util.Locale;
import java.util.Map;
-import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
@@ -64,64 +59,25 @@ import uk.org.ury.server.exceptions.BadRequestException;
import uk.org.ury.server.exceptions.HandleFailureException;
import uk.org.ury.server.exceptions.HandlerNotFoundException;
import uk.org.ury.server.exceptions.HandlerSetupFailureException;
-import uk.org.ury.server.exceptions.HandlingException;
import uk.org.ury.server.exceptions.NotAHandlerException;
/**
* @author Matt Windsor, Apache Software Foundation
*/
-public class HttpHandler implements HttpRequestHandler {
- private Server server;
+public class HttpHandler extends AbstractRequestHandler implements
+ HttpRequestHandler {
/**
* Construct a new HttpHandler.
*
* @param server
- * The server whose HTTP requests are to be handled by this
- * handler.
- */
- public HttpHandler(Server server) {
- this.server = server;
- }
-
- /**
- * Handle a HTTP request.
- *
- * @param request
- * The HTTP request.
+ * The instance of the URY server responsible for the request.
*
- * @param response
- * The response that the handler will populate during the
- * handling of the request.
- *
- * @param context
- * The HTTP context.
+ * @param mount
+ * The directory to which this handler is to be mounted.
*/
- @Override
- public void handle(HttpRequest request, HttpResponse response,
- HttpContext context) throws HttpException, IOException {
- String method = request.getRequestLine().getMethod()
- .toUpperCase(Locale.ENGLISH);
-
- if (method.equals("GET")) {
- try {
- handleGet(request, response, context);
- } catch (HandlerNotFoundException e) {
- // TODO: log
- serveError(request, response, HttpStatus.SC_NOT_FOUND,
- e.getMessage());
- } catch (BadRequestException e) {
- // TODO: log
- serveError(request, response, HttpStatus.SC_BAD_REQUEST,
- e.getMessage());
- } catch (HandlingException e) {
- serveError(request, response,
- HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMessage());
- }
- } else {
- serveError(request, response, HttpStatus.SC_NOT_IMPLEMENTED,
- "Method not implemented.");
- }
+ public HttpHandler(Server server, String mount) {
+ super(server, mount);
}
/**
@@ -156,6 +112,7 @@ public class HttpHandler implements HttpRequestHandler {
* if the class requested to handle the request is not a
* handler.
*/
+ @Override
public void handleGet(HttpRequest request, HttpResponse response,
HttpContext context) throws HandlerNotFoundException,
HandlerSetupFailureException, HandleFailureException,
@@ -245,99 +202,4 @@ public class HttpHandler implements HttpRequestHandler {
response.setEntity(entity);
}
}
-
- /**
- * Serve a HTTP plain-text error as the HTTP response for a request.
- *
- * @param request
- * The request that is being responded to.
- *
- * @param response
- * The response to populate with the error message.
- *
- * @param code
- * HTTP status code to use.
- *
- * @param reason
- * The reason to display to the client.
- */
- private void serveError(HttpRequest request, HttpResponse response,
- int code, String reason) {
- // Get the reason string to put in the error response.
- String statusReason = "";
-
- switch (code) {
- case HttpStatus.SC_BAD_REQUEST:
- statusReason = "Bad Request";
- break;
- case HttpStatus.SC_NOT_FOUND:
- statusReason = "Not Found";
- break;
- default:
- case HttpStatus.SC_INTERNAL_SERVER_ERROR:
- statusReason = "Internal Server Error";
- break;
- }
-
- response.setStatusLine(request.getProtocolVersion(), code, statusReason);
- StringEntity entity = null;
-
- try {
- Map<String, Object> content = new HashMap<String, Object>();
-
- content.put(Directive.STATUS.toString(), Status.ERROR.toString());
- content.put(Directive.REASON.toString(), reason);
-
- entity = new StringEntity(JSONValue.toJSONString(content));
- } catch (UnsupportedEncodingException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- if (entity != null) {
- entity.setContentType(HTTP.PLAIN_TEXT_TYPE);
- response.setEntity(entity);
- }
- }
-
- /**
- * Parse a query string, populating a key-value map of the URL-unescaped
- * results.
- *
- * @param query
- * The query string to parse.
- *
- * @return A map associating parameter keys and values.
- *
- * @throws UnsupportedEncodingException
- * if the URL decoder fails.
- */
- public Map<String, String> parseQueryString(String query)
- throws UnsupportedEncodingException {
- Map<String, String> params = new HashMap<String, String>();
-
- // At least one parameter
- if (query != null && query.endsWith("&") == false) {
- String[] qsplit = { query };
-
- // More than one parameter - split the query.
- if (query.contains("&"))
- qsplit = query.split("&");
-
- for (String param : qsplit) {
- // Has a value
- if (param.contains("=") && param.endsWith("=") == false) {
- String[] paramsplit = param.split("=");
- params.put(URLDecoder.decode(paramsplit[0], "UTF-8"),
- URLDecoder.decode(paramsplit[1], "UTF-8"));
- }
- // Doesn't have a value
- else if (param.contains("=") == false) {
- params.put(URLDecoder.decode(param, "UTF-8"), null);
- }
- }
- }
-
- return params;
- }
}
diff --git a/src/uk/org/ury/server/HttpListenerThread.java b/src/uk/org/ury/server/HttpListenerThread.java
index 9396d0b..c6b042b 100644
--- a/src/uk/org/ury/server/HttpListenerThread.java
+++ b/src/uk/org/ury/server/HttpListenerThread.java
@@ -60,6 +60,8 @@ import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
+import uk.org.ury.library.LibraryRequestHandler;
+
/**
* Listener thread for the URY server HTTP interface.
*
@@ -75,23 +77,24 @@ public class HttpListenerThread extends Thread {
public HttpListenerThread(int port, Server server) throws IOException {
ssocket = new ServerSocket(port);
params = new SyncBasicHttpParams();
-
- params
- .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
- .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
- .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
- .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
- .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1");
- httpproc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
- new ResponseDate(),
- new ResponseServer(),
- new ResponseContent(),
- new ResponseConnControl()
- });
-
+ params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
+ .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE,
+ 8 * 1024)
+ .setBooleanParameter(
+ CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
+ .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
+ .setParameter(CoreProtocolPNames.ORIGIN_SERVER,
+ "HttpComponents/1.1");
+
+ httpproc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] {
+ new ResponseDate(), new ResponseServer(),
+ new ResponseContent(), new ResponseConnControl() });
+
registry = new HttpRequestHandlerRegistry();
- registry.register("*", new HttpHandler(server));
+ registry.register("/library/*", new LibraryRequestHandler(server,
+ "/library"));
+ registry.register("*", new HttpHandler(server, ""));
service = new HttpService(httpproc,
new DefaultConnectionReuseStrategy(),
@@ -105,8 +108,7 @@ public class HttpListenerThread extends Thread {
public void run() {
while (Thread.interrupted() == false) {
Socket csocket = null;
- DefaultHttpServerConnection conn
- = new DefaultHttpServerConnection();
+ DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
Thread thread = null;
try {
@@ -116,7 +118,7 @@ public class HttpListenerThread extends Thread {
e.printStackTrace();
break;
}
-
+
thread = new HttpWorkerThread(service, conn);
thread.setDaemon(true);
thread.start();
diff --git a/src/uk/org/ury/server/RequestHandler.java b/src/uk/org/ury/server/RequestHandler.java
deleted file mode 100644
index d4880d6..0000000
--- a/src/uk/org/ury/server/RequestHandler.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package uk.org.ury.server;
-
-import java.util.Map;
-
-import uk.org.ury.server.exceptions.HandleFailureException;
-
-
-/**
- * Interface for classes that can handle requests addressed to their
- * class name from the main server.
- *
- * For an example of how to implement a RequestHandler, see
- * ServerRequestHandler.
- *
- * @author Matt Windsor
- */
-
-public interface RequestHandler
-{
- /**
- * Handle a server GET request (that is, a request for data
- * output).
- *
- * @param parameters A key-value map of parameters supplied with the
- * server request. Typically, the "function"
- * parameter will detail the function that the
- * request handler is expected to perform.
- *
- * @param server The server from which the request originated.
- * This will be able to provide the handler with
- * pooled resources, for example the database.
- *
- * @return A series of key-value pairs to pass back to
- * the client.
- *
- * @throws HandleFailureException if the handler cannot
- * handle the request.
- */
-
- public Map<String, Object>
- handleGetRequest (Map<String, String> parameters, Server server)
- throws HandleFailureException;
-}
diff --git a/src/uk/org/ury/server/ServerProtocol.java b/src/uk/org/ury/server/ServerProtocol.java
deleted file mode 100644
index 92d2955..0000000
--- a/src/uk/org/ury/server/ServerProtocol.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package uk.org.ury.server;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * The BAPS server protocol (a minimal implementation of HTTP 1.1) handler.
- *
- * @author Matt Windsor
- *
- */
-
-public class ServerProtocol
-{
- public static final String GET_HEADER = "HTTP/1.1 200 OK\n";
-
- public List<String> buffer;
-
-
- public
- ServerProtocol ()
- {
- buffer = new ArrayList<String> ();
- }
-
- public String
- processInput (String string)
- {
- if (string.equals (""))
- {
- System.out.println ("Bingo!");
- return "HTTP/1.1 200 OK\nConnection: Close\n\r\n<html><head></head><body>poo</body></html>\n\r\n";
- }
- return "";
- }
-
-}
diff --git a/src/uk/org/ury/server/exceptions/UnknownFunctionException.java b/src/uk/org/ury/server/exceptions/UnknownFunctionException.java
new file mode 100644
index 0000000..13c1386
--- /dev/null
+++ b/src/uk/org/ury/server/exceptions/UnknownFunctionException.java
@@ -0,0 +1,37 @@
+/*
+ * UnknownFunctionException.java
+ * -----------------------------
+ *
+ * Part of the URY Server Platform
+ *
+ * V0.00 2011/03/20
+ *
+ * (C) 2011 URY Computing
+ */
+
+package uk.org.ury.server.exceptions;
+
+/**
+ * Exception thrown when a handler receives a request for a path that does not
+ * correspond to one of its functions.
+ *
+ * @author Matt Windsor
+ *
+ */
+public class UnknownFunctionException extends HandlingException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7557785978712465975L;
+
+ /**
+ * Construct a new UnknownFunctionException.
+ *
+ * @param path
+ * The path that was requested.
+ */
+ public UnknownFunctionException(String path) {
+ super("Not found: " + path);
+ }
+
+}
diff --git a/src/uk/org/ury/server/protocol/DecodeFailureException.java b/src/uk/org/ury/server/protocol/DecodeFailureException.java
deleted file mode 100644
index faa2b1f..0000000
--- a/src/uk/org/ury/server/protocol/DecodeFailureException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- *
- */
-package uk.org.ury.server.protocol;
-
-/**
- * Exception thrown when the protocol decoder fails.
- *
- * @author Matt Windsor
- */
-
-public class DecodeFailureException extends Exception
-{
- /**
- *
- */
- private static final long serialVersionUID = -3972492943653273528L;
-
-
- /**
- * Construct a new DecodeFailureException with a reason.
- *
- * @param reason The reason for throwing the exception.
- */
-
- public
- DecodeFailureException (String reason)
- {
- super (reason);
- }
-}
diff --git a/src/uk/org/ury/server/protocol/Directive.java b/src/uk/org/ury/server/protocol/Directive.java
deleted file mode 100644
index ce1b8b9..0000000
--- a/src/uk/org/ury/server/protocol/Directive.java
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- *
- */
-package uk.org.ury.server.protocol;
-
-/**
- * Directives supported by the protocol.
- *
- * @author Matt Windsor
- */
-
-public enum Directive
- {
- INFO, // Information string (can usually be ignored)
- ITEMS, // Item
- STATUS, // Status code (from the enum Status)
- REASON; // Error reason
- }
diff --git a/src/uk/org/ury/server/protocol/ProtocolUtils.java b/src/uk/org/ury/server/protocol/ProtocolUtils.java
deleted file mode 100644
index e45bb22..0000000
--- a/src/uk/org/ury/server/protocol/ProtocolUtils.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- *
- */
-package uk.org.ury.server.protocol;
-
-import java.util.Map;
-
-import org.json.simple.JSONObject;
-import org.json.simple.JSONValue;
-
-
-/**
- * Utilities for converting between strings encoded in the response
- * protocol and collections of items.
- *
- * @author Matt Windsor
- *
- */
-
-public class ProtocolUtils
-{
- /**
- * Encode a key-value map into a protocol string.
- *
- * The map can contain strings, lists and other maps. Other
- * types may be accepted by the underlying encoding engine,
- * but the above types are the only ones explicitly accepted.
- *
- * @param items The key-value map of items, which should contain
- * strings, lists and maps. The keys of any map
- * should be protocol directives.
- *
- * @return A string containing the encoded representation of
- * the map.
- */
-
- public static String
- encode (Map<String, Object> items)
- {
- return JSONValue.toJSONString (items);
- }
-
-
- /**
- * Decode a protocol string into a key-value map.
- *
- * @param string The string to decode.
- *
- * @return A key-value map mapping directives to strings,
- * lists and maps.
- *
- * @throws DecodeFailureException if the decoding engine
- * returns something other than a map.
- */
-
- public static Map<?, ?>
- decode (String string) throws DecodeFailureException
- {
- Object result = JSONValue.parse (string);
-
- if (result instanceof JSONObject)
- return (JSONObject) result;
- else
- throw new DecodeFailureException ("Result not a map.");
- }
-
-}
diff --git a/src/uk/org/ury/server/protocol/Status.java b/src/uk/org/ury/server/protocol/Status.java
deleted file mode 100644
index c9d848d..0000000
--- a/src/uk/org/ury/server/protocol/Status.java
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- *
- */
-package uk.org.ury.server.protocol;
-
-
-/**
- * Statuses that can follow the STATUS directory.
- *
- * @author Matt Windsor
- */
-
-public enum Status
- {
- OK, // The request was processed OK; response should be valid
- ERROR // An error occurred; message provided as REASON directive
- }