Push 1793 latest to spike branch
[jalview.git] / src / jalview / ext / ensembl / EnsemblInfo.java
index 3108194..de55a53 100644 (file)
-/*
- * 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 <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
 package jalview.ext.ensembl;
 
-/**
- * A data class to model the data and rest version of one Ensembl domain,
- * currently for rest.ensembl.org and rest.ensemblgenomes.org
- * 
- * @author gmcarstairs
- */
-class EnsemblInfo
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.DBRefSource;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.json.simple.JSONArray;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+public class EnsemblInfo extends EnsemblRestClient
 {
-  /*
-   * The http domain this object is holding data values for
-   */
-  String domain;
 
   /*
-   * The latest version Jalview has tested for, e.g. "4.5"; a minor version change should be
-   * ok, a major version change may break stuff 
+   * cached results of REST /info/divisions service, currently
+   * <pre>
+   * { 
+   *  { "ENSEMBLFUNGI", "http://rest.ensemblgenomes.org"},
+   *    "ENSEMBLBACTERIA", "http://rest.ensemblgenomes.org"},
+   *    "ENSEMBLPROTISTS", "http://rest.ensemblgenomes.org"},
+   *    "ENSEMBLMETAZOA", "http://rest.ensemblgenomes.org"},
+   *    "ENSEMBLPLANTS",  "http://rest.ensemblgenomes.org"},
+   *    "ENSEMBL", "http://rest.ensembl.org" }
+   *  }
+   * </pre>
+   * The values for EnsemblGenomes are retrieved by a REST call, that for
+   * Ensembl is added programmatically for convenience of lookup
    */
-  String expectedRestVersion;
+  private static Map<String, String> divisions;
 
-  /*
-   * Major / minor / point version e.g. "4.5.1"
-   * @see http://rest.ensembl.org/info/rest/?content-type=application/json
-   */
-  String restVersion;
+  @Override
+  public String getDbName()
+  {
+    return "ENSEMBL";
+  }
 
-  /*
-   * data version
-   * @see http://rest.ensembl.org/info/data/?content-type=application/json
-   */
-  String dataVersion;
+  @Override
+  public AlignmentI getSequenceRecords(String queries) throws Exception
+  {
+    return null;
+  }
 
-  /*
-   * true when http://rest.ensembl.org/info/ping/?content-type=application/json
-   * returns response code 200 and not {"error":"Database is unavailable"}
-   */
-  boolean restAvailable;
+  @Override
+  protected URL getUrl(List<String> ids) throws MalformedURLException
+  {
+    return null;
+  }
 
-  /*
-   * absolute time when availability was last checked
+  @Override
+  protected boolean useGetRequest()
+  {
+    return true;
+  }
+
+  @Override
+  protected String getRequestMimeType(boolean multipleIds)
+  {
+    return "application/json";
+  }
+
+  @Override
+  protected String getResponseMimeType()
+  {
+    return "application/json";
+  }
+
+  /**
+   * Answers the domain (http://rest.ensembl.org or
+   * http://rest.ensemblgenomes.org) for the given division, or null if not
+   * recognised by Ensembl.
+   * 
+   * @param division
+   * @return
    */
-  long lastAvailableCheckTime;
+  public String getDomain(String division)
+  {
+    if (divisions == null)
+    {
+      fetchDivisions();
+    }
+    return divisions.get(division.toUpperCase());
+  }
 
-  /*
-   * absolute time when version numbers were last checked
+  /**
+   * On first request only, populate the lookup map by fetching the list of
+   * divisions known to EnsemblGenomes.
    */
-  long lastVersionCheckTime;
+  void fetchDivisions()
+  {
+    divisions = new HashMap<>();
 
-  // flag set to true if REST major version is not the one expected
-  boolean restMajorVersionMismatch;
+    /*
+     * for convenience, pre-fill ensembl.org as the domain for "ENSEMBL"
+     */
+    divisions.put(DBRefSource.ENSEMBL.toUpperCase(), ENSEMBL_REST);
 
-  /*
-   * absolute time to wait till if we overloaded the REST service
+    BufferedReader br = null;
+    try
+    {
+      URL url = getDivisionsUrl(ENSEMBL_GENOMES_REST);
+      if (url != null)
+      {
+        br = getHttpResponse(url, null);
+      }
+      parseResponse(br, ENSEMBL_GENOMES_REST);
+    } catch (IOException e)
+    {
+      // ignore
+    } finally
+    {
+      if (br != null)
+      {
+        try
+        {
+          br.close();
+        } catch (IOException e)
+        {
+          // ignore
+        }
+      }
+    }
+  }
+
+  /**
+   * Parses the JSON response to /info/divisions, and add each to the lookup map
+   * 
+   * @param br
+   * @param domain
    */
-  long retryAfter;
+  void parseResponse(BufferedReader br, String domain)
+  {
+    JSONParser jp = new JSONParser();
+
+    try
+    {
+      JSONArray parsed = (JSONArray) jp.parse(br);
+
+      Iterator rvals = parsed.iterator();
+      while (rvals.hasNext())
+      {
+        String division = rvals.next().toString();
+        divisions.put(division.toUpperCase(), domain);
+      }
+    } catch (IOException | ParseException | NumberFormatException e)
+    {
+      // ignore
+    }
+  }
 
   /**
-   * Constructor given expected REST version number e.g 4.5 or 3.4.3
+   * Constructs the URL for the EnsemblGenomes /info/divisions REST service
+   * @param domain TODO
    * 
-   * @param restExpected
+   * @return
+   * @throws MalformedURLException
    */
-  EnsemblInfo(String theDomain, String restExpected)
+  URL getDivisionsUrl(String domain) throws MalformedURLException
   {
-    domain = theDomain;
-    expectedRestVersion = restExpected;
-    lastAvailableCheckTime = -1;
-    lastVersionCheckTime = -1;
+    return new URL(domain
+            + "/info/divisions?content-type=application/json");
   }
 
+  /**
+   * Returns the set of 'divisions' recognised by Ensembl or EnsemblGenomes
+   * 
+   * @return
+   */
+  public Set<String> getDivisions() {
+    if (divisions == null)
+    {
+      fetchDivisions();
+    }
+
+    return divisions.keySet();
+  }
 }