JAL-1575 bare bones RestHandler added
[jalview.git] / src / jalview / httpserver / AbstractRequestHandler.java
1 package jalview.httpserver;
2
3 import java.io.IOException;
4 import java.net.BindException;
5 import java.util.Collections;
6
7 import javax.servlet.ServletException;
8 import javax.servlet.http.HttpServletRequest;
9 import javax.servlet.http.HttpServletResponse;
10
11 import org.eclipse.jetty.server.Request;
12 import org.eclipse.jetty.server.handler.AbstractHandler;
13
14 /**
15  * 
16  * @author gmcarstairs
17  *
18  */
19 public abstract class AbstractRequestHandler extends AbstractHandler
20 {
21
22   /*
23    * The relative path (below context root) of this handler (without /
24    * separators)
25    */
26   private String path;
27
28   /*
29    * The full URI on which this handler listens
30    */
31   private String uri;
32
33   /**
34    * Handle an incoming Http request.
35    */
36   @Override
37   public void handle(String target, Request baseRequest,
38           HttpServletRequest request, HttpServletResponse response)
39           throws IOException, ServletException
40   {
41     try
42     {
43       // dumpRequest(request); // debug
44       processRequest(request, response);
45     } catch (Throwable t)
46     {
47       /*
48        * Set server error status on response
49        */
50       System.err.println("Exception handling request "
51               + request.getRequestURI() + " : " + t.getMessage());
52       if (response.isCommitted())
53       {
54         /*
55          * Can't write an HTTP header once any response content has been written
56          */
57         System.err
58                 .println("Unable to return HTTP 500 as response already committed");
59       }
60       else
61       {
62         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
63       }
64     } finally
65     {
66       response.getWriter().flush();
67       baseRequest.setHandled(true);
68     }
69   }
70
71   /**
72    * Subclasses should override this method to perform request processing
73    * 
74    * @param request
75    * @param response
76    */
77   protected abstract void processRequest(HttpServletRequest request,
78           HttpServletResponse response);
79
80   /**
81    * For debug - writes HTTP request details to stdout
82    * 
83    * @param request
84    */
85   protected void dumpRequest(HttpServletRequest request)
86   {
87     System.out.println(request.getMethod());
88     System.out.println(request.getRequestURL());
89     for (String hdr : Collections.list(request.getHeaderNames()))
90     {
91       for (String val : Collections.list(request.getHeaders(hdr)))
92       {
93         System.out.println(hdr + ": " + val);
94       }
95     }
96     for (String param : Collections.list(request.getParameterNames()))
97     {
98       for (String val : request.getParameterValues(param))
99       {
100         System.out.println(param + "=" + val);
101       }
102     }
103   }
104
105   /**
106    * Returns a display name for the handler
107    * 
108    * @return
109    */
110   public abstract String getName();
111
112   /**
113    * Deregister this listener and close it down
114    * 
115    * @throws Exception
116    */
117   public void shutdown()
118   {
119     try
120     {
121       HttpServer.getInstance().removeHandler(this);
122       stop();
123     } catch (Exception e)
124     {
125       System.err.println("Error stopping " + getName() + ": "
126               + e.getMessage());
127     }
128   }
129
130   /**
131    * Returns the URI on which we are listening
132    * 
133    * @return
134    */
135   public String getUri()
136   {
137     return this.uri;
138   }
139
140   /**
141    * Set the URI to this handler
142    * 
143    * @param u
144    */
145   protected void setUri(String u)
146   {
147     this.uri = u;
148   }
149
150   /**
151    * Sets the relative path to this handler - do this before registering the
152    * handler.
153    * 
154    * @param p
155    */
156   protected void setPath(String p)
157   {
158     this.path = p;
159   }
160
161   /**
162    * Returns the relative path to this handler below the context root (without /
163    * separators)
164    * 
165    * @return
166    */
167   public String getPath()
168   {
169     return this.path;
170   }
171
172   /**
173    * Registers the handler with the HttpServer and reports its URI on stdout
174    * 
175    * @throws BindException
176    *           if no port could be allocated
177    * @throws IllegalStateException
178    *           if this method is called before {@link #setPath}
179    */
180   protected void registerHandler() throws BindException
181   {
182     HttpServer.getInstance().registerHandler(this);
183   }
184 }