JAL-653 updating 'align as' tests to match latest tweaks to algorithm
[jalview.git] / src / jalview / ext / ensembl / SeqFetcher.java
1 package jalview.ext.ensembl;
2
3 import jalview.io.FileParse;
4
5 import java.io.BufferedReader;
6 import java.io.DataOutputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.InputStreamReader;
10 import java.net.HttpURLConnection;
11 import java.net.URL;
12 import java.net.URLConnection;
13 import java.util.Collections;
14 import java.util.List;
15
16 import org.apache.http.NameValuePair;
17 import org.apache.http.message.BasicNameValuePair;
18
19 public class SeqFetcher
20 {
21   private final static String ENSEMBL_REST = "rest.ensembl.org";
22
23   private static boolean ensemblRestavailable = false;
24
25   private static long lastCheck = -1;
26
27   public boolean isEnsemblAvailable()
28   {
29     if (isTesting || !ensemblRestavailable
30             || System.currentTimeMillis() - lastCheck > 10000)
31     {
32       checkEnsembl();
33       lastCheck = System.currentTimeMillis();
34     }
35     return ensemblRestavailable;
36   }
37
38   private boolean isTesting, testEnsemblStatus;
39
40   /**
41    * @return the isTesting
42    */
43   public boolean isTesting()
44   {
45     return isTesting;
46   }
47
48   /**
49    * @param isTesting
50    *          the isTesting to set
51    */
52   public void setTesting(boolean isTesting)
53   {
54     this.isTesting = isTesting;
55   }
56
57   /**
58    * @return the testEnsemblStatus
59    */
60   public boolean isTestEnsemblStatus()
61   {
62     return testEnsemblStatus;
63   }
64
65   /**
66    * @param testEnsemblStatus
67    *          the testEnsemblStatus to set
68    */
69   public void setTestEnsemblStatus(boolean testEnsemblStatus)
70   {
71     this.testEnsemblStatus = testEnsemblStatus;
72   }
73
74   private void checkEnsembl()
75   {
76     if (isTesting)
77     {
78       ensemblRestavailable = testEnsemblStatus;
79       return;
80     }
81     try
82     {
83       URL ping = new URL("http://" + ENSEMBL_REST + "/info/ping");
84       HttpURLConnection conn = (HttpURLConnection) (ping.openConnection());
85       if (conn.getResponseCode() >= 200 && conn.getResponseCode() < 300)
86       {
87         ensemblRestavailable = true;
88         return;
89       }
90     } catch (Error err)
91     {
92       err.printStackTrace();
93     } catch (Exception exx)
94     {
95       exx.printStackTrace();
96     }
97     ensemblRestavailable = false;
98   }
99
100   public SeqFetcher()
101   {
102   }
103
104   public enum EnsemblSeqType
105   {
106     GENOMIC("genomic"), CDS("cds"), TRANSCRIPT("cds"), PROTEIN("protein"), CDNA(
107             "cdna");
108
109     private String type;
110
111     EnsemblSeqType(String t)
112     {
113       type = t;
114     }
115
116     public String getType()
117     {
118       return type;
119     }
120   }
121
122   /**
123    * reolve request type as an argument for sequence and features queries
124    * 
125    * @param type
126    */
127   public List<NameValuePair> getObjectTypeArg(EnsemblSeqType type)
128   {
129     NameValuePair nameValue = new BasicNameValuePair("type", type.getType());
130     return Collections.singletonList(nameValue);
131   }
132
133   /**
134    * return a reader to a Fasta response from the Ensembl sequence endpoint
135    * 
136    * @param returnType
137    * @param ids
138    * @return
139    * @throws IOException
140    */
141   public FileParse getSequenceReader(EnsemblSeqType returnType,
142           List<String> ids) throws IOException
143   {
144
145     // adapted From the rest.ensembl.org documentation for sequence_id
146
147     String urls = "http://" + ENSEMBL_REST + "/sequence/id";
148     List<NameValuePair> vals = getObjectTypeArg(returnType);
149     boolean f = true;
150     for (NameValuePair nvp : vals)
151     {
152       if (f)
153       {
154         f = false;
155         urls += "?";
156       }
157       else
158       {
159         urls += "&";
160       }
161       urls += nvp.getName() + "=" + nvp.getValue();
162     }
163
164     URL url = new URL(urls);
165
166     URLConnection connection = url.openConnection();
167     HttpURLConnection httpConnection = (HttpURLConnection) connection;
168
169     httpConnection.setRequestMethod("POST");
170     httpConnection.setRequestProperty("Content-Type", "application/json");
171     httpConnection.setRequestProperty("Accept", "text/x-fasta");
172     byte[] thepostbody;
173     {
174       StringBuilder postBody = new StringBuilder();
175       postBody.append("{\"ids\":[");
176       boolean first = true;
177       for (String id : ids)
178       {
179         if (first)
180         {
181           first = false;
182         }
183         else
184         {
185           postBody.append(",");
186         }
187         postBody.append("\"");
188         postBody.append(id.trim());
189         postBody.append("\"");
190       }
191       postBody.append("]}");
192       thepostbody = postBody.toString().getBytes();
193     }
194     httpConnection.setRequestProperty("Content-Length",
195             Integer.toString(thepostbody.length));
196     httpConnection.setUseCaches(false);
197     httpConnection.setDoInput(true);
198     httpConnection.setDoOutput(true);
199
200     DataOutputStream wr = new DataOutputStream(
201             httpConnection.getOutputStream());
202     wr.write(thepostbody);
203     wr.flush();
204     wr.close();
205
206     InputStream response = connection.getInputStream();
207     int responseCode = httpConnection.getResponseCode();
208
209     if (responseCode != 200)
210     {
211       throw new RuntimeException(
212               "Response code was not 200. Detected response was "
213                       + responseCode);
214     }
215
216     BufferedReader reader = null;
217     reader = new BufferedReader(new InputStreamReader(response, "UTF-8"));
218     FileParse fp = new FileParse(reader, url.toString(), "HTTP_POST");
219     return fp;
220   }
221
222 }