package jalview.ext.ensembl; import jalview.io.FileParse; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; public class SeqFetcher { private final static String ENSEMBL_REST = "rest.ensembl.org"; private static final String SEQUENCE_ID_URL = "http://" + ENSEMBL_REST + "/sequence/id"; private static final String PING_URL = "http://" + ENSEMBL_REST + "/info/ping"; private final static long RETEST_INTERVAL = 10000L; // 10 seconds private static boolean ensemblRestAvailable = false; private static long lastCheck = -1; /** * Rechecks if Ensembl is responding, unless the last check was successful and * the retest interval has not yet elapsed. Returns true if Ensembl is up, * else false. * * @return */ public boolean isEnsemblAvailable() { long now = System.currentTimeMillis(); boolean retest = now - lastCheck > RETEST_INTERVAL; if (ensemblRestAvailable && !retest) { return true; } ensemblRestAvailable = checkEnsembl(); lastCheck = now; return ensemblRestAvailable; } /** * Tries to connect to Ensembl's REST 'ping' endpoint, and returns true if * successful, else false * * @return */ private boolean checkEnsembl() { try { URL ping = new URL(PING_URL); HttpURLConnection conn = (HttpURLConnection) ping.openConnection(); int rc = conn.getResponseCode(); conn.disconnect(); if (rc >= 200 && rc < 300) { return true; } } catch (Throwable t) { System.err.println("Error connecting to " + PING_URL + ": " + t.getMessage()); } return false; } public SeqFetcher() { } public enum EnsemblSeqType { GENOMIC("genomic"), CDS("cds"), TRANSCRIPT("cds"), PROTEIN("protein"), CDNA( "cdna"); private String type; EnsemblSeqType(String t) { type = t; } public String getType() { return type; } } /** * Returns a list of additional URL query parameters to specify the desired * sequence type (genomic/cds/protein etc), and data format Fasta * * @param type */ public List getAdditionalParameters(EnsemblSeqType type) { List params = new ArrayList(); params.add(new BasicNameValuePair("type", type.getType())); params.add(new BasicNameValuePair("content-type", "text/x-fasta")); return params; } /** * return a reader to a Fasta response from the Ensembl sequence endpoint * * @param returnType * @param ids * @return * @throws IOException */ public FileParse getSequenceReader(EnsemblSeqType returnType, List ids) throws IOException { // see http://rest.ensembl.org/documentation/info/sequence_id String urlstring = SEQUENCE_ID_URL; List vals = getAdditionalParameters(returnType); boolean first = true; for (NameValuePair nvp : vals) { urlstring += first ? "?" : "&"; first = false; urlstring += nvp.getName() + "=" + nvp.getValue(); } URL url = new URL(urlstring); URLConnection connection = url.openConnection(); HttpURLConnection httpConnection = (HttpURLConnection) connection; httpConnection.setRequestMethod("POST"); httpConnection.setRequestProperty("Content-Type", "application/json"); httpConnection.setRequestProperty("Accept", "text/x-fasta"); byte[] thepostbody; { StringBuilder postBody = new StringBuilder(); postBody.append("{\"ids\":["); first = true; for (String id : ids) { if (!first) { postBody.append(","); } first = false; postBody.append("\""); postBody.append(id.trim()); postBody.append("\""); } postBody.append("]}"); thepostbody = postBody.toString().getBytes(); } httpConnection.setRequestProperty("Content-Length", Integer.toString(thepostbody.length)); httpConnection.setUseCaches(false); httpConnection.setDoInput(true); httpConnection.setDoOutput(true); DataOutputStream wr = new DataOutputStream( httpConnection.getOutputStream()); wr.write(thepostbody); wr.flush(); wr.close(); InputStream response = connection.getInputStream(); int responseCode = httpConnection.getResponseCode(); if (responseCode != 200) { throw new RuntimeException( "Response code was not 200. Detected response was " + responseCode); } BufferedReader reader = null; reader = new BufferedReader(new InputStreamReader(response, "UTF-8")); FileParse fp = new FileParse(reader, url.toString(), "HTTP_POST"); return fp; } }