package http.server; import http.gen.HTTPReq; import http.gen.HTTPResp; import java.io.IOException; import java.lang.reflect.Method; import edu.neu.ccs.demeterf.demfgen.lib.List; import edu.neu.ccs.demeterf.demfgen.lib.Map; /** Web Server Factory class */ public class Factory { private Factory(){} static boolean verbose = false; /** Set to true in order to get Output for Server/Dispatch descisions. */ public static void setVerbose(boolean v){ verbose = v; } static void p(String s){ if (verbose)System.err.println(" ** " + s); } /** Create a new Server using the given Handler. A {@link http.server.Server Server} * Annotation is used to describe the Port the Server will Listen on, and methods * should be Annotated with {@link http.server.Path Path} to describe responses * to various Path requests. See {@link http.Test Test} for an Example. */ public static ServerThread create(Object handler) throws IOException { return create(handler,false); } /** Create a Single/Multi-threaded Server */ public static ServerThread create(Object handler, boolean single) throws IOException{ Class c = handler.getClass(); if (!c.isAnnotationPresent(Server.class)) { throw error("Cannot Create Server for unannotated class '" + c.getCanonicalName() + "'"); } Server s = c.getAnnotation(Server.class); p("Server Port = " + s.value()); return new ServerThread(s, single, List.create(c.getDeclaredMethods()).fold( new List.Fold>() { public Map fold(Method m, Map res){ if (!m.isAnnotationPresent(Path.class))return res; String p = check(m); m.setAccessible(true); p("Mapping '" + p + "' to " + m.getName()); return res.put(p, m); } }, Map. create()), handler); } /** Do a sanity check of the types of an annotated method */ private static String check(Method m){ Path p = m.getAnnotation(Path.class); if (!HTTPResp.class.equals(m.getReturnType())) { throw error("Return Type is incorrect: '" + m.getReturnType().getClass() + "'"); } Class[] params = m.getParameterTypes(); if (params.length > 1) throw error("Too many Parameters for Server Method '" + m.getName() + "'"); if (!params[0].equals(HTTPReq.class)) throw error("Wrong parameters type for method '" + m.getName() + "'"); return p.value(); } private static RuntimeException error(String e){ return new RuntimeException(e); } }