namespace edu.neu.ccs.demeterf.http.server{ using edu.neu.ccs.demeterf.http.classes; using edu.neu.ccs.demeterf.util; using System.IO; using System.Reflection; using System.Net.Sockets; using System; using edu.neu.ccs.demeterf.lib; /** Web Server Factory class */ public class Factory { private Factory(){} static bool verbose = false; /** Set to true in order to get Output for Server/Dispatch descisions. */ public static void setVerbose(bool v){ verbose = v; } public static void p(String s){ if (verbose) { Console.WriteLine(" ** " + s); } } /** * Create a new Server using the given Handler. The {@link * edu.neu.ccs.demeterf.http.server.Server Server} annotation is * used to tag a class as an HTTP Server/Handler. Within the * class, {@link edu.neu.ccs.demeterf.http.server.Port Port} * Annotation is used to mark the port (an instance variable) the * Server will listen on, which is bound (read) at Server creation * time. Handler methods are annotated with {@link * edu.neu.ccs.demeterf.http.server.Path Path} to describe * responses to various Path requests. See {@link * edu.neu.ccs.demeterf.http.Test Test} for an Example. */ public static ServerThread create(Object handler){ return create(handler, false); } /** Create a Single/Multi-threaded Server */ public static ServerThread create(Object handler, bool single){ Type t = handler.GetType(); if (!t.IsDefined(typeof(Server),true)){ throw error("Cannot Create Server for unannotated class '" + t.Name + "'"); } int port = getPort(t, handler); p("Server Port = " + port); return new ServerThread(port, single, ServerDispatch.create(handler)); } /** Create a ServerDispatch for direct testing */ public ServerDispatch localDispatcher(Object handler){ return ServerDispatch.create(handler, ServerDispatch.MinimalFormals); } /** Get the Port number of the server handler instance */ private static int getPort(Type t, Object server){ foreach(FieldInfo ff in Util.getFieldArray(t)){ if(ff.IsDefined(typeof(Port),true) && (ff.FieldType.Equals(typeof(int)) || ff.FieldType.Equals(typeof(Int32)))){ try{ return (int)ff.GetValue(server); }catch(Exception e){ throw error("Port Field '"+ff.Name+"' is not accessible in " + t.Name); } } } throw error("No Port Field found in " + t.Name); } /** Create a RuntimeException to throw with the given Message */ public static Exception error(String s){ return new Exception(s); } /** Create a RuntimeException to throw with the given Cause */ public static Exception error(Exception e){ return e; } } }