Merge branch 'features/JAL-1541_BioJsMSA' into develop
[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    * @throws IOException
77    */
78   protected abstract void processRequest(HttpServletRequest request,
79           HttpServletResponse response) throws IOException;
80
81   /**
82    * For debug - writes HTTP request details to stdout
83    * 
84    * @param request
85    */
86   protected void dumpRequest(HttpServletRequest request)
87   {
88     System.out.println(request.getMethod());
89     System.out.println(request.getRequestURL());
90     for (String hdr : Collections.list(request.getHeaderNames()))
91     {
92       for (String val : Collections.list(request.getHeaders(hdr)))
93       {
94         System.out.println(hdr + ": " + val);
95       }
96     }
97     for (String param : Collections.list(request.getParameterNames()))
98     {
99       for (String val : request.getParameterValues(param))
100       {
101         System.out.println(param + "=" + val);
102       }
103     }
104   }
105
106   /**
107    * Returns a display name for the handler
108    * 
109    * @return
110    */
111   public abstract String getName();
112
113   /**
114    * Deregister this listener and close it down
115    * 
116    * @throws Exception
117    */
118   public void shutdown()
119   {
120     try
121     {
122       HttpServer.getInstance().removeHandler(this);
123       stop();
124     } catch (Exception e)
125     {
126       System.err.println("Error stopping " + getName() + ": "
127               + e.getMessage());
128     }
129   }
130
131   /**
132    * Returns the URI on which we are listening
133    * 
134    * @return
135    */
136   public String getUri()
137   {
138     return this.uri;
139   }
140
141   /**
142    * Set the URI to this handler
143    * 
144    * @param u
145    */
146   protected void setUri(String u)
147   {
148     this.uri = u;
149   }
150
151   /**
152    * Sets the relative path to this handler - do this before registering the
153    * handler.
154    * 
155    * @param p
156    */
157   protected void setPath(String p)
158   {
159     this.path = p;
160   }
161
162   /**
163    * Returns the relative path to this handler below the context root (without /
164    * separators)
165    * 
166    * @return
167    */
168   public String getPath()
169   {
170     return this.path;
171   }
172
173   /**
174    * Registers the handler with the HttpServer and reports its URI on stdout
175    * 
176    * @throws BindException
177    *           if no port could be allocated
178    * @throws IllegalStateException
179    *           if this method is called before {@link #setPath}
180    */
181   protected void registerHandler() throws BindException
182   {
183     HttpServer.getInstance().registerHandler(this);
184   }
185 }