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