properly catch exceptions from querying server with sequence command
[jalview.git] / src / org / biojava / dasobert / das / SequenceThread.java
1 /*
2  *                  BioJava development code
3  *
4  * This code may be freely distributed and modified under the
5  * terms of the GNU Lesser General Public Licence.  This should
6  * be distributed with the code.  If you do not have a copy,
7  * see:
8  *
9  *      http://www.gnu.org/copyleft/lesser.html
10  *
11  * Copyright for this code is held jointly by the individual
12  * authors.  These should be listed in @author doc comments.
13  *
14  * For more information on the BioJava project and its aims,
15  * or to join the biojava-l mailing list, visit the home page
16  * at:
17  *
18  *      http://www.biojava.org/
19  * 
20  * Created on Nov 20, 2005
21  *
22  */
23 package org.biojava.dasobert.das;
24
25 import java.io.InputStream;
26 import java.net.HttpURLConnection;
27 import java.net.URL;
28 import java.util.Iterator;
29 import java.util.logging.Level;
30 import java.util.logging.Logger;
31 import javax.xml.parsers.ParserConfigurationException;
32 import javax.xml.parsers.SAXParser;
33 import javax.xml.parsers.SAXParserFactory;
34
35 import org.biojava.dasobert.dasregistry.Das1Source;
36 import org.biojava.dasobert.eventmodel.SequenceEvent;
37 import org.biojava.dasobert.eventmodel.SequenceListener;
38 import org.xml.sax.InputSource;
39 import org.xml.sax.SAXException;
40 import org.xml.sax.SAXNotRecognizedException;
41 import org.xml.sax.XMLReader;
42 import java.util.*;
43
44 /**
45  * a thread that gets the sequence from a DAS server
46  * 
47  * @author Andreas Prlic
48  * 
49  */
50 public class SequenceThread extends Thread
51 {
52
53   Das1Source[] sequenceServers;
54
55   String sp_accession;
56
57   List seqListeners;
58
59   String version;
60
61   static Logger logger = Logger.getLogger("org.biojava.spice");
62
63   public SequenceThread(String sp_accession, Das1Source ds)
64   {
65     super();
66     Das1Source[] dss = new Das1Source[1];
67     dss[0] = ds;
68     this.sp_accession = sp_accession;
69     this.sequenceServers = dss;
70     clearSequenceListeners();
71     version = "";
72   }
73
74   public SequenceThread(String sp_accession, Das1Source[] ds)
75   {
76     super();
77
78     this.sp_accession = sp_accession;
79     this.sequenceServers = ds;
80     clearSequenceListeners();
81   }
82
83   public void clearSequenceListeners()
84   {
85     seqListeners = new ArrayList();
86   }
87
88   public void addSequenceListener(SequenceListener lis)
89   {
90     seqListeners.add(lis);
91   }
92
93   public void run()
94   {
95     getSequence();
96   }
97
98   public void getSequence()
99   {
100
101     boolean gotSequence = false;
102
103     for (int i = 0; i < sequenceServers.length; i++)
104     {
105
106       if (gotSequence)
107         break;
108
109       Das1Source ds = sequenceServers[i];
110       String url = ds.getUrl();
111       char lastChar = url.charAt(url.length() - 1);
112       if (!(lastChar == '/'))
113         url += "/";
114       String dascmd = url + "sequence?segment=";
115       String connstr = dascmd + sp_accession;
116
117       try
118       {
119         version = "";
120
121         String sequence = retrieveSequence(connstr);
122         // TODO: discriminate exceptions caused by connection/server errors and ones caused by the sequence not being found in the reference source.
123         if (sequence!=null)
124         {
125           // bug in aristotle das source?
126           sequence.replaceAll(" ", "");
127           gotSequence = true;
128           // set the sequence ...
129
130           triggerNewSequence(sp_accession, sequence, ds, version);
131         }
132         return;
133       } catch (Exception ex)
134       {
135         ex.printStackTrace();
136         logger.warning(ex.getMessage());
137
138         // triggerException(ex);
139
140       }
141     }
142
143     logger
144             .log(
145                     Level.WARNING,
146                     "could not retreive UniProt sequence from any available DAS sequence server");
147
148     triggerNoSequence(sp_accession);
149
150   }
151
152   // private void triggerException(Exception e){
153   // Iterator iter = seqListeners.iterator();
154   // while (iter.hasNext()){
155   // SequenceListener li = (SequenceListener)iter.next();
156   // li.exceptionOccured(e);
157   // }
158   // }
159
160   private void triggerNewSequence(String sp_accession, String sequence,
161           Das1Source source, String version)
162   {
163
164     Iterator iter = seqListeners.iterator();
165     while (iter.hasNext())
166     {
167       SequenceListener li = (SequenceListener) iter.next();
168       // SequenceEvent event = new SequenceEvent(sequence);
169       SequenceEvent event = new SequenceEvent(sp_accession, sequence,
170               version);
171       event.setSource(source);
172       li.newSequence(event);
173     }
174   }
175
176   private void triggerNoSequence(String ac)
177   {
178
179     Iterator iter = seqListeners.iterator();
180     while (iter.hasNext())
181     {
182       SequenceListener li = (SequenceListener) iter.next();
183       li.noObjectFound(ac);
184     }
185
186   }
187
188   /**
189    * retrieve the Sequence from a DAS server.
190    * 
191    * @param connstr -
192    *                the DAS - request string. e.g.
193    *                http://www.ebi.ac.uk/das-srv/uniprot/das/aristotle/sequence?segment=P00280
194    * @return the requested Sequence
195    * @throws Exception
196    */
197   public String retrieveSequence(String connstr) throws Exception
198   {
199
200     // logger.finest("trying: " + connstr) ;
201     URL dasUrl = new URL(connstr);
202     // DAS_httpConnector dhtp = new DAS_httpConnector() ;
203     logger.info("requesting sequence from " + connstr);
204     InputStream dasInStream = open(dasUrl);
205
206     SAXParserFactory spfactory = SAXParserFactory.newInstance();
207
208     // never do this
209     // String vali = System.getProperty("XMLVALIDATION");
210     String vali = "false";
211     boolean validate = false;
212     if ((vali != null) && (vali.equals("true")))
213       validate = true;
214     spfactory.setValidating(validate);
215
216     SAXParser saxParser = null;
217
218     try
219     {
220       saxParser = spfactory.newSAXParser();
221     } catch (ParserConfigurationException e)
222     {
223       // e.printStackTrace();
224       logger.log(Level.FINER, "Uncaught exception", e);
225     }
226
227     XMLReader xmlreader = saxParser.getXMLReader();
228
229     try
230     {
231       xmlreader.setFeature("http://xml.org/sax/features/validation",
232               validate);
233     } catch (SAXException e)
234     {
235       logger.finer("Cannot set validation to " + validate);
236       logger.log(Level.FINER, "Uncaught exception", e);
237     }
238
239     try
240     {
241       xmlreader
242               .setFeature(
243                       "http://apache.org/xml/features/nonvalidating/load-external-dtd",
244                       validate);
245     } catch (SAXNotRecognizedException e)
246     {
247       // e.printStackTrace();
248       logger.finer("Cannot set load-external-dtd to" + validate);
249       logger.log(Level.FINER, "Uncaught exception", e);
250       // System.err.println("Cannot set load-external-dtd to" + validate);
251     }
252     if (dasInStream==null)
253     {
254       return null;
255     }
256     // DAS_DNA_Handler cont_handle = new DAS_DNA_Handler() ;
257     DAS_Sequence_Handler cont_handle = new DAS_Sequence_Handler();
258     xmlreader.setContentHandler(cont_handle);
259     xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
260     InputSource insource = new InputSource();
261     insource.setByteStream(dasInStream);
262
263     xmlreader.parse(insource);
264     String sequence = cont_handle.get_sequence();
265     version = cont_handle.getVersion();
266     // logger.finest("Got sequence from DAS: " +sequence);
267
268     logger.exiting(this.getClass().getName(), "retreiveSequence", sequence);
269     return sequence;
270   }
271
272   private InputStream open(URL url)
273   {
274     {
275
276       InputStream inStream = null;
277       try
278       {
279
280         HttpURLConnection huc = null;
281
282         huc = DAS_FeatureRetrieve.openHttpURLConnection(url);
283
284         logger.finest(huc.getResponseMessage());
285
286         inStream = huc.getInputStream();
287
288       } catch (Exception ex)
289       {
290         ex.printStackTrace();
291         logger.log(Level.WARNING, "exception occured", ex);
292       }
293
294       return inStream;
295     }
296
297   }
298
299 }