JAL-3851 Added GetCrossReferencesEndpoint. Quite a bit of refactorying of Async error...
[jalview.git] / src / jalview / rest / AbstractEndpoint.java
1 package jalview.rest;
2
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.PrintWriter;
6
7 import javax.servlet.http.HttpServletRequest;
8 import javax.servlet.http.HttpServletResponse;
9
10 import jalview.bin.Cache;
11 import jalview.gui.AlignFrame;
12 import jalview.gui.Desktop;
13 import jalview.rest.RestHandler.EndpointI;
14
15 public abstract class AbstractEndpoint implements EndpointI
16 {
17   private final String path;
18
19   private API api;
20
21   private final String name;
22
23   private final String parameters;
24
25   private final String description;
26
27   public AbstractEndpoint(API api, String path, String name,
28           String parameters, String description)
29   {
30     this.api = api;
31     this.path = path;
32     this.name = name;
33     this.parameters = parameters;
34     this.description = description;
35   }
36
37   public String getPath()
38   {
39     return this.path;
40   }
41
42   protected API getAPI()
43   {
44     return this.api;
45   }
46
47   public String getName()
48   {
49     return this.name;
50   }
51
52   public String getParameters()
53   {
54     return this.parameters;
55   }
56
57   public String getDescription()
58   {
59     return this.description;
60   }
61
62   public abstract void processEndpoint(HttpServletRequest request,
63           HttpServletResponse response);
64
65   /*
66    * Shared methods below here
67    */
68
69   protected String[] getEndpointPathParameters(HttpServletRequest request)
70   {
71     String pathInfo = request.getPathInfo();
72     int slashpos = pathInfo.indexOf('/', 1);
73     return slashpos < 1 ? null
74             : pathInfo.substring(slashpos + 1).split("/");
75   }
76
77   protected void returnError(HttpServletRequest request,
78           HttpServletResponse response, String message)
79   {
80     String okString = request.getParameter("ok");
81     boolean ok = (okString != null && okString.equalsIgnoreCase("true"));
82     response.setStatus(ok ? HttpServletResponse.SC_OK
83             : HttpServletResponse.SC_BAD_REQUEST);
84     String endpointName = getPath();
85     Cache.error(getAPI().getName() + " error: endpoint " + endpointName
86             + " failed: '" + message + "'");
87     try
88     {
89       PrintWriter writer = response.getWriter();
90       writer.write("message=Endpoint " + endpointName + ": " + message);
91     } catch (IOException e)
92     {
93       Cache.info(e);
94     }
95   }
96
97   protected String getRequestBody(HttpServletRequest request)
98           throws IOException
99   {
100     StringBuilder sb = new StringBuilder();
101     BufferedReader reader = request.getReader();
102     try
103     {
104       String line;
105       while ((line = reader.readLine()) != null)
106       {
107         sb.append(line).append('\n');
108       }
109     } finally
110     {
111       reader.close();
112     }
113     return sb.toString();
114   }
115
116   protected boolean checkParameters(HttpServletRequest request,
117           HttpServletResponse response, int i)
118   {
119     String[] parameters = getEndpointPathParameters(request);
120
121     // check we can run fetchsequence
122     if (parameters.length < i)
123     {
124       returnError(request, response,
125               "requires parameters:" + getParameters() + "\n" + getName()
126                       + ": " + getDescription());
127       return false;
128     }
129     return true;
130   }
131
132   public int[][] parseIntRanges(String rangesString)
133   {
134     if (rangesString.equals("*"))
135     {
136       return new int[][] { { -1 }, { -1 } };
137     }
138     String[] rangeStrings = rangesString.split(",");
139     int[][] ranges = new int[2][rangeStrings.length];
140     for (int i = 0; i < rangeStrings.length; i++)
141     {
142       String range = rangeStrings[i];
143       try
144       {
145         int hyphenpos = range.indexOf('-');
146         if (hyphenpos < 0)
147         {
148           ranges[0][i] = Integer.parseInt(range);
149           ranges[1][i] = ranges[0][i];
150         }
151         else
152         {
153           ranges[0][i] = Integer.parseInt(range.substring(0, hyphenpos));
154           ranges[1][i] = Integer.parseInt(range.substring(hyphenpos + 1));
155         }
156       } catch (NumberFormatException nfe)
157       {
158         return null;
159       }
160     }
161     return ranges;
162   }
163
164   /*
165    * Get all AlignFrames or just one if requested to work on a specific window (fromId query string parameter)
166    */
167   protected AlignFrame[] getAlignFrames(HttpServletRequest request,
168           boolean all)
169   {
170     return getAlignFrames(request, "fromId", all);
171   }
172
173   protected AlignFrame[] getAlignFrames(HttpServletRequest request,
174           String idParam, boolean all)
175   {
176     String fromIdString = request.getParameter(idParam);
177
178     if (fromIdString != null)
179     {
180       AlignFrame af = AlignFrame.getAlignFrameFromRestId(fromIdString);
181       return af == null ? null : new AlignFrame[] { af };
182     }
183     else if (all)
184     {
185       return Desktop.getAlignFrames();
186     }
187     else
188     {
189       return null;
190     }
191   }
192
193   protected AlignFrame getAlignFrameFromId(HttpServletRequest request)
194   {
195     return getAlignFrameFromId(request, "fromId");
196   }
197
198   protected AlignFrame getAlignFrameFromId(HttpServletRequest request,
199           String idParam)
200   {
201     AlignFrame[] afs = getAlignFrames(request, idParam, false);
202     return (afs == null || afs.length < 1 || afs[0] == null) ? null
203             : afs[0];
204   }
205
206 }