JAL-1705 DbSourceProxy properties converted to methods, tidy/format code
[jalview.git] / src / jalview / ext / ensembl / SeqFetcher.java
index 7c913bf..57f000f 100644 (file)
@@ -10,7 +10,7 @@ import java.io.InputStreamReader;
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.net.URLConnection;
-import java.util.Collections;
+import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.http.NameValuePair;
@@ -20,81 +20,60 @@ public class SeqFetcher
 {
   private final static String ENSEMBL_REST = "rest.ensembl.org";
 
-  private static boolean ensemblRestavailable = false;
+  private static final String SEQUENCE_ID_URL = "http://" + ENSEMBL_REST + "/sequence/id";
 
-  private static long lastCheck = -1;
+  private static final String PING_URL = "http://" + ENSEMBL_REST + "/info/ping";
 
-  public boolean isEnsemblAvailable()
-  {
-    if (isTesting || !ensemblRestavailable
-            || System.currentTimeMillis() - lastCheck > 10000)
-    {
-      checkEnsembl();
-      lastCheck = System.currentTimeMillis();
-    }
-    return ensemblRestavailable;
-  }
-
-  private boolean isTesting, testEnsemblStatus;
+  private final static long RETEST_INTERVAL = 10000L; // 10 seconds
 
-  /**
-   * @return the isTesting
-   */
-  public boolean isTesting()
-  {
-    return isTesting;
-  }
+  private static boolean ensemblRestAvailable = false;
 
-  /**
-   * @param isTesting
-   *          the isTesting to set
-   */
-  public void setTesting(boolean isTesting)
-  {
-    this.isTesting = isTesting;
-  }
+  private static long lastCheck = -1;
 
   /**
-   * @return the testEnsemblStatus
+   * 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 isTestEnsemblStatus()
+  public boolean isEnsemblAvailable()
   {
-    return testEnsemblStatus;
+    long now = System.currentTimeMillis();
+    boolean retest = now - lastCheck > RETEST_INTERVAL;
+    if (ensemblRestAvailable && !retest)
+    {
+      return true;
+    }
+    ensemblRestAvailable = checkEnsembl();
+    lastCheck = now;
+    return ensemblRestAvailable;
   }
 
   /**
-   * @param testEnsemblStatus
-   *          the testEnsemblStatus to set
+   * Tries to connect to Ensembl's REST 'ping' endpoint, and returns true if
+   * successful, else false
+   * 
+   * @return
    */
-  public void setTestEnsemblStatus(boolean testEnsemblStatus)
+  private boolean checkEnsembl()
   {
-    this.testEnsemblStatus = testEnsemblStatus;
-  }
-
-  private void checkEnsembl()
-  {
-    if (isTesting)
-    {
-      ensemblRestavailable = testEnsemblStatus;
-      return;
-    }
     try
     {
-      URL ping = new URL("http://" + ENSEMBL_REST + "/info/ping");
-      HttpURLConnection conn = (HttpURLConnection) (ping.openConnection());
-      if (conn.getResponseCode() >= 200 && conn.getResponseCode() < 300)
+      URL ping = new URL(PING_URL);
+      HttpURLConnection conn = (HttpURLConnection) ping.openConnection();
+      int rc = conn.getResponseCode();
+      conn.disconnect();
+      if (rc >= 200 && rc < 300)
       {
-        ensemblRestavailable = true;
-        return;
+        return true;
       }
-    } catch (Error err)
-    {
-      err.printStackTrace();
-    } catch (Exception exx)
+    } catch (Throwable t)
     {
-      exx.printStackTrace();
+      System.err.println("Error connecting to " + PING_URL + ": "
+              + t.getMessage());
     }
-    ensemblRestavailable = false;
+    return false;
   }
 
   public SeqFetcher()
@@ -120,14 +99,17 @@ public class SeqFetcher
   }
 
   /**
-   * reolve request type as an argument for sequence and features queries
+   * 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<NameValuePair> getObjectTypeArg(EnsemblSeqType type)
+  public List<NameValuePair> getAdditionalParameters(EnsemblSeqType type)
   {
-    NameValuePair nameValue = new BasicNameValuePair("type", type.getType());
-    return Collections.singletonList(nameValue);
+    List<NameValuePair> params = new ArrayList<NameValuePair>();
+    params.add(new BasicNameValuePair("type", type.getType()));
+    params.add(new BasicNameValuePair("content-type", "text/x-fasta"));
+    return params;
   }
 
   /**
@@ -141,27 +123,19 @@ public class SeqFetcher
   public FileParse getSequenceReader(EnsemblSeqType returnType,
           List<String> ids) throws IOException
   {
+    // see http://rest.ensembl.org/documentation/info/sequence_id
 
-    // adapted From the rest.ensembl.org documentation for sequence_id
-
-    String urls = "http://" + ENSEMBL_REST + "/sequence/id";
-    List<NameValuePair> vals = getObjectTypeArg(returnType);
-    boolean f = true;
+    String urlstring = SEQUENCE_ID_URL;
+    List<NameValuePair> vals = getAdditionalParameters(returnType);
+    boolean first = true;
     for (NameValuePair nvp : vals)
     {
-      if (f)
-      {
-        f = false;
-        urls += "?";
-      }
-      else
-      {
-        urls += "&";
-      }
-      urls += nvp.getName() + "=" + nvp.getValue();
+      urlstring += first ? "?" : "&";
+      first = false;
+      urlstring += nvp.getName() + "=" + nvp.getValue();
     }
 
-    URL url = new URL(urls);
+    URL url = new URL(urlstring);
 
     URLConnection connection = url.openConnection();
     HttpURLConnection httpConnection = (HttpURLConnection) connection;
@@ -173,17 +147,14 @@ public class SeqFetcher
     {
       StringBuilder postBody = new StringBuilder();
       postBody.append("{\"ids\":[");
-      boolean first = true;
+      first = true;
       for (String id : ids)
       {
-        if (first)
-        {
-          first = false;
-        }
-        else
+        if (!first)
         {
           postBody.append(",");
         }
+        first = false;
         postBody.append("\"");
         postBody.append(id.trim());
         postBody.append("\"");