/* * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.ws.ebi; import jalview.datamodel.DBRefSource; import jalview.util.MessageManager; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; /** * DOCUMENT ME! * * @author $author$ * @version $Revision$ */ public class EBIFetchClient { /** * Creates a new EBIFetchClient object. */ public EBIFetchClient() { } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public String[] getSupportedDBs() { // TODO - implement rest call for dbfetch getSupportedDBs throw new Error(MessageManager.getString("error.not_yet_implemented")); } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public String[] getSupportedFormats() { // TODO - implement rest call for dbfetch getSupportedFormats throw new Error(MessageManager.getString("error.not_yet_implemented")); } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public String[] getSupportedStyles() { // TODO - implement rest call for dbfetch getSupportedStyles throw new Error(MessageManager.getString("error.not_yet_implemented")); } /** * Send an HTTP fetch request to EBI and save the reply in a temporary file. * * @param ids * the query formatted as db:query1;query2;query3 * @param format * the format wanted * @param extension * for the temporary file to hold response (without separator) * @return the file holding the response * @throws OutOfMemoryError */ public File fetchDataAsFile(String ids, String format, String ext) throws OutOfMemoryError { File outFile = null; try { outFile = File.createTempFile("jalview", "." + ext); outFile.deleteOnExit(); fetchData(ids, format, outFile); if (outFile.length() == 0) { outFile.delete(); return null; } } catch (Exception ex) { } return outFile; } /** * Fetches queries and either saves the response to a file or returns as * string data * * @param ids * @param format * @param outFile * @return * @throws OutOfMemoryError */ String[] fetchData(String ids, String format, File outFile) throws OutOfMemoryError { StringBuilder querystring = new StringBuilder(ids.length()); String database = parseIds(ids, querystring); if (database == null) { System.err.println("Invalid Query string : '" + ids + "'"); System.err.println("Should be of form 'dbname:q1;q2;q3;q4'"); return null; } // note: outFile is currently always specified, so return value is null String[] rslt = fetchBatch(querystring.toString(), database, format, outFile); return (rslt != null && rslt.length > 0 ? rslt : null); } /** * Parses ids formatted as dbname:q1;q2;q3, returns the dbname and adds * queries as comma-separated items to the querystring. dbname must be * specified for at least one queryId. Returns null if a mixture of different * dbnames is found (ignoring case). * * @param ids * @param queryString * @return */ static String parseIds(String ids, StringBuilder queryString) { String database = null; StringTokenizer queries = new StringTokenizer(ids, ";"); boolean appending = queryString.length() > 0; while (queries.hasMoreTokens()) { String query = queries.nextToken(); int p = query.indexOf(':'); if (p > -1) { String db = query.substring(0, p); if (database != null && !db.equalsIgnoreCase(database)) { /* * different databases mixed in together - invalid */ return null; } database = db; query = query.substring(p + 1); } queryString.append(appending ? "," : ""); queryString.append(query); appending = true; } return database; } /** * Fetches queries and either saves the response to a file or (if no file * specified) returns as string data * * @param ids * @param database * @param format * @param outFile * @return * @throws OutOfMemoryError */ String[] fetchBatch(String ids, String database, String format, File outFile) throws OutOfMemoryError { // long time = System.currentTimeMillis(); String url = buildUrl(ids, database, format); try { URL rcall = new URL(url); HttpURLConnection conn = (HttpURLConnection) rcall.openConnection(); int responseCode = conn.getResponseCode(); if (responseCode != 200) { System.err.println("Warning: response code " + responseCode + " for " + url); } InputStream is = new BufferedInputStream(conn.getInputStream()); if (outFile != null) { FileOutputStream fio = new FileOutputStream(outFile); byte[] bb = new byte[32 * 1024]; int l; while ((l = is.read(bb)) > 0) { fio.write(bb, 0, l); } fio.close(); is.close(); } else { BufferedReader br = new BufferedReader(new InputStreamReader(is)); String rtn; List arl = new ArrayList(); while ((rtn = br.readLine()) != null) { arl.add(rtn); } return arl.toArray(new String[arl.size()]); } } catch (OutOfMemoryError er) { System.out.println("OUT OF MEMORY DOWNLOADING QUERY FROM " + database + ":\n" + ids); throw er; } catch (Exception ex) { if (ex.getMessage().startsWith( "uk.ac.ebi.jdbfetch.exceptions.DbfNoEntryFoundException")) { return null; } System.err.println("Unexpected exception when retrieving from " + database + "\nQuery was : '" + ids + "'"); ex.printStackTrace(System.err); return null; } finally { // System.err.println("EBIFetch took " + (System.currentTimeMillis() - // time) + " ms"); } return null; } /** * Constructs the URL to fetch from * * @param ids * @param database * @param format * @return */ static String buildUrl(String ids, String database, String format) { String url; if (database.equalsIgnoreCase(DBRefSource.EMBL) || database.equalsIgnoreCase(DBRefSource.EMBLCDS)) { url = "https://www.ebi.ac.uk/ena/data/view/" + ids.toLowerCase() + (format != null ? "&" + format : ""); } else { url = "https://www.ebi.ac.uk/Tools/dbfetch/dbfetch/" + database.toLowerCase() + "/" + ids.toLowerCase() + (format != null ? "/" + format : ""); } return url; } }