Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
EBIFetchClient | 46 | 73 | 33 |
1 | /* | |
2 | * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) | |
3 | * Copyright (C) $$Year-Rel$$ The Jalview Authors | |
4 | * | |
5 | * This file is part of Jalview. | |
6 | * | |
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. | |
11 | * | |
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. | |
16 | * | |
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. | |
20 | */ | |
21 | package jalview.ws.ebi; | |
22 | ||
23 | import java.io.BufferedReader; | |
24 | import java.io.File; | |
25 | import java.io.IOException; | |
26 | import java.io.InputStream; | |
27 | import java.io.InputStreamReader; | |
28 | import java.net.HttpURLConnection; | |
29 | import java.net.URL; | |
30 | import java.util.ArrayList; | |
31 | import java.util.List; | |
32 | import java.util.Locale; | |
33 | import java.util.StringTokenizer; | |
34 | ||
35 | import jalview.datamodel.DBRefSource; | |
36 | import jalview.util.HttpUtils; | |
37 | import jalview.util.MessageManager; | |
38 | import jalview.util.Platform; | |
39 | ||
40 | /** | |
41 | * DOCUMENT ME! | |
42 | * | |
43 | * @author $author$ | |
44 | * @version $Revision$ | |
45 | */ | |
46 | public class EBIFetchClient | |
47 | { | |
48 | ||
49 | /** | |
50 | * Creates a new EBIFetchClient object. | |
51 | */ | |
52 | 0 | public EBIFetchClient() |
53 | { | |
54 | } | |
55 | ||
56 | /** | |
57 | * DOCUMENT ME! | |
58 | * | |
59 | * @return DOCUMENT ME! | |
60 | */ | |
61 | 0 | public String[] getSupportedDBs() |
62 | { | |
63 | // TODO - implement rest call for dbfetch getSupportedDBs | |
64 | 0 | throw new Error(MessageManager.getString("error.not_yet_implemented")); |
65 | } | |
66 | ||
67 | /** | |
68 | * DOCUMENT ME! | |
69 | * | |
70 | * @return DOCUMENT ME! | |
71 | */ | |
72 | 0 | public String[] getSupportedFormats() |
73 | { | |
74 | // TODO - implement rest call for dbfetch getSupportedFormats | |
75 | 0 | throw new Error(MessageManager.getString("error.not_yet_implemented")); |
76 | } | |
77 | ||
78 | /** | |
79 | * DOCUMENT ME! | |
80 | * | |
81 | * @return DOCUMENT ME! | |
82 | */ | |
83 | 0 | public String[] getSupportedStyles() |
84 | { | |
85 | // TODO - implement rest call for dbfetch getSupportedStyles | |
86 | 0 | throw new Error(MessageManager.getString("error.not_yet_implemented")); |
87 | } | |
88 | ||
89 | /** | |
90 | * Send an HTTP fetch request to EBI and save the reply in a temporary file. | |
91 | * | |
92 | * @param ids | |
93 | * the query formatted as db:query1;query2;query3 | |
94 | * @param format | |
95 | * the format wanted | |
96 | * @param ext | |
97 | * for the temporary file to hold response (without separator) | |
98 | * @return the file holding the response | |
99 | * @throws OutOfMemoryError | |
100 | */ | |
101 | ||
102 | 0 | public File fetchDataAsFile(String ids, String format, String ext) |
103 | throws OutOfMemoryError | |
104 | { | |
105 | 0 | File outFile = null; |
106 | 0 | try |
107 | { | |
108 | 0 | outFile = File.createTempFile("jalview", "." + ext); |
109 | 0 | outFile.deleteOnExit(); |
110 | 0 | fetchData(ids, format, outFile); |
111 | 0 | if (outFile.length() == 0) |
112 | { | |
113 | 0 | outFile.delete(); |
114 | 0 | return null; |
115 | } | |
116 | } catch (Exception ex) | |
117 | { | |
118 | } | |
119 | 0 | return outFile; |
120 | } | |
121 | ||
122 | /** | |
123 | * Fetches queries and either saves the response to a file or returns as | |
124 | * string data | |
125 | * | |
126 | * @param ids | |
127 | * @param format | |
128 | * @param outFile | |
129 | * @return | |
130 | * @throws OutOfMemoryError | |
131 | */ | |
132 | 0 | String[] fetchData(String ids, String format, File outFile) |
133 | throws OutOfMemoryError | |
134 | { | |
135 | 0 | StringBuilder querystring = new StringBuilder(ids.length()); |
136 | 0 | String database = parseIds(ids, querystring); |
137 | 0 | if (database == null) |
138 | { | |
139 | 0 | jalview.bin.Console |
140 | .errPrintln("Invalid Query string : '" + ids + "'"); | |
141 | 0 | jalview.bin.Console |
142 | .errPrintln("Should be of form 'dbname:q1;q2;q3;q4'"); | |
143 | 0 | return null; |
144 | } | |
145 | ||
146 | // note: outFile is currently always specified, so return value is null | |
147 | 0 | String[] rslt = fetchBatch(querystring.toString(), database, format, |
148 | outFile); | |
149 | ||
150 | 0 | return (rslt != null && rslt.length > 0 ? rslt : null); |
151 | } | |
152 | ||
153 | /** | |
154 | * Parses ids formatted as dbname:q1;q2;q3, returns the dbname and adds | |
155 | * queries as comma-separated items to the querystring. dbname must be | |
156 | * specified for at least one queryId. Returns null if a mixture of different | |
157 | * dbnames is found (ignoring case). | |
158 | * | |
159 | * @param ids | |
160 | * @param queryString | |
161 | * @return | |
162 | */ | |
163 | 7 | static String parseIds(String ids, StringBuilder queryString) |
164 | { | |
165 | 7 | String database = null; |
166 | 7 | StringTokenizer queries = new StringTokenizer(ids, ";"); |
167 | 7 | boolean appending = queryString.length() > 0; |
168 | 19 | while (queries.hasMoreTokens()) |
169 | { | |
170 | 13 | String query = queries.nextToken(); |
171 | 13 | int p = query.indexOf(':'); |
172 | 13 | if (p > -1) |
173 | { | |
174 | 9 | String db = query.substring(0, p); |
175 | 9 | if (database != null && !db.equalsIgnoreCase(database)) |
176 | { | |
177 | /* | |
178 | * different databases mixed in together - invalid | |
179 | */ | |
180 | 1 | return null; |
181 | } | |
182 | 8 | database = db; |
183 | 8 | query = query.substring(p + 1); |
184 | } | |
185 | 12 | queryString.append(appending ? "," : ""); |
186 | 12 | queryString.append(query); |
187 | 12 | appending = true; |
188 | } | |
189 | 6 | return database; |
190 | } | |
191 | ||
192 | /** | |
193 | * Fetches queries and either saves the response to a file or (if no file | |
194 | * specified) returns as string data | |
195 | * | |
196 | * @param ids | |
197 | * @param database | |
198 | * @param format | |
199 | * @param outFile | |
200 | * @return array of lines from EBI only if outFile is null (which it will not | |
201 | * be) | |
202 | * @throws OutOfMemoryError | |
203 | */ | |
204 | 0 | String[] fetchBatch(String ids, String database, String format, |
205 | File outFile) throws OutOfMemoryError | |
206 | { | |
207 | 0 | String url = buildUrl(ids, database, format); |
208 | 0 | InputStream is = null; |
209 | 0 | BufferedReader br = null; |
210 | 0 | try |
211 | { | |
212 | 0 | URL rcall = new URL(url); |
213 | 0 | HttpURLConnection conn = (HttpURLConnection) HttpUtils |
214 | .openConnection(rcall); | |
215 | 0 | int responseCode = conn.getResponseCode(); |
216 | 0 | if (responseCode == 200) |
217 | { | |
218 | 0 | is = conn.getInputStream(); |
219 | 0 | if (outFile != null) |
220 | { | |
221 | 0 | Platform.streamToFile(is, outFile); |
222 | 0 | return null; |
223 | } | |
224 | 0 | br = new BufferedReader(new InputStreamReader(is)); |
225 | 0 | String rtn; |
226 | 0 | List<String> arl = new ArrayList<>(); |
227 | 0 | while ((rtn = br.readLine()) != null) |
228 | { | |
229 | 0 | arl.add(rtn); |
230 | } | |
231 | 0 | return (String[]) arl.toArray(); |
232 | } | |
233 | 0 | jalview.bin.Console.errPrintln( |
234 | "Warning: response code " + responseCode + " for " + url); | |
235 | } catch (OutOfMemoryError er) | |
236 | { | |
237 | 0 | jalview.bin.Console.outPrintln("OUT OF MEMORY DOWNLOADING QUERY FROM " |
238 | + database + ":\n" + ids); | |
239 | 0 | throw er; |
240 | } catch (Exception ex) | |
241 | { | |
242 | 0 | if (!ex.getMessage().startsWith( |
243 | "uk.ac.ebi.jdbfetch.exceptions.DbfNoEntryFoundException")) | |
244 | { | |
245 | 0 | jalview.bin.Console |
246 | .errPrintln("Unexpected exception when retrieving from " | |
247 | + database + "\nQuery was : '" + ids + "'"); | |
248 | 0 | ex.printStackTrace(System.err); |
249 | } | |
250 | } finally | |
251 | { | |
252 | 0 | if (is != null) |
253 | { | |
254 | 0 | try |
255 | { | |
256 | 0 | is.close(); |
257 | } catch (IOException e) | |
258 | { | |
259 | } | |
260 | } | |
261 | 0 | if (br != null) |
262 | { | |
263 | 0 | try |
264 | { | |
265 | 0 | br.close(); |
266 | } catch (IOException e) | |
267 | { | |
268 | } | |
269 | } | |
270 | } | |
271 | 0 | return null; |
272 | } | |
273 | ||
274 | 1 | static |
275 | { | |
276 | 1 | Platform.addJ2SDirectDatabaseCall("https://www.ebi.ac.uk/"); |
277 | } | |
278 | ||
279 | /** | |
280 | * Constructs the URL to fetch from | |
281 | * | |
282 | * @param ids | |
283 | * @param database | |
284 | * @param format | |
285 | * @return | |
286 | */ | |
287 | 4 | static String buildUrl(String ids, String database, String format) |
288 | { | |
289 | 4 | String url; |
290 | 4 | if (database.equalsIgnoreCase(DBRefSource.EMBL) |
291 | || database.equalsIgnoreCase(DBRefSource.EMBLCDS)) | |
292 | { | |
293 | 2 | url = "https://www.ebi.ac.uk/ena/browser/api/embl/" |
294 | + ids.toLowerCase(Locale.ROOT) + "?download=true&gzip=true"; | |
295 | } | |
296 | else | |
297 | { | |
298 | 2 | url = "https://www.ebi.ac.uk/Tools/dbfetch/dbfetch/" |
299 | + database.toLowerCase(Locale.ROOT) + "/" | |
300 | + ids.toLowerCase(Locale.ROOT) | |
301 | 2 | + (format != null ? "/" + format : ""); |
302 | } | |
303 | 4 | return url; |
304 | } | |
305 | } |