simple transformation of feature types like dbref and dbxref into database references
[jalview.git] / src / jalview / ws / DasSequenceFeatureFetcher.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)\r
3  * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  * \r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  * \r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  * \r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.ws;\r
20 \r
21 import java.net.*;\r
22 import java.util.*;\r
23 \r
24 import javax.swing.*;\r
25 \r
26 import org.biojava.dasobert.das.*;\r
27 import org.biojava.dasobert.das2.*;\r
28 import org.biojava.dasobert.das2.io.*;\r
29 import org.biojava.dasobert.dasregistry.*;\r
30 import org.biojava.dasobert.eventmodel.*;\r
31 import jalview.bin.Cache;\r
32 import jalview.datamodel.*;\r
33 import jalview.gui.*;\r
34 \r
35 /**\r
36  * DOCUMENT ME!\r
37  * \r
38  * @author $author$\r
39  * @version $Revision$\r
40  */\r
41 public class DasSequenceFeatureFetcher\r
42 {\r
43   SequenceI[] sequences;\r
44 \r
45   AlignFrame af;\r
46 \r
47   FeatureSettings fsettings;\r
48 \r
49   StringBuffer sbuffer = new StringBuffer();\r
50 \r
51   Vector selectedSources;\r
52 \r
53   boolean cancelled = false;\r
54 \r
55   private void debug(String mesg)\r
56   {\r
57     debug(mesg, null);\r
58   }\r
59 \r
60   private void debug(String mesg, Exception e)\r
61   {\r
62     if (Cache.log != null)\r
63     {\r
64       Cache.log.debug(mesg, e);\r
65     }\r
66     else\r
67     {\r
68       System.err.println(mesg);\r
69       if (e != null)\r
70       {\r
71         e.printStackTrace();\r
72       }\r
73     }\r
74   }\r
75 \r
76   long startTime;\r
77 \r
78   /**\r
79    * Creates a new SequenceFeatureFetcher object. Uses default\r
80    * \r
81    * @param align\r
82    *                DOCUMENT ME!\r
83    * @param ap\r
84    *                DOCUMENT ME!\r
85    */\r
86   public DasSequenceFeatureFetcher(SequenceI[] sequences,\r
87           FeatureSettings fsettings, Vector selectedSources)\r
88   {\r
89     this(sequences, fsettings, selectedSources, true, true);\r
90   }\r
91 \r
92   public DasSequenceFeatureFetcher(SequenceI[] sequences,\r
93           FeatureSettings fsettings, Vector selectedSources,\r
94           boolean checkDbrefs, boolean promptFetchDbrefs)\r
95   {\r
96     this.selectedSources = selectedSources;\r
97     this.sequences = sequences;\r
98     if (fsettings != null)\r
99     {\r
100       this.fsettings = fsettings;\r
101       this.af = fsettings.af;\r
102       af.getViewport().setShowSequenceFeatures(true);\r
103     }\r
104     int uniprotCount = 0;\r
105     for (int i = 0; i < selectedSources.size(); i++)\r
106     {\r
107       DasSource source = (DasSource) selectedSources.elementAt(i);\r
108       DasCoordinateSystem[] coords = source.getCoordinateSystem();\r
109       for (int c = 0; c < coords.length; c++)\r
110       {\r
111         // TODO: match UniProt coord system canonically (?) - does\r
112         // UniProt==uniprot==UNIPROT ?\r
113         if (coords[c].getName().indexOf("UniProt") > -1)\r
114         {\r
115           uniprotCount++;\r
116           break;\r
117         }\r
118       }\r
119     }\r
120 \r
121     int refCount = 0;\r
122     for (int i = 0; i < sequences.length; i++)\r
123     {\r
124       DBRefEntry[] dbref = sequences[i].getDBRef();\r
125       if (dbref != null)\r
126       {\r
127         for (int j = 0; j < dbref.length; j++)\r
128         {\r
129           if (dbref[j].getSource().equals(\r
130                   jalview.datamodel.DBRefSource.UNIPROT))\r
131           {\r
132             refCount++;\r
133             break;\r
134           }\r
135         }\r
136       }\r
137     }\r
138 \r
139     if (checkDbrefs && refCount < sequences.length && uniprotCount > 0)\r
140     {\r
141 \r
142       int reply = JOptionPane.YES_OPTION;\r
143       if (promptFetchDbrefs)\r
144       {\r
145         reply = JOptionPane\r
146                 .showInternalConfirmDialog(\r
147                         Desktop.desktop,\r
148                         "Do you want Jalview to find\n"\r
149                                 + "Uniprot Accession ids for given sequence names?",\r
150                         "Find Uniprot Accession Ids",\r
151                         JOptionPane.YES_NO_OPTION,\r
152                         JOptionPane.QUESTION_MESSAGE);\r
153       }\r
154 \r
155       if (reply == JOptionPane.YES_OPTION)\r
156       {\r
157         Thread thread = new Thread(new FetchDBRefs());\r
158         thread.start();\r
159       }\r
160       else\r
161       {\r
162         startFetching();\r
163       }\r
164     }\r
165     else\r
166     {\r
167       startFetching();\r
168     }\r
169 \r
170   }\r
171 \r
172   class FetchDBRefs implements Runnable\r
173   {\r
174     public void run()\r
175     {\r
176       new DBRefFetcher(sequences, af).fetchDBRefs(true);\r
177       startFetching();\r
178     }\r
179   }\r
180 \r
181   /**\r
182    * Spawns a number of dasobert Fetcher threads to add features to sequences in\r
183    * the dataset\r
184    */\r
185   void startFetching()\r
186   {\r
187     cancelled = false;\r
188     startTime = System.currentTimeMillis();\r
189     if (af != null)\r
190     {\r
191       af.setProgressBar("Fetching DAS Sequence Features", startTime);\r
192     }\r
193 \r
194     DasSource[] sources = new jalview.gui.DasSourceBrowser().getDASSource();\r
195 \r
196     if (selectedSources == null || selectedSources.size() == 0)\r
197     {\r
198       String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE",\r
199               "uniprot");\r
200       StringTokenizer st = new StringTokenizer(active, "\t");\r
201       Vector selectedSources = new Vector();\r
202       String token;\r
203       while (st.hasMoreTokens())\r
204       {\r
205         token = st.nextToken();\r
206         for (int i = 0; i < sources.length; i++)\r
207         {\r
208           if (sources[i].getNickname().equals(token))\r
209           {\r
210             selectedSources.addElement(sources[i]);\r
211             break;\r
212           }\r
213         }\r
214       }\r
215     }\r
216 \r
217     if (selectedSources == null || selectedSources.size() == 0)\r
218     {\r
219       System.out.println("No DAS Sources active");\r
220       cancelled = true;\r
221       setGuiNoDassourceActive();\r
222       return;\r
223     }\r
224 \r
225     sourcesRemaining = selectedSources.size();\r
226     // Now sending requests one at a time to each server\r
227     for (int sourceIndex = 0; sourceIndex < selectedSources.size()\r
228             && !cancelled; sourceIndex++)\r
229     {\r
230       DasSource dasSource = (DasSource) selectedSources\r
231               .elementAt(sourceIndex);\r
232 \r
233       nextSequence(dasSource, sequences[0]);\r
234     }\r
235   }\r
236 \r
237   private void setGuiNoDassourceActive()\r
238   {\r
239 \r
240     if (af != null)\r
241     {\r
242       af.setProgressBar("No DAS Sources Active", startTime);\r
243     }\r
244     if (getFeatSettings() != null)\r
245     {\r
246       fsettings.noDasSourceActive();\r
247     }\r
248   }\r
249 \r
250   /**\r
251    * Update our fsettings dialog reference if we didn't have one when we were\r
252    * first initialised.\r
253    * \r
254    * @return fsettings\r
255    */\r
256   private FeatureSettings getFeatSettings()\r
257   {\r
258     if (fsettings == null)\r
259     {\r
260       if (af != null)\r
261       {\r
262         fsettings = af.featureSettings;\r
263       }\r
264     }\r
265     return fsettings;\r
266   }\r
267 \r
268   public void cancel()\r
269   {\r
270     if (af != null)\r
271     {\r
272       af.setProgressBar("DAS Feature Fetching Cancelled", startTime);\r
273     }\r
274     cancelled = true;\r
275   }\r
276 \r
277   int sourcesRemaining = 0;\r
278 \r
279   void responseComplete(DasSource dasSource, SequenceI seq)\r
280   {\r
281     if (seq != null)\r
282     {\r
283       for (int seqIndex = 0; seqIndex < sequences.length - 1 && !cancelled; seqIndex++)\r
284       {\r
285         if (sequences[seqIndex] == seq)\r
286         {\r
287           nextSequence(dasSource, sequences[++seqIndex]);\r
288           return;\r
289         }\r
290       }\r
291     }\r
292 \r
293     sourcesRemaining--;\r
294 \r
295     if (sourcesRemaining == 0)\r
296     {\r
297       System.err.println("Fetching Complete.");\r
298       setGuiFetchComplete();\r
299     }\r
300 \r
301   }\r
302 \r
303   private void setGuiFetchComplete()\r
304   {\r
305 \r
306     if (af != null)\r
307     {\r
308       af.setProgressBar("DAS Feature Fetching Complete", startTime);\r
309     }\r
310 \r
311     if (af != null && af.featureSettings != null)\r
312     {\r
313       af.featureSettings.setTableData();\r
314     }\r
315 \r
316     if (getFeatSettings() != null)\r
317     {\r
318       fsettings.complete();\r
319     }\r
320   }\r
321 \r
322   void featuresAdded(SequenceI seq)\r
323   {\r
324     if (af == null)\r
325     {\r
326       // no gui to update with features.\r
327       return;\r
328     }\r
329     af.getFeatureRenderer().featuresAdded();\r
330 \r
331     int start = af.getViewport().getStartSeq();\r
332     int end = af.getViewport().getEndSeq();\r
333     int index;\r
334     for (index = start; index < end; index++)\r
335     {\r
336       if (seq == af.getViewport().getAlignment().getSequenceAt(index)\r
337               .getDatasetSequence())\r
338       {\r
339         af.alignPanel.paintAlignment(true);\r
340         break;\r
341       }\r
342     }\r
343   }\r
344 \r
345   void nextSequence(DasSource dasSource, SequenceI seq)\r
346   {\r
347     if (cancelled)\r
348       return;\r
349     DBRefEntry[] uprefs = jalview.util.DBRefUtils.selectRefs(\r
350             seq.getDBRef(), new String[]\r
351             {\r
352             // jalview.datamodel.DBRefSource.PDB,\r
353             jalview.datamodel.DBRefSource.UNIPROT,\r
354             // jalview.datamodel.DBRefSource.EMBL - not tested on any EMBL coord\r
355             // sys sources\r
356             });\r
357     // TODO: minimal list of DAS queries to make by querying with untyped ID if\r
358     // distinct from any typed IDs\r
359 \r
360     boolean dasCoordSysFound = false;\r
361 \r
362     if (uprefs != null)\r
363     {\r
364       // do any of these ids match the source's coordinate system ?\r
365       for (int j = 0; !dasCoordSysFound && j < uprefs.length; j++)\r
366       {\r
367         DasCoordinateSystem cs[] = dasSource.getCoordinateSystem();\r
368 \r
369         for (int csIndex = 0; csIndex < cs.length && !dasCoordSysFound; csIndex++)\r
370         {\r
371           if (cs.length > 0\r
372                   && jalview.util.DBRefUtils.isDasCoordinateSystem(\r
373                           cs[csIndex].getName(), uprefs[j]))\r
374           {\r
375             debug("Launched fetcher for coordinate system "\r
376                     + cs[0].getName());\r
377             // Will have to pass any mapping information to the fetcher\r
378             // - the start/end for the DBRefEntry may not be the same as the\r
379             // sequence's start/end\r
380 \r
381             System.out.println(seq.getName() + " "\r
382                     + (seq.getDatasetSequence() == null) + " "\r
383                     + dasSource.getUrl());\r
384 \r
385             dasCoordSysFound = true; // break's out of the loop\r
386             createFeatureFetcher(seq, dasSource, uprefs[j]);\r
387           }\r
388           else\r
389             System.out.println("IGNORE " + cs[csIndex].getName());\r
390         }\r
391       }\r
392     }\r
393 \r
394     if (!dasCoordSysFound)\r
395     {\r
396       String id = null;\r
397       // try and use the name as the sequence id\r
398       if (seq.getName().indexOf("|") > -1)\r
399       {\r
400         id = seq.getName().substring(seq.getName().lastIndexOf("|") + 1);\r
401         if (id.trim().length() < 4)\r
402         {\r
403           // hack - we regard a significant ID as being at least 4\r
404           // non-whitespace characters\r
405           id = seq.getName().substring(0, seq.getName().lastIndexOf("|"));\r
406           if (id.indexOf("|") > -1)\r
407           {\r
408             id = id.substring(id.lastIndexOf("|") + 1);\r
409           }\r
410         }\r
411       }\r
412       else\r
413       {\r
414         id = seq.getName();\r
415       }\r
416       if (id != null)\r
417       {\r
418         // Should try to call a general feature fetcher that\r
419         // queries many sources with name to discover applicable ID references\r
420         createFeatureFetcher(seq, dasSource, id);\r
421       }\r
422     }\r
423 \r
424   }\r
425 \r
426   /**\r
427    * fetch and add das features to a sequence using the given source URL and\r
428    * compatible DbRef id. new features are mapped using the DbRef mapping to the\r
429    * local coordinate system.\r
430    * \r
431    * @param seq\r
432    * @param SourceUrl\r
433    * @param dbref\r
434    */\r
435   protected void createFeatureFetcher(final SequenceI seq,\r
436           final DasSource dasSource, final DBRefEntry dbref)\r
437   {\r
438 \r
439     // ////////////\r
440     // / fetch DAS features\r
441     final Das1Source source = new Das1Source();\r
442     source.setUrl(dasSource.getUrl());\r
443     source.setNickname(dasSource.getNickname());\r
444     if (dbref == null || dbref.getAccessionId() == null\r
445             || dbref.getAccessionId().length() < 1)\r
446     {\r
447       responseComplete(dasSource, seq); // reduce thread count anyhow\r
448       return;\r
449     }\r
450     debug("new Das Feature Fetcher for " + dbref.getSource() + ":"\r
451             + dbref.getAccessionId() + " querying " + dasSource.getUrl());\r
452     FeatureThread fetcher = new FeatureThread(dbref.getAccessionId()\r
453     // + ":" + start + "," + end,\r
454             , source);\r
455 \r
456     fetcher.addFeatureListener(new FeatureListener()\r
457     {\r
458       public void comeBackLater(FeatureEvent e)\r
459       {\r
460         responseComplete(dasSource, seq);\r
461         debug("das source " + e.getSource().getNickname()\r
462                 + " asked us to come back in " + e.getComeBackLater()\r
463                 + " secs.");\r
464       }\r
465 \r
466       public void newFeatures(FeatureEvent e)\r
467       {\r
468 \r
469         Das1Source ds = e.getSource();\r
470 \r
471         Map[] features = e.getFeatures();\r
472         // add features to sequence\r
473         debug("das source " + ds.getUrl() + " returned " + features.length\r
474                 + " features");\r
475 \r
476         if (features.length > 0)\r
477         {\r
478           for (int i = 0; i < features.length; i++)\r
479           {\r
480             // standard DAS feature-> jalview sequence feature transformation\r
481             SequenceFeature f = newSequenceFeature(features[i], source\r
482                     .getNickname());\r
483             if (!parseSeqFeature(seq, f, features[i], source))\r
484             {\r
485               if (dbref.getMap() != null && f.getBegin() > 0\r
486                       && f.getEnd() > 0)\r
487               {\r
488                 debug("mapping from " + f.getBegin() + " - " + f.getEnd());\r
489                 SequenceFeature vf[] = null;\r
490 \r
491                 try\r
492                 {\r
493                   vf = dbref.getMap().locateFeature(f);\r
494                 } catch (Exception ex)\r
495                 {\r
496                   Cache.log\r
497                           .info("Error in 'experimental' mapping of features. Please try to reproduce and then report info to jalview-discuss@jalview.org.");\r
498                   Cache.log.info("Mapping feature from " + f.getBegin()\r
499                           + " to " + f.getEnd() + " in dbref "\r
500                           + dbref.getAccessionId() + " in "\r
501                           + dbref.getSource());\r
502                   Cache.log.info("using das Source " + ds.getUrl());\r
503                   Cache.log.info("Exception", ex);\r
504                 }\r
505 \r
506                 if (vf != null)\r
507                 {\r
508                   for (int v = 0; v < vf.length; v++)\r
509                   {\r
510                     debug("mapping to " + v + ": " + vf[v].getBegin()\r
511                             + " - " + vf[v].getEnd());\r
512                     seq.addSequenceFeature(vf[v]);\r
513                   }\r
514                 }\r
515               }\r
516               else\r
517               {\r
518                 seq.addSequenceFeature(f);\r
519               }\r
520             }\r
521           }\r
522           featuresAdded(seq);\r
523         }\r
524         else\r
525         {\r
526           // System.out.println("No features found for " + seq.getName()\r
527           // + " from: " + e.getDasSource().getNickname());\r
528         }\r
529         responseComplete(dasSource, seq);\r
530 \r
531       }\r
532     }\r
533 \r
534     );\r
535 \r
536     fetcher.start();\r
537   }\r
538 \r
539   protected void createFeatureFetcher(final SequenceI seq,\r
540           final DasSource dasSource, String id)\r
541   {\r
542     // ////////////\r
543     // / fetch DAS features\r
544     final Das1Source source = new Das1Source();\r
545     source.setUrl(dasSource.getUrl());\r
546     source.setNickname(dasSource.getNickname());\r
547 \r
548     if (id != null)\r
549     {\r
550       id = id.trim();\r
551     }\r
552     if (id != null && id.length() > 0)\r
553     {\r
554       debug("new Das Feature Fetcher for " + id + " querying "\r
555               + dasSource.getUrl());\r
556       FeatureThread fetcher = new FeatureThread(id\r
557       // + ":" + start + "," + end,\r
558               , source);\r
559 \r
560       fetcher.addFeatureListener(new FeatureListener()\r
561       {\r
562         public void comeBackLater(FeatureEvent e)\r
563         {\r
564           responseComplete(dasSource, seq);\r
565           debug("das source " + e.getSource().getNickname()\r
566                   + " asked us to come back in " + e.getComeBackLater()\r
567                   + " secs.");\r
568         }\r
569 \r
570         public void newFeatures(FeatureEvent e)\r
571         {\r
572 \r
573           Das1Source ds = e.getSource();\r
574 \r
575           Map[] features = e.getFeatures();\r
576           // add features to sequence\r
577           debug("das source " + ds.getUrl() + " returned "\r
578                   + features.length + " features");\r
579 \r
580           if (features.length > 0)\r
581           {\r
582             for (int i = 0; i < features.length; i++)\r
583             {\r
584               // standard DAS feature-> jalview sequence feature transformation\r
585               SequenceFeature f = newSequenceFeature(features[i], source\r
586                       .getNickname());\r
587               if (!parseSeqFeature(seq, f, features[i], source))\r
588               {\r
589                 // just add as a simple sequence feature\r
590                 seq.addSequenceFeature(f);\r
591               }\r
592             }\r
593 \r
594             featuresAdded(seq);\r
595           }\r
596           else\r
597           {\r
598             // System.out.println("No features found for " + seq.getName()\r
599             // + " from: " + e.getDasSource().getNickname());\r
600           }\r
601           responseComplete(dasSource, seq);\r
602 \r
603         }\r
604       }\r
605 \r
606       );\r
607 \r
608       fetcher.start();\r
609     }\r
610     else\r
611     {\r
612       // invalid fetch - indicate it is finished.\r
613       debug("Skipping empty ID for querying " + dasSource.getUrl());\r
614       responseComplete(dasSource, seq);\r
615     }\r
616   }\r
617 \r
618   /**\r
619    * examine the given sequence feature to determine if it should actually\r
620    * be turned into sequence annotation or database cross references rather\r
621    * than a simple sequence feature. \r
622    * @param seq the sequence to annotate\r
623    * @param f the jalview sequence feature generated from the DAS feature \r
624    * @param map the sequence feature attributes\r
625    * @param source the source that emitted the feature\r
626    * @return true if feature was consumed as another kind of annotation.\r
627    */\r
628   protected boolean parseSeqFeature(SequenceI seq, SequenceFeature f, Map map,\r
629           Das1Source source)\r
630   {\r
631     // check if source has biosapiens or other sequence ontology label\r
632     if (f.getType()!=null && (f.getType().equalsIgnoreCase("DBXREF")\r
633             || f.getType().equalsIgnoreCase("DBREF")))\r
634     {\r
635       // try to parse the accession out\r
636       \r
637       DBRefEntry dbr = new DBRefEntry();\r
638       dbr.setVersion(source.getNickname());\r
639       StringTokenizer st = new StringTokenizer(f.getDescription(),":");\r
640       if (st.hasMoreTokens())\r
641       {\r
642         dbr.setSource(st.nextToken());\r
643       }\r
644       if (st.hasMoreTokens())\r
645       {\r
646         dbr.setAccessionId(st.nextToken());\r
647       }\r
648       seq.addDBRef(dbr);\r
649       return true;\r
650     }\r
651     return false;\r
652   }\r
653 \r
654   /**\r
655    * creates a jalview sequence feature from a das feature document\r
656    * \r
657    * @param dasfeature\r
658    * @return sequence feature object created using dasfeature information\r
659    */\r
660   SequenceFeature newSequenceFeature(Map dasfeature, String nickname)\r
661   {\r
662     if (dasfeature == null)\r
663     {\r
664       return null;\r
665     }\r
666     try\r
667     {\r
668       /**\r
669        * Different qNames for a DAS Feature - are string keys to the HashMaps in\r
670        * features "METHOD") || qName.equals("TYPE") || qName.equals("START") ||\r
671        * qName.equals("END") || qName.equals("NOTE") || qName.equals("LINK") ||\r
672        * qName.equals("SCORE")\r
673        */\r
674       String desc = new String();\r
675       if (dasfeature.containsKey("NOTE"))\r
676       {\r
677         desc += (String) dasfeature.get("NOTE");\r
678       }\r
679 \r
680       int start = 0, end = 0;\r
681       float score = 0f;\r
682 \r
683       try\r
684       {\r
685         start = Integer.parseInt(dasfeature.get("START").toString());\r
686       } catch (Exception ex)\r
687       {\r
688       }\r
689       try\r
690       {\r
691         end = Integer.parseInt(dasfeature.get("END").toString());\r
692       } catch (Exception ex)\r
693       {\r
694       }\r
695       try\r
696       {\r
697         Object scr = dasfeature.get("SCORE");\r
698         if (scr!=null)\r
699           {score = (float) Double.parseDouble(scr.toString());\r
700           \r
701           }\r
702       } catch (Exception ex)\r
703       {\r
704       }\r
705 \r
706       SequenceFeature f = new SequenceFeature((String) dasfeature\r
707               .get("TYPE"), desc, start, end, score, nickname);\r
708 \r
709       if (dasfeature.containsKey("LINK"))\r
710       {\r
711         // Do not put feature extent in link text for non-positional features\r
712         if (f.begin == 0 && f.end == 0)\r
713         {\r
714           f.addLink(f.getType() + "|" + dasfeature.get("LINK"));\r
715         }\r
716         else\r
717         {\r
718           f.addLink(f.getType() + " " + f.begin + "_" + f.end + "|"\r
719                   + dasfeature.get("LINK"));\r
720         }\r
721       }\r
722 \r
723       return f;\r
724     } catch (Exception e)\r
725     {\r
726       System.out.println("ERRR " + e);\r
727       e.printStackTrace();\r
728       System.out.println("############");\r
729       debug("Failed to parse " + dasfeature.toString(), e);\r
730       return null;\r
731     }\r
732   }\r
733 \r
734   /**\r
735    * query the default DAS Source Registry for sources. Uses value of jalview\r
736    * property DAS_REGISTRY_URL and the DasSourceBrowser.DEFAULT_REGISTRY if that\r
737    * doesn't exist.\r
738    * \r
739    * @return list of sources\r
740    */\r
741   public static DasSource[] getDASSources()\r
742   {\r
743 \r
744     String registryURL = jalview.bin.Cache.getDefault("DAS_REGISTRY_URL",\r
745             DasSourceBrowser.DEFAULT_REGISTRY);\r
746     return getDASSources(registryURL);\r
747   }\r
748 \r
749   /**\r
750    * query the given URL for DasSources.\r
751    * \r
752    * @param registryURL\r
753    *                return sources from registryURL\r
754    */\r
755   public static DasSource[] getDASSources(String registryURL)\r
756   {\r
757     DasSourceReaderImpl reader = new DasSourceReaderImpl();\r
758 \r
759     try\r
760     {\r
761       URL url = new URL(registryURL);\r
762 \r
763       DasSource[] sources = reader.readDasSource(url);\r
764 \r
765       List das1sources = new ArrayList();\r
766       for (int i = 0; i < sources.length; i++)\r
767       {\r
768         DasSource ds = sources[i];\r
769         if (ds instanceof Das2Source)\r
770         {\r
771           Das2Source d2s = (Das2Source) ds;\r
772           if (d2s.hasDas1Capabilities())\r
773           {\r
774             Das1Source d1s = DasSourceConverter.toDas1Source(d2s);\r
775             das1sources.add(d1s);\r
776           }\r
777 \r
778         }\r
779         else if (ds instanceof Das1Source)\r
780         {\r
781           das1sources.add((Das1Source) ds);\r
782         }\r
783       }\r
784 \r
785       return (Das1Source[]) das1sources.toArray(new Das1Source[das1sources\r
786               .size()]);\r
787     } catch (Exception ex)\r
788     {\r
789       ex.printStackTrace();\r
790       return null;\r
791     }\r
792   }\r
793 \r
794 }\r