Merge branch 'documentation/JAL-3407_2.11.1_release' into releases/Release_2_11_1_Branch
[jalview.git] / src / jalview / ext / ensembl / EnsemblInfo.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.ext.ensembl;
22
23 import jalview.datamodel.AlignmentI;
24 import jalview.datamodel.DBRefSource;
25
26 import java.io.BufferedReader;
27 import java.io.IOException;
28 import java.net.MalformedURLException;
29 import java.net.URL;
30 import java.util.HashMap;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Set;
35
36 import org.json.simple.JSONArray;
37 import org.json.simple.parser.JSONParser;
38 import org.json.simple.parser.ParseException;
39
40 public class EnsemblInfo extends EnsemblRestClient
41 {
42
43   /*
44    * cached results of REST /info/divisions service, currently
45    * <pre>
46    * { 
47    *  { "ENSEMBLFUNGI", "http://rest.ensemblgenomes.org"},
48    *    "ENSEMBLBACTERIA", "http://rest.ensemblgenomes.org"},
49    *    "ENSEMBLPROTISTS", "http://rest.ensemblgenomes.org"},
50    *    "ENSEMBLMETAZOA", "http://rest.ensemblgenomes.org"},
51    *    "ENSEMBLPLANTS",  "http://rest.ensemblgenomes.org"},
52    *    "ENSEMBL", "http://rest.ensembl.org" }
53    *  }
54    * </pre>
55    * The values for EnsemblGenomes are retrieved by a REST call, that for
56    * Ensembl is added programmatically for convenience of lookup
57    */
58   private static Map<String, String> divisions;
59
60   @Override
61   public String getDbName()
62   {
63     return "ENSEMBL";
64   }
65
66   @Override
67   public AlignmentI getSequenceRecords(String queries) throws Exception
68   {
69     return null;
70   }
71
72   @Override
73   protected URL getUrl(List<String> ids) throws MalformedURLException
74   {
75     return null;
76   }
77
78   @Override
79   protected boolean useGetRequest()
80   {
81     return true;
82   }
83
84   /**
85    * Answers the domain (http://rest.ensembl.org or
86    * http://rest.ensemblgenomes.org) for the given division, or null if not
87    * recognised by Ensembl.
88    * 
89    * @param division
90    * @return
91    */
92   public String getDomain(String division)
93   {
94     if (divisions == null)
95     {
96       fetchDivisions();
97     }
98     return divisions.get(division.toUpperCase());
99   }
100
101   /**
102    * On first request only, populate the lookup map by fetching the list of
103    * divisions known to EnsemblGenomes.
104    */
105   void fetchDivisions()
106   {
107     divisions = new HashMap<>();
108
109     /*
110      * for convenience, pre-fill ensembl.org as the domain for "ENSEMBL"
111      */
112     divisions.put(DBRefSource.ENSEMBL.toUpperCase(), ensemblDomain);
113
114     BufferedReader br = null;
115     try
116     {
117       URL url = getDivisionsUrl(ensemblGenomesDomain);
118       if (url != null)
119       {
120         br = getHttpResponse(url, null);
121       }
122       parseResponse(br, ensemblGenomesDomain);
123     } catch (IOException e)
124     {
125       // ignore
126     } finally
127     {
128       if (br != null)
129       {
130         try
131         {
132           br.close();
133         } catch (IOException e)
134         {
135           // ignore
136         }
137       }
138     }
139   }
140
141   /**
142    * Parses the JSON response to /info/divisions, and add each to the lookup map
143    * 
144    * @param br
145    * @param domain
146    */
147   void parseResponse(BufferedReader br, String domain)
148   {
149     JSONParser jp = new JSONParser();
150
151     try
152     {
153       JSONArray parsed = (JSONArray) jp.parse(br);
154
155       Iterator rvals = parsed.iterator();
156       while (rvals.hasNext())
157       {
158         String division = rvals.next().toString();
159         divisions.put(division.toUpperCase(), domain);
160       }
161     } catch (IOException | ParseException | NumberFormatException e)
162     {
163       // ignore
164     }
165   }
166
167   /**
168    * Constructs the URL for the EnsemblGenomes /info/divisions REST service
169    * @param domain TODO
170    * 
171    * @return
172    * @throws MalformedURLException
173    */
174   URL getDivisionsUrl(String domain) throws MalformedURLException
175   {
176     return new URL(domain
177             + "/info/divisions?content-type=application/json");
178   }
179
180   /**
181    * Returns the set of 'divisions' recognised by Ensembl or EnsemblGenomes
182    * 
183    * @return
184    */
185   public Set<String> getDivisions() {
186     if (divisions == null)
187     {
188       fetchDivisions();
189     }
190
191     return divisions.keySet();
192   }
193 }