Das client files
[jalview.git] / src / org / biojava / dasobert / dasregistry / Das1Validator.java
1 /*                    BioJava development code
2  *
3  * This code may be freely distributed and modified under the
4  * terms of the GNU Lesser General Public Licence.  This should
5  * be distributed with the code.  If you do not have a copy,
6  * see:
7  *
8  *      http://www.gnu.org/copyleft/lesser.html
9  *
10  * Copyright for this code is held jointly by the individual
11  * authors.  These should be listed in @author doc comments.
12  *
13  * For more information on the BioJava project and its aims,
14  * or to join the biojava-l mailing list, visit the home page
15  * at:
16  *
17  *      http://www.biojava.org/
18  *
19  * Created on 30.08.2005
20  * @author Andreas Prlic
21  *
22  */
23
24
25 package org.biojava.dasobert.dasregistry ;
26
27 //import org.biojava.services.das.*;
28 //xml stuff
29 import org.xml.sax.*;
30 import javax.xml.parsers.*;
31 import java.util.ArrayList                    ;
32 import java.util.Map                          ;
33 import java.util.List                         ;
34 import java.io.InputStream                    ;
35
36 import java.net.URL                           ;
37
38
39 //for validation add dependency on SPICE... :-/
40 import java.net.HttpURLConnection;
41 import org.biojava.dasobert.das.*;
42 import org.biojava.dasobert.das.DAS_Entry_Points_Handler;
43 import org.biojava.dasobert.das.DAS_Types_Handler;
44
45
46
47 public class Das1Validator {
48
49     public final static String[] DAS_CAPABILITIES = {
50         "sequence",
51         "structure",
52         "alignment",
53         "types",
54         "features",
55         "entry_points",
56         "dna",
57         "stylesheet"
58     } ;
59
60
61     //private final static String DATASOURCE_NAME = "jdbc/mysql";
62     String validationMessage;
63
64     public boolean VALIDATION = false; // DTD validation ..
65
66     List all_capabilities;
67     public Das1Validator() {
68         validationMessage = "" ;
69         all_capabilities = new ArrayList();
70         for ( int i = 0 ; i< DAS_CAPABILITIES.length; i++ ) {
71             all_capabilities.add(DAS_CAPABILITIES[i]);
72         }
73     }
74
75     /** return which errors have been produced during validation... */
76     public String getValidationMessage(){
77         return validationMessage;
78     }
79
80
81
82     public String[] validate(String url, DasCoordinateSystem[] coords, String[] capabilities){
83         validationMessage="";
84         // a list containing all valid DAS requests ...
85
86         List lst =new ArrayList();
87
88         char lastChar = url.charAt(url.length()-1);
89         if ( lastChar  != '/')
90             url += "/";
91
92         validateURL(url);
93
94
95         // test if all specified capabilities really work
96         for ( int c = 0 ; c < capabilities.length ; c++) {
97             String capability = capabilities[c];
98             if ( all_capabilities.contains(capability)) {
99                 //System.out.println("testing " + capability);
100
101                 if ( capability.equals("sequence")) {
102                     for ( int i=0;i< coords.length;i++){
103                         DasCoordinateSystem ds =coords[i];
104                         String testcode = ds.getTestCode();
105
106                         // do a DAS sequence retreive
107                         if (  validateSequence(url,testcode) )
108                             lst.add(capability);
109
110                     }
111
112                 }
113                 else if ( capability.equals("structure")) {
114
115                 }
116                 else if ( capability.equals("features")){
117                     for ( int i=0;i< coords.length;i++){
118                         DasCoordinateSystem ds =coords[i];
119                         String testcode = ds.getTestCode();
120
121
122                         if ( validateFeatures(url,testcode))
123                             lst.add(capability);
124
125                     }
126                 }
127                 else if ( capability.equals("alignment")){
128
129                 } else if ( capability.equals("types")){
130                     if ( validateTypes(url))
131                         lst.add(capability);
132                     //else
133                     //    error =true ;
134
135                 } else if ( capability.equals("entry_points")) {
136                     if ( validateEntry_Points(url))
137                         lst.add(capability);
138                     //else
139                     //    error = true;
140                 } else if ( capability.equals("stylesheet")) {
141                     if ( validateStylesheet(url))
142                         lst.add(capability);
143                     //} else
144                     //    error = true;
145                 } else if ( capability.equals("dna")){
146                     for ( int i=0;i< coords.length;i++){
147                         DasCoordinateSystem ds =coords[i];
148                         String testcode = ds.getTestCode();
149
150                         if ( validateDNA(url,testcode))
151                             lst.add(capability);
152                     }
153                 }
154                 else {
155                     validationMessage += "<br/>---<br/> test of capability " + capability + " not implemented,yet.";
156                     lst.add(capability);
157                 }
158             }
159         }
160
161         //if ( error) {
162         //    System.out.println("DasValidator: "+ validationMessage);
163         //}
164         //this.validationMessage = validationMessage;
165         return (String[])lst.toArray(new String[lst.size()]);
166
167     }
168
169     /** make sure the URL matches the DAS spec
170      returns true if URL looks o.k...
171      */
172     public  boolean validateURL(String url) {
173         String[] spl = url.split("/");
174
175         //for (int i = 0 ; i < spl.length  ; i++ ) {
176         //    System.out.println("spl["+i+"]:"+spl[i]);
177         //}
178
179         if (spl == null ) {
180             validationMessage +="---<br/> URL is not well formed" ;
181             return false;
182         }
183
184         if ( spl.length <= 4) {
185             validationMessage +="---<br/> URL is not well formed <br/>" +
186             "should be http[s]://site.specific.prefix/das/dassourcename/";
187             return false;
188         }
189
190         //System.out.println("split 0 : " + spl[0]);
191         if ( ! (spl[0].equals("http:"))) {
192             if ( ! ( spl[0].equals("https:"))){
193                 validationMessage +="---<br/> URL is not well formed (does not start with http:// or https://)" ;
194                 return false;
195             }
196
197         }
198
199         String dastxt = spl[spl.length-2] ;
200         //System.out.println("should be >das< " + dastxt);
201         if ( ! dastxt.equals("das")) {
202             String suggestion = spl[0] + "//" ;
203             String wrong      = spl[0] + "//" ;
204             for (int i = 2 ; i < spl.length -2 ; i++ ) {
205                 suggestion += spl[i] + "/" ;
206                 wrong += spl[i] + "/" ;
207             }
208             suggestion +="<b>das</b>/"+spl[spl.length-1];
209             wrong +="<b>" + spl[spl.length-2] + "</b>/"+spl[spl.length-1];
210             validationMessage +="--<br/> the URL does not match the DAS spec. it should be <br/>"+
211             " http[s]://site.specific.prefix/das/dassourcename/ <br/>" +
212             " found >" + dastxt +" < instead of >das< <br/>" +
213             " suggested url: " + suggestion + "<br/>"+
214             " instead of: " + wrong ;
215             return false;
216         }
217         return true;
218
219     }
220
221     private boolean validateDNA(String url, String testcode){
222         try {
223             String cmd = url+"dna?segment="+testcode;
224             URL strurl = new URL(cmd);
225             InputStream dasInStream = open(strurl);
226
227             XMLReader xmlreader = getXMLReader();
228
229             DAS_DNA_Handler cont_handle = new DAS_DNA_Handler() ;
230
231             xmlreader.setContentHandler(cont_handle);
232             xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
233             InputSource insource = new InputSource() ;
234
235             insource.setByteStream(dasInStream);
236             xmlreader.parse(insource);
237             String sequence = cont_handle.get_sequence();
238             if ( sequence.length() > 0 ) {
239                 return true;
240             } else {
241                 validationMessage  +="<br/>---<br/> contacting " + cmd + "<br/>";
242                 validationMessage += " no sequence was returned";
243
244                 return false;
245             }
246
247
248         } catch ( Exception e) {
249             //e.printStackTrace();
250             validationMessage += "<br/>---<br/> contacting " + url + "dna?segment="+testcode + "<br/>";
251
252             Throwable cause = e.getCause();
253             if ( cause != null)
254                 validationMessage += cause.toString();
255             else
256                 validationMessage += e.toString();
257         }
258         return false;
259
260     }
261
262     private boolean validateStylesheet(String url) {
263         try {
264             DAS_StylesheetRetrieve dsr = new DAS_StylesheetRetrieve();
265             URL styleurl = new URL(url+"stylesheet");
266
267             Map[] stylesheet = dsr.retrieve(styleurl);
268             if (( stylesheet != null ) && ( stylesheet.length > 0))
269                 return true;
270             else {
271                 validationMessage  +="<br/>---<br/> contacting " + url + "stylesheet<br/>";
272                 validationMessage += " no stylesheet was returned";
273                 return false;
274             }
275         } catch (Exception e) {
276             validationMessage += "<br/>---<br/> contacting " + url+"stylesheet <br/>";
277
278             Throwable cause = e.getCause();
279             if ( cause != null)
280                 validationMessage += cause.toString();
281             else
282                 validationMessage += e.toString();
283         }
284         return false;
285     }
286
287
288     private boolean validateEntry_Points(String url){
289         try {
290             URL u = new URL(url+"entry_points");
291
292             InputStream dasInStream = open(u);
293
294             XMLReader xmlreader = getXMLReader();
295
296             DAS_Entry_Points_Handler cont_handle = new DAS_Entry_Points_Handler() ;
297
298             xmlreader.setContentHandler(cont_handle);
299             xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
300             InputSource insource = new InputSource() ;
301             insource.setByteStream(dasInStream);
302             xmlreader.parse(insource);
303             String version = cont_handle.getVersion();
304             if ( version != null ) {
305                 return true;
306             } else {
307                 validationMessage  +="<br/>---<br/> contacting " + url +"entry_points <br/>";
308                 validationMessage += " no version was returned";
309
310                 return false;
311             }
312
313
314         } catch ( Exception e) {
315             //e.printStackTrace();
316             validationMessage += "<br/>---<br/> contacting " + url+ "types <br/>";
317
318             Throwable cause = e.getCause();
319             if ( cause != null)
320                 validationMessage += cause.toString();
321             else
322                 validationMessage += e.toString();
323         }
324         return false;
325     }
326
327     private boolean validateTypes(String url){
328         try {
329             URL u = new URL(url+"types");
330             InputStream dasInStream = open(u);
331             XMLReader xmlreader = getXMLReader();
332
333             DAS_Types_Handler cont_handle = new DAS_Types_Handler() ;
334
335             xmlreader.setContentHandler(cont_handle);
336             xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
337             InputSource insource = new InputSource() ;
338             insource.setByteStream(dasInStream);
339             xmlreader.parse(insource);
340             String[] types = cont_handle.getTypes();
341             if ( types.length > 0 ) {
342                 return true;
343             } else {
344                 validationMessage  +="<br/>---<br/> contacting " + url +"types <br/>";
345                 validationMessage += " no types were returned";
346
347                 return false;
348             }
349
350
351         } catch ( Exception e) {
352             //e.printStackTrace();
353             validationMessage += "<br/>---<br/> contacting " + url+ "types <br/>";
354
355             Throwable cause = e.getCause();
356             if ( cause != null)
357                 validationMessage += cause.toString();
358             else
359                 validationMessage += e.toString();
360         }
361         return false;
362     }
363
364
365     private boolean validateFeatures(String url, String testcode){
366         try {
367             URL u = new URL(url+"features?segment="+testcode);
368             InputStream dasInStream = open(u);
369             XMLReader xmlreader = getXMLReader();
370
371             DAS_Feature_Handler cont_handle = new DAS_Feature_Handler() ;
372             cont_handle.setDASCommand(url.toString());
373             xmlreader.setContentHandler(cont_handle);
374             xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
375             InputSource insource = new InputSource() ;
376             insource.setByteStream(dasInStream);
377             xmlreader.parse(insource);
378             List features = cont_handle.get_features();
379             if ( features.size() > 0 ) {
380                 return true;
381             } else {
382                 validationMessage  +="<br/>---<br/> contacting " + url+"features?segment="+testcode + "<br/>";
383                 validationMessage += " no features were returned";
384
385                 return false;
386             }
387
388         } catch ( Exception e) {
389             //e.printStackTrace();
390             validationMessage += "<br/>---<br/> contacting " + url+"features?segment="+testcode + "<br/>";
391
392             Throwable cause = e.getCause();
393             if ( cause != null)
394                 validationMessage += cause.toString();
395             else
396                 validationMessage += e.toString();
397         }
398         return false;
399     }
400      private boolean validateSequence(String url, String testcode) {
401         URL dasUrl;
402         String cmd = url+"sequence?segment="+testcode;
403         try {
404             dasUrl = new URL(cmd);
405
406         } catch ( Exception e) {
407             e.printStackTrace();
408             return false;
409         }
410         try {
411             InputStream dasInStream =open(dasUrl);
412             SAXParserFactory spfactory =
413                 SAXParserFactory.newInstance();
414             spfactory.setValidating(true);
415
416             SAXParser saxParser = null ;
417
418             try{
419                 saxParser =
420                     spfactory.newSAXParser();
421             } catch (ParserConfigurationException e) {
422                 e.printStackTrace();
423             }
424             XMLReader xmlreader = saxParser.getXMLReader();
425
426             try {
427                 xmlreader.setFeature("http://xml.org/sax/features/validation", VALIDATION);
428             } catch (SAXException e) {
429                 e.printStackTrace();
430             }
431             try {
432                 xmlreader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",VALIDATION);
433             } catch (SAXNotRecognizedException e){
434                 e.printStackTrace();
435             }
436
437             DAS_Sequence_Handler cont_handle = new DAS_Sequence_Handler() ;
438             xmlreader.setContentHandler(cont_handle);
439             xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
440             InputSource insource = new InputSource() ;
441             insource.setByteStream(dasInStream);
442             xmlreader.parse(insource);
443             String sequence = cont_handle.get_sequence();
444             if ( ( sequence==null) || (sequence.equals(""))) {
445                 validationMessage += "---<br/>contacting " + cmd +"<br/>";
446                 validationMessage += "no sequence found";
447                 return false;
448             }
449             return true;
450         } catch (Exception e) {
451             validationMessage += "---<br/>contacting " + cmd +"<br/>";
452
453             Throwable cause = e.getCause();
454             if ( cause != null)
455                 validationMessage += cause.toString();
456             else
457                 validationMessage += e.toString();
458             //e.printStackTrace();
459         }
460         return false;
461     }
462
463     private XMLReader getXMLReader() throws SAXException{
464         SAXParserFactory spfactory =
465             SAXParserFactory.newInstance();
466
467         spfactory.setValidating(false) ;
468         SAXParser saxParser = null ;
469
470         try{
471             saxParser =
472                 spfactory.newSAXParser();
473         } catch (ParserConfigurationException e) {
474             e.printStackTrace();
475         }
476
477         XMLReader xmlreader = saxParser.getXMLReader();
478         boolean validation = VALIDATION;
479         //XMLReader xmlreader = XMLReaderFactory.createXMLReader();
480         try {
481             xmlreader.setFeature("http://xml.org/sax/features/validation", validation);
482         } catch (SAXException e) {
483             e.printStackTrace();
484         }
485
486         try {
487             xmlreader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",validation);
488         } catch (SAXNotRecognizedException e){
489             e.printStackTrace();
490         }
491         return xmlreader;
492
493     }
494
495
496
497     private InputStream open(URL url) throws Exception{
498
499         // TODO Auto-generated method stub
500
501         InputStream inStream = null;
502
503         HttpURLConnection huc = null;
504         huc = (HttpURLConnection) url.openConnection();
505         //String contentEncoding = huc.getContentEncoding();
506         inStream = huc.getInputStream();
507         return inStream;
508     }
509
510
511
512
513
514 }