package jalview.rest; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jalview.bin.Console; import jalview.gui.AlignFrame; import jalview.gui.Desktop; import jalview.rest.RestHandler.EndpointI; public abstract class AbstractEndpoint implements EndpointI { private final String path; private API api; private final String name; private final String parameters; private final String description; private String[] pathParameters = null; private Map queryParameters = null; private Map options = null; private String requestUrl = null; private String id = null; private String fromId = null; public AbstractEndpoint(API api, String path, String name, String parameters, String description) { this.api = api; this.path = path; this.name = name; this.parameters = parameters; this.description = description; } public String getPath() { return this.path; } protected API getAPI() { return this.api; } public String getName() { return this.name; } public String getParameters() { return this.parameters; } public String getDescription() { return this.description; } public abstract void processEndpoint(HttpServletRequest request, HttpServletResponse response); /* * Shared methods below here */ protected String getId(HttpServletRequest request) { if (id != null) return id; id = getQueryParameter(request, "id"); return id; } protected String getFromId(HttpServletRequest request) { if (fromId != null) return fromId; fromId = getQueryParameter(request, "fromId"); return fromId; } protected Map getQueryParameters( HttpServletRequest request) { if (queryParameters != null) return queryParameters; queryParameters = request.getParameterMap(); return queryParameters; } protected String getQueryParameter(HttpServletRequest request, String param) { String[] vals = getQueryParameters(request).get(param); return (vals == null || vals.length < 1) ? null : vals[0]; } protected String[] getEndpointPathParameters(HttpServletRequest request) { if (pathParameters != null) return pathParameters; String pathInfo = request.getPathInfo(); int slashpos = pathInfo.indexOf('/', 1); if (slashpos < 1) return null; pathParameters = pathInfo.substring(slashpos + 1).split("/"); return pathParameters; } protected Map getOptions(HttpServletRequest request) { if (this.options != null) return this.options; Map opts = new HashMap<>(); for (Entry e : getQueryParameters(null).entrySet()) { if (e.getKey().startsWith("option:")) { for (int i = 0; i < e.getValue().length; i++) { opts.put(e.getKey().substring(7), e.getValue()[i]); } } } String[] params = getEndpointPathParameters(request); if (params != null) { for (int i = 0; i < params.length; i++) { String param = params[i]; if (param.startsWith("option:")) { int ePos = param.indexOf("="); if (ePos == -1) { opts.put(param.substring(7), null); } else { opts.put(param.substring(7, ePos), param.substring(ePos + 1)); } } } } this.options = opts; return opts; } protected String getRequestUrl(HttpServletRequest request) { if (requestUrl != null) return requestUrl; if (request != null) { StringBuilder sb = new StringBuilder( request.getRequestURL().toString()); String query = request.getQueryString(); if (query != null || query.length() > 0) { sb.append("?").append(query); } requestUrl = sb.toString(); } else { Console.debug("AbstractEndpoint: request is null"); } return requestUrl; } protected void returnError(HttpServletRequest request, HttpServletResponse response, String message) { String okString = request.getParameter("ok"); boolean ok = (okString != null && okString.equalsIgnoreCase("true")); /* * Annoyingly jetty is not adding content to anything other than a few * 20x status codes. Possibly it is closing the PrintWriter. * Find a fix for this! ****************************************************/ response.setStatus(ok ? HttpServletResponse.SC_OK : // // HttpServletResponse.SC_BAD_REQUEST // HttpServletResponse.SC_PARTIAL_CONTENT // ); String endpointName = getPath(); Console.error(getAPI().getName() + " error: endpoint " + endpointName + " failed: '" + message + "'"); try { PrintWriter writer = response.getWriter(); writer.write("message=Endpoint " + endpointName + ": " + message); } catch (IOException e) { Console.info("Exception writing to REST response", e); } } protected boolean checkParameters(HttpServletRequest request, HttpServletResponse response, int i) { String[] parameters = getEndpointPathParameters(request); // check we can run fetchsequence if (parameters.length < i) { returnError(request, response, "requires parameters:" + getParameters() + "\n" + getName() + ": " + getDescription()); return false; } return true; } public int[][] parseIntRanges(String rangesString) { if (rangesString.equals("*")) { return new int[][] { { -1 }, { -1 } }; } String[] rangeStrings = rangesString.split(","); int[][] ranges = new int[2][rangeStrings.length]; for (int i = 0; i < rangeStrings.length; i++) { String range = rangeStrings[i]; try { int hyphenpos = range.indexOf('-'); if (hyphenpos < 0) { ranges[0][i] = Integer.parseInt(range); ranges[1][i] = ranges[0][i]; } else { ranges[0][i] = Integer.parseInt(range.substring(0, hyphenpos)); ranges[1][i] = Integer.parseInt(range.substring(hyphenpos + 1)); } } catch (NumberFormatException nfe) { return null; } } return ranges; } /* * Get all AlignFrames or just one if requested to work on a specific window (fromId query string parameter) */ protected AlignFrame[] getAlignFrames(HttpServletRequest request, boolean all) { return getAlignFrames(request, "fromId", all); } protected AlignFrame[] getAlignFrames(HttpServletRequest request, String idParam, boolean all) { String fromIdString = this.getQueryParameter(request, idParam); if (fromIdString != null) { AlignFrame af = AlignFrame.getAlignFrameFromRestId(fromIdString); return af == null ? null : new AlignFrame[] { af }; } else if (all) { return Desktop.getAlignFrames(); } else { return null; } } protected AlignFrame getAlignFrameFromId(HttpServletRequest request) { return getAlignFrameFromId(request, "fromId"); } protected AlignFrame getAlignFrameFromId(HttpServletRequest request, String idParam) { AlignFrame[] afs = getAlignFrames(request, idParam, false); return (afs == null || afs.length < 1) ? null : afs[0]; } protected boolean deleteFromCache() { return false; } }