Merge commit '326d48e' into HEAD
[jalview.git] / src / jalview / ext / ensembl / EnsemblSymbol.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 java.io.BufferedReader;
24 import java.io.IOException;
25 import java.net.MalformedURLException;
26 import java.net.URL;
27 import java.util.ArrayList;
28 import java.util.Iterator;
29 import java.util.List;
30
31 import org.json.simple.JSONArray;
32 import org.json.simple.JSONObject;
33 import org.json.simple.parser.JSONParser;
34 import org.json.simple.parser.ParseException;
35
36 /**
37  * A client for the Ensembl xrefs/symbol REST service;
38  * 
39  * @see http://rest.ensembl.org/documentation/info/xref_external
40  * @author gmcarstairs
41  *
42  */
43 public class EnsemblSymbol extends EnsemblXref
44 {
45   /**
46    * Constructor given the target domain to fetch data from
47    * 
48    * @param domain
49    * @param dbName
50    * @param dbVersion
51    */
52   public EnsemblSymbol(String domain, String dbName, String dbVersion)
53   {
54     super(domain, dbName, dbVersion);
55   }
56
57   /**
58    * Returns the first "id" value in gene identifier format from the JSON
59    * response, or null if none found
60    * 
61    * @param br
62    * @return
63    * @throws IOException
64    */
65   protected String parseSymbolResponse(BufferedReader br)
66           throws IOException
67   {
68     JSONParser jp = new JSONParser();
69     String result = null;
70     try
71     {
72       JSONArray responses = (JSONArray) jp.parse(br);
73       Iterator rvals = responses.iterator();
74       while (rvals.hasNext())
75       {
76         JSONObject val = (JSONObject) rvals.next();
77         String id = val.get("id").toString();
78         String type = val.get("type").toString();
79         if (id != null && "gene".equals(type))
80         {
81           result = id;
82           break;
83         }
84       }
85     } catch (ParseException e)
86     {
87       // ignore
88     }
89     return result;
90   }
91
92   /**
93    * Constructs the URL for the REST symbol endpoint
94    * 
95    * @param id
96    *          the accession id (Ensembl or external)
97    * @param species
98    *          a species name recognisable by Ensembl
99    * @param type
100    *          an optional type to filter the response (gene, transcript,
101    *          translation)
102    * @return
103    */
104   protected URL getUrl(String id, Species species, String... type)
105   {
106     StringBuilder sb = new StringBuilder();
107     sb.append(getDomain()).append("/xrefs/symbol/")
108             .append(species.toString()).append("/").append(id)
109             .append("?content-type=application/json");
110     for (String t : type)
111     {
112       sb.append("&object_type=").append(t);
113     }
114     try
115     {
116       String url = sb.toString();
117       return new URL(url);
118     } catch (MalformedURLException e)
119     {
120       return null;
121     }
122   }
123
124   /**
125    * Calls the Ensembl xrefs REST 'symbol' endpoint and retrieves any gene ids
126    * for the given identifier, for any known model organisms
127    * 
128    * @param identifier
129    * @return
130    */
131   public List<String> getGeneIds(String identifier)
132   {
133     List<String> result = new ArrayList<String>();
134     List<String> ids = new ArrayList<String>();
135     ids.add(identifier);
136
137     String[] queries = identifier.split(getAccessionSeparator());
138     BufferedReader br = null;
139     try
140     {
141       for (String query : queries)
142       {
143         for (Species taxon : Species.values())
144         {
145           if (taxon.isModelOrganism())
146           {
147             URL url = getUrl(query, taxon, "gene");
148             if (url != null)
149             {
150               br = getHttpResponse(url, ids);
151               if (br != null)
152               {
153                 String geneId = parseSymbolResponse(br);
154                 if (geneId != null && !result.contains(geneId))
155                 {
156                   result.add(geneId);
157                 }
158               }
159             }
160           }
161         }
162       }
163     } catch (IOException e)
164     {
165       // ignore
166     } finally
167     {
168       if (br != null)
169       {
170         try
171         {
172           br.close();
173         } catch (IOException e)
174         {
175           // ignore
176         }
177       }
178     }
179     return result;
180   }
181
182 }