JAL-2321 ensure default is ‘parseImmediately=true’
[jalview.git] / src / jalview / ext / ensembl / EnsemblLookup.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
25 import java.io.BufferedReader;
26 import java.io.IOException;
27 import java.net.MalformedURLException;
28 import java.net.URL;
29 import java.util.Arrays;
30 import java.util.List;
31
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 lookup REST endpoint, used to find the gene
38  * identifier given a gene, transcript or protein identifier.
39  * 
40  * @author gmcarstairs
41  */
42 public class EnsemblLookup extends EnsemblRestClient
43 {
44   /**
45    * Default constructor (to use rest.ensembl.org)
46    */
47   public EnsemblLookup()
48   {
49     super();
50   }
51
52   /**
53    * Constructor given the target domain to fetch data from
54    * 
55    * @param
56    */
57   public EnsemblLookup(String d)
58   {
59     super(d);
60   }
61
62   @Override
63   public String getDbName()
64   {
65     return "ENSEMBL";
66   }
67
68   @Override
69   public AlignmentI getSequenceRecords(String queries) throws Exception
70   {
71     return null;
72   }
73
74   @Override
75   protected URL getUrl(List<String> ids) throws MalformedURLException
76   {
77     String identifier = ids.get(0);
78     return getUrl(identifier, null);
79   }
80
81   /**
82    * Gets the url for lookup of the given identifier, optionally with objectType
83    * also specified in the request
84    * 
85    * @param identifier
86    * @param objectType
87    * @return
88    */
89   protected URL getUrl(String identifier, String objectType)
90   {
91     String url = getDomain() + "/lookup/id/" + identifier
92             + CONTENT_TYPE_JSON;
93     if (objectType != null)
94     {
95       url += "&" + OBJECT_TYPE + "=" + objectType;
96     }
97
98     try
99     {
100       return new URL(url);
101     } catch (MalformedURLException e)
102     {
103       return null;
104     }
105   }
106
107   @Override
108   protected boolean useGetRequest()
109   {
110     return true;
111   }
112
113   @Override
114   protected String getRequestMimeType(boolean multipleIds)
115   {
116     return "application/json";
117   }
118
119   @Override
120   protected String getResponseMimeType()
121   {
122     return "application/json";
123   }
124
125   /**
126    * Returns the gene id related to the given identifier, which may be for a
127    * gene, transcript or protein
128    * 
129    * @param identifier
130    * @return
131    */
132   public String getGeneId(String identifier)
133   {
134     return getGeneId(identifier, null);
135   }
136
137   /**
138    * Returns the gene id related to the given identifier (which may be for a
139    * gene, transcript or protein)
140    * 
141    * @param identifier
142    * @param objectType
143    * @return
144    */
145   public String getGeneId(String identifier, String objectType)
146   {
147     List<String> ids = Arrays.asList(new String[] { identifier });
148
149     BufferedReader br = null;
150     try
151     {
152       URL url = getUrl(identifier, objectType);
153       if (url != null)
154       {
155         br = getHttpResponse(url, ids);
156       }
157       return br == null ? null : parseResponse(br);
158     } catch (IOException e)
159     {
160       // ignore
161       return null;
162     } finally
163     {
164       if (br != null)
165       {
166         try
167         {
168           br.close();
169         } catch (IOException e)
170         {
171           // ignore
172         }
173       }
174     }
175   }
176
177   /**
178    * Parses the JSON response and returns the gene identifier, or null if not
179    * found. If the returned object_type is Gene, returns the id, if Transcript
180    * returns the Parent. If it is Translation (peptide identifier), then the
181    * Parent is the transcript identifier, so we redo the search with this value.
182    * 
183    * @param br
184    * @return
185    * @throws IOException
186    */
187   protected String parseResponse(BufferedReader br) throws IOException
188   {
189     String geneId = null;
190     JSONParser jp = new JSONParser();
191     try
192     {
193       JSONObject val = (JSONObject) jp.parse(br);
194       String type = val.get(OBJECT_TYPE).toString();
195       if (OBJECT_TYPE_GENE.equalsIgnoreCase(type))
196       {
197         // got the gene - just returns its id
198         geneId = val.get(ID).toString();
199       }
200       else if (OBJECT_TYPE_TRANSCRIPT.equalsIgnoreCase(type))
201       {
202         // got the transcript - return its (Gene) Parent
203         geneId = val.get(PARENT).toString();
204       }
205       else if (OBJECT_TYPE_TRANSLATION.equalsIgnoreCase(type))
206       {
207         // got the protein - get its Parent, restricted to type Transcript
208         String transcriptId = val.get(PARENT).toString();
209         geneId = getGeneId(transcriptId, OBJECT_TYPE_TRANSCRIPT);
210       }
211     } catch (ParseException e)
212     {
213       // ignore
214     }
215     return geneId;
216   }
217
218 }