updated jalview version of dasobert 1.53e client and added Das Sequence Source discov...
[jalview.git] / src / org / biojava / dasobert / das / DAS_FeatureRetrieve.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 19.03.2004
21  * @author Andreas Prlic
22  *
23  */
24 package org.biojava.dasobert.das;
25
26 import java.io.*;
27 import java.lang.reflect.*;
28 import java.net.*;
29 import java.util.*;
30 import java.util.logging.*;
31 import javax.xml.parsers.*;
32
33 import org.xml.sax.*;
34
35 /**
36  * A class to perform a DAS features request
37  *
38  * @author Andreas Prlic
39  * Adapted for jalview use.
40  * @author Andrew Waterhouse 
41  * Updated to Das 1.53e feature spec.
42  * @author Jim Procter
43  */
44 public class DAS_FeatureRetrieve
45 {
46   String version;
47   List features;
48   Logger logger;
49   int comeBackLater;
50   URL url;
51   /**
52    * @param url the URL the features should be downloaded from
53    *
54    */
55   public DAS_FeatureRetrieve(URL url)
56   {
57     super();
58
59     logger = Logger.getLogger("org.biojava.spice");
60     features = new ArrayList();
61     comeBackLater = -1;
62     this.url = url;
63     reload();
64   }
65
66   /** contact the DAS-feature server again. Usually
67    * it is not necessary to call this again, because the constructor already does, but
68    * if comeBackLater > -1 this should be called again.
69    *
70    */
71   public void reload()
72   {
73
74     try
75     {
76
77       InputStream dasInStream = null;
78       try
79       {
80         dasInStream = open(url);
81       }
82       catch (Exception e)
83       {
84         comeBackLater = -1;
85         System.out.println("NO RESPONSE FROM " + url);
86         logger.log(Level.FINE, "could not open connection to " + url, e);
87         return;
88       }
89
90       SAXParserFactory spfactory =
91           SAXParserFactory.newInstance();
92
93       spfactory.setValidating(false);
94
95       SAXParser saxParser = null;
96
97       try
98       {
99         saxParser =
100             spfactory.newSAXParser();
101       }
102       catch (ParserConfigurationException e)
103       {
104         e.printStackTrace();
105       }
106
107       String vali = System.getProperty("XMLVALIDATION");
108
109       boolean validation = false;
110       if (vali != null)
111       {
112         if (vali.equals("true"))
113         {
114           validation = true;
115         }
116       }
117
118       XMLReader xmlreader = saxParser.getXMLReader();
119
120       //XMLReader xmlreader = XMLReaderFactory.createXMLReader();
121       try
122       {
123         xmlreader.setFeature("http://xml.org/sax/features/validation",
124                              validation);
125       }
126       catch (SAXException e)
127       {
128         logger.log(Level.FINE, "Cannot set validation " + validation);
129       }
130
131       try
132       {
133         xmlreader.setFeature(
134             "http://apache.org/xml/features/nonvalidating/load-external-dtd",
135             validation);
136       }
137       catch (SAXNotRecognizedException e)
138       {
139         e.printStackTrace();
140         logger.log(Level.FINE, "Cannot set load-external-dtd " + validation);
141
142       }
143
144       DAS_Feature_Handler cont_handle = new DAS_Feature_Handler();
145       cont_handle.setDASCommand(url.toString());
146       xmlreader.setContentHandler(cont_handle);
147       xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
148       InputSource insource = new InputSource();
149       insource.setByteStream(dasInStream);
150
151       try
152       {
153         xmlreader.parse(insource);
154         features = cont_handle.get_features();
155                 version  = cont_handle.getVersion();
156                 
157         comeBackLater = cont_handle.getComBackLater();
158       }
159       catch (Exception e)
160       {
161         System.out.println("Error parsing response from: " + url + "\n" + e);
162         logger.log(Level.FINE, "error while parsing response from " + url);
163         comeBackLater = -1;
164         features = new ArrayList();
165       }
166     }
167     catch (Exception ex)
168     {
169       ex.printStackTrace();
170       comeBackLater = -1;
171     }
172   }
173
174   /** open HttpURLConnection. Recommended way to open
175    * HttpURLConnections, since this take care of setting timeouts
176    * properly for java 1.4 and 1.5*/
177   public static HttpURLConnection openHttpURLConnection(URL url)
178       throws IOException, ConnectException
179   {
180     HttpURLConnection huc = null;
181     huc = (HttpURLConnection) url.openConnection();
182
183     String os_name = java.lang.System.getProperty("os.name");
184     String os_version = java.lang.System.getProperty("os.version");
185     String os_arch = java.lang.System.getProperty("os.arch");
186     String VERSION = "1.0";
187
188     String userAgent = "Jalview " + VERSION + "(" + os_name + "; " + os_arch +
189         " ; " + os_version + ")";
190     //e.g. "Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.7.2) Gecko/20040803"
191     huc.addRequestProperty("User-Agent", userAgent);
192     //logger.finest("opening "+url);
193
194
195     int timeout = 10000;
196     System.setProperty("sun.net.client.defaultConnectTimeout", timeout + "");
197     System.setProperty("sun.net.client.defaultReadTimeout", timeout + "");
198
199     // use reflection to determine if get and set timeout methods for urlconnection are available
200     // seems java 1.5 does not watch the System properties any longer...
201     // and java 1.4 did not provide these...
202     // for 1.4 see setSystemProperties
203
204     try
205     {
206       // try to use reflection to set timeout property
207       Class urlconnectionClass = Class.forName("java.net.HttpURLConnection");
208
209       Method setconnecttimeout = urlconnectionClass.getMethod(
210           "setConnectTimeout", new Class[]
211           {int.class}
212           );
213       setconnecttimeout.invoke(huc, new Object[]
214                                {new Integer(timeout)});
215
216       Method setreadtimeout = urlconnectionClass.getMethod(
217           "setReadTimeout", new Class[]
218           {int.class}
219           );
220       setreadtimeout.invoke(huc, new Object[]
221                             {new Integer(timeout)});
222       //System.out.println("successfully set java 1.5 timeout");
223     }
224     catch (Exception e)
225     {
226       //e.printStackTrace();
227       // most likely it was a NoSuchMEthodException and we are running java 1.4.
228     }
229     return huc;
230   }
231
232   private InputStream open(URL url)
233       throws java.io.IOException, java.net.ConnectException
234   {
235     InputStream inStream = null;
236
237     HttpURLConnection huc = openHttpURLConnection(url);
238
239     inStream = huc.getInputStream();
240
241     return inStream;
242
243   }
244
245   /** returns a List of Features
246    * @return a List of Maps containing the features*/
247   public List get_features()
248   {
249
250     return features;
251     }
252     
253     
254     /** Get the version string of the reference object.
255      * If it does not match the version string that is obtained from the 
256      * reference server there is a version problem!
257      *  
258      * @return version string. (e.g. a MD5 digest of the reference sequence)
259      */
260     public String getVersion() {
261                 return version;
262         }
263
264
265         public void setVersion(String version) {
266                 this.version = version;
267   }
268
269   /** returns the comeBackLater value - if a server returned suchh -
270    *
271    * @return comeBackLater in seconds, or -1 if not provided by server
272    */
273   public int getComeBackLater()
274   {
275
276     return comeBackLater;
277
278   }
279
280 }