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