JAL-2113 embl_mapping.xml and code updated for EMBL XML v1.2
[jalview.git] / src / jalview / ws / ebi / EBIFetchClient.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.ws.ebi;
22
23 import jalview.datamodel.DBRefSource;
24 import jalview.util.MessageManager;
25
26 import java.io.BufferedInputStream;
27 import java.io.BufferedReader;
28 import java.io.File;
29 import java.io.FileOutputStream;
30 import java.io.InputStream;
31 import java.io.InputStreamReader;
32 import java.net.URL;
33 import java.util.ArrayList;
34 import java.util.List;
35 import java.util.StringTokenizer;
36
37 /**
38  * DOCUMENT ME!
39  * 
40  * @author $author$
41  * @version $Revision$
42  */
43 public class EBIFetchClient
44 {
45   String format = "default";
46
47   String style = "raw";
48
49   /**
50    * Creates a new EBIFetchClient object.
51    */
52   public EBIFetchClient()
53   {
54   }
55
56   /**
57    * DOCUMENT ME!
58    * 
59    * @return DOCUMENT ME!
60    */
61   public String[] getSupportedDBs()
62   {
63     // TODO - implement rest call for dbfetch getSupportedDBs
64     throw new Error(MessageManager.getString("error.not_yet_implemented"));
65   }
66
67   /**
68    * DOCUMENT ME!
69    * 
70    * @return DOCUMENT ME!
71    */
72   public String[] getSupportedFormats()
73   {
74     // TODO - implement rest call for dbfetch getSupportedFormats
75     throw new Error(MessageManager.getString("error.not_yet_implemented"));
76   }
77
78   /**
79    * DOCUMENT ME!
80    * 
81    * @return DOCUMENT ME!
82    */
83   public String[] getSupportedStyles()
84   {
85     // TODO - implement rest call for dbfetch getSupportedStyles
86     throw new Error(MessageManager.getString("error.not_yet_implemented"));
87   }
88
89   /**
90    * Send an HTTP fetch request to EBI and save the reply in a temporary file.
91    * 
92    * @param ids
93    *          the query formatted as db:query1;query2;query3
94    * @param format
95    *          the format wanted
96    * @param s
97    *          - unused parameter
98    * @return the file holding the response
99    * @throws OutOfMemoryError
100    */
101
102   public File fetchDataAsFile(String ids, String format, String s,
103           String ext)
104           throws OutOfMemoryError
105   {
106     File outFile = null;
107     try
108     {
109       outFile = File.createTempFile("jalview", ext);
110       outFile.deleteOnExit();
111       fetchData(ids, format, s, outFile);
112       if (outFile.length() == 0)
113       {
114         outFile.delete();
115         return null;
116       }
117     } catch (Exception ex)
118     {
119     }
120     return outFile;
121   }
122
123   /**
124    * Single DB multiple record retrieval
125    * 
126    * @param ids
127    *          db:query1;query2;query3
128    * @param format
129    *          raw/xml
130    * @param s
131    *          not used - remove?
132    * 
133    * @return Raw string array result of query set
134    */
135   public String[] fetchData(String ids, String format, String s)
136           throws OutOfMemoryError
137   {
138     return fetchData(ids, format, s, null);
139   }
140
141   String[] fetchData(String ids, String f, String s, File outFile)
142           throws OutOfMemoryError
143   {
144     // Need to split
145     // ids of the form uniprot:25KD_SARPE;ADHR_DROPS;
146     String[] rslts = new String[0];
147     StringTokenizer queries = new StringTokenizer(ids, ";");
148     String db = null;
149     StringBuffer querystring = null;
150     int nq = 0;
151     while (queries.hasMoreTokens())
152     {
153       String query = queries.nextToken();
154       int p;
155       if ((p = query.indexOf(':')) > -1)
156       {
157         db = query.substring(0, p);
158         query = query.substring(p + 1);
159       }
160       if (querystring == null)
161       {
162         querystring = new StringBuffer(query);
163         nq++;
164       }
165       else
166       {
167         querystring.append("," + query);
168         nq++;
169       }
170     }
171     if (db == null)
172     {
173       System.err.println("Invalid Query string : '" + ids
174               + "'\nShould be of form 'dbname:q1;q2;q3;q4'");
175       return null;
176     }
177     String[] rslt = fetchBatch(querystring.toString(), db, f, s, outFile);
178     if (rslt != null)
179     {
180       String[] nrslts = new String[rslt.length + rslts.length];
181       System.arraycopy(rslts, 0, nrslts, 0, rslts.length);
182       System.arraycopy(rslt, 0, nrslts, rslts.length, rslt.length);
183       rslts = nrslts;
184     }
185
186     return (rslts.length == 0 ? null : rslts);
187   }
188
189   public String[] fetchBatch(String ids, String dbPath, String format, String s,
190           File outFile) throws OutOfMemoryError
191   {
192     // long time = System.currentTimeMillis();
193     /*
194      * JAL-1855 dbfetch from ena_sequence, ena_coding
195      */
196     String url;
197     if (dbPath.equalsIgnoreCase(DBRefSource.EMBL)
198             || dbPath.equalsIgnoreCase(DBRefSource.EMBLCDS))
199     {
200       url = "http://www.ebi.ac.uk/ena/data/view/" + ids.toLowerCase()
201               + (format != null ? "&" + format : "");
202     }
203     else
204     {
205       url = "http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/"
206               + dbPath.toLowerCase() + "/" + ids.toLowerCase()
207               + (format != null ? "/" + format : "");
208     }
209
210     try
211     {
212       URL rcall = new URL(url);
213
214       InputStream is = new BufferedInputStream(rcall.openStream());
215       if (outFile != null)
216       {
217         FileOutputStream fio = new FileOutputStream(outFile);
218         byte[] bb = new byte[32 * 1024];
219         int l;
220         while ((l = is.read(bb)) > 0)
221         {
222           fio.write(bb, 0, l);
223         }
224         fio.close();
225         is.close();
226       }
227       else
228       {
229         BufferedReader br = new BufferedReader(new InputStreamReader(is));
230         String rtn;
231         List<String> arl = new ArrayList<String>();
232         while ((rtn = br.readLine()) != null)
233         {
234           arl.add(rtn);
235         }
236         return arl.toArray(new String[arl.size()]);
237       }
238     } catch (OutOfMemoryError er)
239     {
240
241       System.out.println("OUT OF MEMORY DOWNLOADING QUERY FROM " + dbPath
242               + ":\n" + ids);
243       throw er;
244     } catch (Exception ex)
245     {
246       if (ex.getMessage().startsWith(
247               "uk.ac.ebi.jdbfetch.exceptions.DbfNoEntryFoundException"))
248       {
249         return null;
250       }
251       System.err.println("Unexpected exception when retrieving from "
252               + dbPath
253               + "\nQuery was : '" + ids + "'");
254       ex.printStackTrace(System.err);
255       return null;
256     } finally
257     {
258       // System.err.println("EBIFetch took " + (System.currentTimeMillis() -
259       // time) + " ms");
260     }
261     return null;
262   }
263 }