JAL-3019 correctly form toRange of 'traversed' MapList
[jalview.git] / src / jalview / ext / ensembl / EnsemblInfo.java
1 package jalview.ext.ensembl;
2
3 import jalview.datamodel.AlignmentI;
4 import jalview.datamodel.DBRefSource;
5
6 import java.io.BufferedReader;
7 import java.io.IOException;
8 import java.net.MalformedURLException;
9 import java.net.URL;
10 import java.util.HashMap;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15
16 import org.json.simple.JSONArray;
17 import org.json.simple.parser.JSONParser;
18 import org.json.simple.parser.ParseException;
19
20 public class EnsemblInfo extends EnsemblRestClient
21 {
22
23   /*
24    * cached results of REST /info/divisions service, currently
25    * <pre>
26    * { 
27    *  { "ENSEMBLFUNGI", "http://rest.ensemblgenomes.org"},
28    *    "ENSEMBLBACTERIA", "http://rest.ensemblgenomes.org"},
29    *    "ENSEMBLPROTISTS", "http://rest.ensemblgenomes.org"},
30    *    "ENSEMBLMETAZOA", "http://rest.ensemblgenomes.org"},
31    *    "ENSEMBLPLANTS",  "http://rest.ensemblgenomes.org"},
32    *    "ENSEMBL", "http://rest.ensembl.org" }
33    *  }
34    * </pre>
35    * The values for EnsemblGenomes are retrieved by a REST call, that for
36    * Ensembl is added programmatically for convenience of lookup
37    */
38   private static Map<String, String> divisions;
39
40   @Override
41   public String getDbName()
42   {
43     return "ENSEMBL";
44   }
45
46   @Override
47   public AlignmentI getSequenceRecords(String queries) throws Exception
48   {
49     return null;
50   }
51
52   @Override
53   protected URL getUrl(List<String> ids) throws MalformedURLException
54   {
55     return null;
56   }
57
58   @Override
59   protected boolean useGetRequest()
60   {
61     return true;
62   }
63
64   @Override
65   protected String getRequestMimeType(boolean multipleIds)
66   {
67     return "application/json";
68   }
69
70   @Override
71   protected String getResponseMimeType()
72   {
73     return "application/json";
74   }
75
76   /**
77    * Answers the domain (http://rest.ensembl.org or
78    * http://rest.ensemblgenomes.org) for the given division, or null if not
79    * recognised by Ensembl.
80    * 
81    * @param division
82    * @return
83    */
84   public String getDomain(String division)
85   {
86     if (divisions == null)
87     {
88       fetchDivisions();
89     }
90     return divisions.get(division.toUpperCase());
91   }
92
93   /**
94    * On first request only, populate the lookup map by fetching the list of
95    * divisions known to EnsemblGenomes.
96    */
97   void fetchDivisions()
98   {
99     divisions = new HashMap<>();
100
101     /*
102      * for convenience, pre-fill ensembl.org as the domain for "ENSEMBL"
103      */
104     divisions.put(DBRefSource.ENSEMBL.toUpperCase(), ensemblDomain);
105
106     BufferedReader br = null;
107     try
108     {
109       URL url = getDivisionsUrl(ensemblGenomesDomain);
110       if (url != null)
111       {
112         br = getHttpResponse(url, null);
113       }
114       parseResponse(br, ensemblGenomesDomain);
115     } catch (IOException e)
116     {
117       // ignore
118     } finally
119     {
120       if (br != null)
121       {
122         try
123         {
124           br.close();
125         } catch (IOException e)
126         {
127           // ignore
128         }
129       }
130     }
131   }
132
133   /**
134    * Parses the JSON response to /info/divisions, and add each to the lookup map
135    * 
136    * @param br
137    * @param domain
138    */
139   void parseResponse(BufferedReader br, String domain)
140   {
141     JSONParser jp = new JSONParser();
142
143     try
144     {
145       JSONArray parsed = (JSONArray) jp.parse(br);
146
147       Iterator rvals = parsed.iterator();
148       while (rvals.hasNext())
149       {
150         String division = rvals.next().toString();
151         divisions.put(division.toUpperCase(), domain);
152       }
153     } catch (IOException | ParseException | NumberFormatException e)
154     {
155       // ignore
156     }
157   }
158
159   /**
160    * Constructs the URL for the EnsemblGenomes /info/divisions REST service
161    * @param domain TODO
162    * 
163    * @return
164    * @throws MalformedURLException
165    */
166   URL getDivisionsUrl(String domain) throws MalformedURLException
167   {
168     return new URL(domain
169             + "/info/divisions?content-type=application/json");
170   }
171
172   /**
173    * Returns the set of 'divisions' recognised by Ensembl or EnsemblGenomes
174    * 
175    * @return
176    */
177   public Set<String> getDivisions() {
178     if (divisions == null)
179     {
180       fetchDivisions();
181     }
182
183     return divisions.keySet();
184   }
185 }