JAL-1705 include stop codons in derived CDS; support ensemblgenomes
[jalview.git] / src / jalview / ext / ensembl / EnsemblXref.java
1 package jalview.ext.ensembl;
2
3 import jalview.datamodel.AlignmentI;
4 import jalview.datamodel.DBRefEntry;
5 import jalview.util.DBRefUtils;
6
7 import java.io.BufferedReader;
8 import java.io.IOException;
9 import java.net.MalformedURLException;
10 import java.net.URL;
11 import java.util.ArrayList;
12 import java.util.Iterator;
13 import java.util.List;
14
15 import org.json.simple.JSONArray;
16 import org.json.simple.JSONObject;
17 import org.json.simple.parser.JSONParser;
18 import org.json.simple.parser.ParseException;
19
20 /**
21  * A class to fetch cross-references from Ensembl by calling the /xrefs REST
22  * service
23  * 
24  * @author gmcarstairs
25  * @see http://rest.ensembl.org/documentation/info/xref_id
26  */
27 class EnsemblXref extends EnsemblRestClient
28 {
29
30   /**
31    * Constructor given the target domain to fetch data from
32    * 
33    * @param d
34    */
35   public EnsemblXref(String d)
36   {
37     super(d);
38   }
39
40   @Override
41   public String getDbName()
42   {
43     return "ENSEMBL (xref)";
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 getUrl(ids.get(0));
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    * Calls the Ensembl xrefs REST endpoint and retrieves any cross-references
78    * ("primary_id") for the given identifier (Ensembl accession id) and database
79    * names. The "dbname" returned by Ensembl is canonicalised to Jalview's
80    * standard version, and a DBRefEntry constructed. If no databases are
81    * specified, all available cross-references are retrieved.
82    * 
83    * @param identifier
84    * @param databases
85    * @return
86    */
87   public List<DBRefEntry> getCrossReferences(String identifier,
88           List<String> databases)
89   {
90     List<DBRefEntry> result = new ArrayList<DBRefEntry>();
91     List<String> ids = new ArrayList<String>();
92     ids.add(identifier);
93
94     BufferedReader br = null;
95     try
96     {
97       URL url = getUrl(identifier);
98         if (url != null)
99         {
100           br = getHttpResponse(url, ids);
101         }
102       return (parseResponse(br, databases));
103     } catch (IOException e)
104     {
105       // ignore
106     } finally
107     {
108       if (br != null)
109       {
110         try
111         {
112           br.close();
113         } catch (IOException e)
114         {
115           // ignore
116         }
117       }
118     }
119
120     return result;
121   }
122
123   /**
124    * Parses "primary_id" and "dbname" values from the JSON response and
125    * constructs a DBRefEntry if the dbname is in the list supplied. Returns a
126    * list of DBRefEntry created.
127    * 
128    * @param br
129    * @param databases
130    * @return
131    * @throws IOException
132    */
133   protected List<DBRefEntry> parseResponse(BufferedReader br,
134           List<String> databases)
135           throws IOException
136   {
137     JSONParser jp = new JSONParser();
138     List<DBRefEntry> result = new ArrayList<DBRefEntry>();
139     try
140     {
141       JSONArray responses = (JSONArray) jp.parse(br);
142       Iterator rvals = responses.iterator();
143       while (rvals.hasNext())
144       {
145         JSONObject val = (JSONObject) rvals.next();
146         String dbName = val.get("dbname").toString();
147         if (databases != null && !databases.isEmpty()
148                 && !databases.contains(dbName))
149         {
150           continue;
151         }
152         String id = val.get("primary_id").toString();
153         if (dbName != null && id != null)
154         {
155           dbName = DBRefUtils.getCanonicalName(dbName);
156           DBRefEntry dbref = new DBRefEntry(dbName, "0", id);
157           result.add(dbref);
158         }
159       }
160     } catch (ParseException e)
161     {
162       // ignore
163     }
164     return result;
165   }
166
167   /**
168    * Returns the URL for the REST endpoint to fetch all cross-references for an
169    * identifier. Note this may return protein cross-references for nucleotide.
170    * Filter the returned list as required.
171    * 
172    * @param identifier
173    * @return
174    */
175   protected URL getUrl(String identifier)
176   {
177     String url = getDomain() + "/xrefs/id/" + identifier
178             + "?content-type=application/json&all_levels=1";
179     try
180     {
181       return new URL(url);
182     } catch (MalformedURLException e)
183     {
184       return null;
185     }
186   }
187
188 }