2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import java.io.BufferedReader;
24 import java.io.IOException;
25 import java.io.PrintWriter;
26 import java.net.BindException;
27 import java.util.HashMap;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
33 import jalview.bin.Cache;
34 import jalview.httpserver.AbstractRequestHandler;
37 * A simple handler to process (or delegate) HTTP requests on /jalview/rest
39 public class RestHandler extends AbstractRequestHandler
44 STARTED, IN_PROGRESS, FINISHED, ERROR
47 public interface EndpointI
49 public String getName();
51 public void processEndpoint(HttpServletRequest request,
52 HttpServletResponse response);
56 public interface EndpointOld
58 public void processEndpoint(String endpointName,
59 HttpServletRequest request, HttpServletResponse response);
62 private static final String MY_PATH = "rest";
64 private static final String MY_NAME = "Rest";
66 private String missingEndpointMessage = null;
68 private boolean init = false;
70 // map of method names and method handlers
71 private Map<String, EndpointI> endpoints = null;
73 protected Map<String, EndpointI> getEndpoints()
79 * Singleton instance of this class
81 private static RestHandler instance = null;
84 * Returns the singleton instance of this class
87 * @throws BindException
89 public static RestHandler getInstance() throws BindException
91 synchronized (RestHandler.class)
95 instance = new RestHandler();
102 * Private constructor enforces use of singleton
104 * @throws BindException
106 protected RestHandler() throws BindException
111 * We don't register the handler here - this is done as a special case in
112 * HttpServer initialisation; to do it here would invite an infinite loop of
113 * RestHandler/HttpServer constructor
118 * Handle a jalview/rest request
120 * @throws IOException
123 protected void processRequest(HttpServletRequest request,
124 HttpServletResponse response) throws IOException
127 * Currently just echoes the request; add helper classes as required to
130 System.out.println(request.toString());
131 if (endpoints == null)
133 final String queryString = request.getQueryString();
134 final String reply = "REST not yet implemented; received "
135 + request.getMethod() + ": " + request.getRequestURL()
136 + (queryString == null ? "" : "?" + queryString);
137 System.out.println(reply);
139 response.setHeader("Cache-Control", "no-cache/no-store");
140 response.setHeader("Content-type", "text/plain");
141 final PrintWriter writer = response.getWriter();
147 String endpointName = getRequestedEndpointName(request);
149 Cache.info("REMOVEME endpointName=" + endpointName);
150 Cache.info("REMOVEME endpoints[" + endpointName + "]="
151 + endpoints.get(endpointName));
152 if (!endpoints.containsKey(endpointName)
153 || endpoints.get(endpointName) == null)
156 response.setHeader("Cache-Control", "no-cache/no-store");
157 response.setHeader("Content-type", "text/plain");
158 response.setStatus(400);
159 PrintWriter writer = response.getWriter();
160 writer.write(missingEndpointMessage == null
161 ? "REST endpoint '" + endpointName + "' not defined"
162 : missingEndpointMessage);
167 response.setHeader("Cache-Control", "no-cache/no-store");
168 response.setHeader("Content-type", "text/plain");
169 EndpointI ep = endpoints.get(endpointName);
170 ep.processEndpoint(request, response);
176 * Returns a display name for this service
179 public String getName()
187 * @throws BindException
189 protected void init() throws BindException
194 protected void init(String path) throws BindException
197 // Override this in extended class
198 // e.g. registerHandler and addEndpoints
201 protected boolean addEndpoint(EndpointI ep)
203 if (endpoints == null)
205 endpoints = new HashMap<>();
207 Cache.info("REMOVEME Adding Endpoint ep=" + ep);
208 Cache.info("REMOVEME Adding Endpoint ep.getName()=" + ep.getName());
209 Endpoint e = (Endpoint) ep;
210 Cache.info("REMOVEME Adding Endpoint e.name=" + e.name);
211 endpoints.put(ep.getName(), ep);
215 protected String getRequestedEndpointName(HttpServletRequest request)
217 String pathInfo = request.getPathInfo();
218 int slashpos = pathInfo.indexOf('/', 1);
219 return slashpos > 1 ? pathInfo.substring(1, slashpos)
220 : pathInfo.substring(1);
223 protected String[] getEndpointPathParameters(HttpServletRequest request)
225 String pathInfo = request.getPathInfo();
226 int slashpos = pathInfo.indexOf('/', 1);
227 return slashpos < 1 ? null
228 : pathInfo.substring(slashpos + 1).split("/");
231 protected void returnError(HttpServletRequest request,
232 HttpServletResponse response, String message)
234 response.setStatus(500); // set this to something better
235 String endpointName = getRequestedEndpointName(request);
236 Cache.error(this.MY_NAME + " error: endpoint " + endpointName
237 + " failed: '" + message + "'");
240 PrintWriter writer = response.getWriter();
241 writer.write("Endpoint " + endpointName + ": " + message);
243 } catch (IOException e)
249 protected void returnStatus(HttpServletResponse response, String id,
254 PrintWriter writer = response.getWriter();
256 writer.write("id=" + id + "\n");
258 writer.write("status=" + status.toString() + "\n");
259 } catch (IOException e)
265 protected String getRequestBody(HttpServletRequest request)
268 StringBuilder sb = new StringBuilder();
269 BufferedReader reader = request.getReader();
273 while ((line = reader.readLine()) != null)
275 sb.append(line).append('\n');
281 return sb.toString();