removed all dasobert code and begun to replace with Jdas calls.
[jalview.git] / src / jalview / gui / DasSourceBrowser.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)\r
3  * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
4  * \r
5  * This file is part of Jalview.\r
6  * \r
7  * Jalview is free software: you can redistribute it and/or\r
8  * modify it under the terms of the GNU General Public License \r
9  * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\r
10  * \r
11  * Jalview is distributed in the hope that it will be useful, but \r
12  * WITHOUT ANY WARRANTY; without even the implied warranty \r
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
14  * PURPOSE.  See the GNU General Public License for more details.\r
15  * \r
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.\r
17  */\r
18 package jalview.gui;\r
19 \r
20 import java.security.interfaces.DSAKey;\r
21 import java.text.ParseException;\r
22 import java.util.*;\r
23 import java.util.List;\r
24 \r
25 import java.awt.*;\r
26 import java.awt.event.*;\r
27 import javax.swing.*;\r
28 import javax.swing.event.*;\r
29 import javax.swing.table.*;\r
30 \r
31 import org.biodas.jdas.dassources.Capabilities;\r
32 import org.biodas.jdas.dassources.utils.DasTimeFormat;\r
33 import org.biodas.jdas.schema.sources.CAPABILITY;\r
34 import org.biodas.jdas.schema.sources.COORDINATES;\r
35 import org.biodas.jdas.schema.sources.MAINTAINER;\r
36 import org.biodas.jdas.schema.sources.PROP;\r
37 import org.biodas.jdas.schema.sources.SOURCE;\r
38 import org.biodas.jdas.schema.sources.SOURCES;\r
39 import org.biodas.jdas.schema.sources.VERSION;\r
40 \r
41 import jalview.jbgui.*;\r
42 import jalview.util.*;\r
43 \r
44 public class DasSourceBrowser extends GDasSourceBrowser implements\r
45         Runnable, ListSelectionListener\r
46 {\r
47   static org.biodas.jdas.schema.sources.SOURCE[] dasSources = null;\r
48 \r
49   Hashtable localSources = null;\r
50 \r
51   Vector selectedSources;\r
52 \r
53   public static String DEFAULT_REGISTRY = "http://www.dasregistry.org/das1/sources/";\r
54 \r
55   /**\r
56    * true if thread is running and we are talking to DAS registry service\r
57    */\r
58   public boolean loadingDasSources = false;\r
59 \r
60   protected static String getDasRegistryURL()\r
61   {\r
62     String registry = jalview.bin.Cache.getDefault("DAS_REGISTRY_URL",\r
63             DEFAULT_REGISTRY);\r
64 \r
65     if (registry.indexOf("/registry/das1/sources/") > -1)\r
66     {\r
67       jalview.bin.Cache.setProperty(jalview.bin.Cache.DAS_REGISTRY_URL,\r
68               DEFAULT_REGISTRY);\r
69       registry = DEFAULT_REGISTRY;\r
70     }\r
71     return registry;\r
72   }\r
73 \r
74   public DasSourceBrowser(FeatureSettings featureSettings)\r
75   {\r
76     fs = featureSettings;\r
77     String registry = getDasRegistryURL();\r
78 \r
79     registryURL.setText(registry);\r
80 \r
81     setSelectedFromProperties();\r
82 \r
83     displayFullDetails(null);\r
84     table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\r
85 \r
86     filter1.addListSelectionListener(this);\r
87     filter2.addListSelectionListener(this);\r
88     filter3.addListSelectionListener(this);\r
89 \r
90     // Ask to be notified of selection changes.\r
91     ListSelectionModel rowSM = table.getSelectionModel();\r
92     rowSM.addListSelectionListener(new ListSelectionListener()\r
93     {\r
94       public void valueChanged(ListSelectionEvent e)\r
95       {\r
96         ListSelectionModel lsm = (ListSelectionModel) e.getSource();\r
97         if (!lsm.isSelectionEmpty())\r
98         {\r
99           int selectedRow = lsm.getMinSelectionIndex();\r
100           displayFullDetails(table.getValueAt(selectedRow, 0).toString());\r
101         }\r
102       }\r
103     });\r
104 \r
105     table.addMouseListener(new MouseAdapter()\r
106     {\r
107       public void mouseClicked(MouseEvent evt)\r
108       {\r
109         if (evt.getClickCount() == 2\r
110                 || SwingUtilities.isRightMouseButton(evt))\r
111         {\r
112           editRemoveLocalSource(evt);\r
113         }\r
114       }\r
115     });\r
116 \r
117     if (dasSources != null)\r
118     {\r
119       init();\r
120     }\r
121   }\r
122 \r
123   FeatureSettings fs = null;\r
124 \r
125   public DasSourceBrowser()\r
126   {\r
127     this(null);\r
128   }\r
129 \r
130   public void paintComponent(java.awt.Graphics g)\r
131   {\r
132     if (dasSources == null && !loadingDasSources)\r
133     {\r
134       Thread worker = new Thread(this);\r
135       worker.start();\r
136     }\r
137   }\r
138 \r
139   void init()\r
140   {\r
141     int dSize = dasSources.length;\r
142     Object[][] data = new Object[dSize][2];\r
143     for (int i = 0; i < dSize; i++)\r
144     {\r
145       data[i][0] = dasSources[i]. // what's equivalent of nickname\r
146       data[i][1] = new Boolean(selectedSources.contains(dasSources[i]\r
147               .getNickname()));\r
148     }\r
149 \r
150     refreshTableData(data);\r
151     setCapabilities(dasSources);\r
152 \r
153     javax.swing.SwingUtilities.invokeLater(new Runnable()\r
154     {\r
155       public void run()\r
156       {\r
157         TableSorter sorter = (TableSorter) table.getModel();\r
158         sorter.setSortingStatus(1, TableSorter.DESCENDING);\r
159         sorter.setSortingStatus(1, TableSorter.NOT_SORTED);\r
160       }\r
161     });\r
162 \r
163     progressBar.setIndeterminate(false);\r
164     progressBar.setVisible(false);\r
165     addLocal.setVisible(true);\r
166     refresh.setVisible(true);\r
167   }\r
168 \r
169   public void refreshTableData(Object[][] data)\r
170   {\r
171     TableSorter sorter = new TableSorter(new DASTableModel(data));\r
172     sorter.setTableHeader(table.getTableHeader());\r
173     table.setModel(sorter);\r
174   }\r
175 \r
176   void displayFullDetails(String nickName)\r
177   {\r
178 \r
179     StringBuffer text = new StringBuffer(\r
180             "<HTML><font size=\"2\" face=\"Verdana, Arial, Helvetica, sans-serif\">");\r
181 \r
182     if (nickName == null)\r
183     {\r
184       fullDetails.setText(text + "Select a DAS service from the table"\r
185               + " to read a full description here.</font></html>");\r
186       return;\r
187     }\r
188 \r
189     int dSize = dasSources.length;\r
190     for (int i = 0; i < dSize; i++)\r
191     {\r
192       if (!dasSources[i].getNickname().equals(nickName))\r
193       {\r
194         continue;\r
195       }\r
196 \r
197       DasSource ds = dasSources[i];\r
198 \r
199       text.append("<font color=\"#0000FF\">Id:</font> "\r
200               + dasSources[i].getId() + "<br>");\r
201       text.append("<font color=\"#0000FF\">Nickname:</font> "\r
202               + dasSources[i].getNickname() + "<br>");\r
203       text.append("<font color=\"#0000FF\">URL:</font> "\r
204               + dasSources[i].getUrl() + "<br>");\r
205 \r
206       text.append("<font color=\"#0000FF\">Admin Email:</font> <a href=\"mailto:"\r
207               + dasSources[i].getAdminemail()\r
208               + "\">"\r
209               + dasSources[i].getAdminemail() + "</a>" + "<br>");\r
210 \r
211       text.append("<font color=\"#0000FF\">Registered at:</font> "\r
212               + dasSources[i].getRegisterDate() + "<br>");\r
213 \r
214       text.append("<font color=\"#0000FF\">Last successful test:</font> "\r
215               + dasSources[i].getLeaseDate() + "<br>");\r
216 \r
217       text.append("<font color=\"#0000FF\">Labels:</font> ");\r
218       for (int s = 0; s < dasSources[i].getLabels().length; s++)\r
219       {\r
220         text.append(dasSources[i].getLabels()[s]);\r
221         if (s < dasSources[i].getLabels().length - 1)\r
222         {\r
223           text.append(",");\r
224         }\r
225         text.append(" ");\r
226       }\r
227       text.append("<br>");\r
228 \r
229       text.append("<font color=\"#0000FF\">Capabilities:</font> ");\r
230       String[] scap = dasSources[i].getCapabilities();\r
231       for (int j = 0; j < scap.length; j++)\r
232       {\r
233         text.append(scap[j]);\r
234         if (j < scap.length - 1)\r
235         {\r
236           text.append(", ");\r
237         }\r
238       }\r
239       text.append("<br>");\r
240 \r
241       text.append("<font color=\"#0000FF\">Coordinates:</font> ");\r
242       DasCoordinateSystem[] dcs = ds.getCoordinateSystem();\r
243       for (int j = 0; j < dcs.length; j++)\r
244       {\r
245         text.append("(" + dcs[j].getUniqueId() + ") "\r
246                 + dcs[j].getCategory() + ", " + dcs[j].getName());\r
247         if (dcs[j].getNCBITaxId() != 0)\r
248         {\r
249           text.append(", " + dcs[j].getNCBITaxId());\r
250         }\r
251         if (dcs[j].getOrganismName().length() > 0)\r
252         {\r
253           text.append(", " + dcs[j].getOrganismName());\r
254         }\r
255 \r
256         text.append("<br>");\r
257       }\r
258 \r
259       text.append("<font color=\"#0000FF\">Description:</font> "\r
260               + dasSources[i].getDescription() + "<br>");\r
261 \r
262       if (dasSources[i].getHelperurl() != null\r
263               && dasSources[i].getHelperurl().length() > 0)\r
264       {\r
265         text.append("<font color=\"#0000FF\"><a href=\""\r
266                 + dasSources[i].getHelperurl()\r
267                 + "\">Go to site</a></font<br>");\r
268       }\r
269 \r
270       text.append("</font></html>");\r
271 \r
272       break;\r
273     }\r
274 \r
275     fullDetails.setText(text.toString());\r
276     javax.swing.SwingUtilities.invokeLater(new Runnable()\r
277     {\r
278       public void run()\r
279       {\r
280         fullDetailsScrollpane.getVerticalScrollBar().setValue(0);\r
281       }\r
282     });\r
283   }\r
284 \r
285   public void run()\r
286   {\r
287     loadingDasSources = true;\r
288 \r
289     addLocal.setVisible(false);\r
290     refresh.setVisible(false);\r
291     progressBar.setVisible(true);\r
292     progressBar.setIndeterminate(true);\r
293     setParentGuiEnabled(false);\r
294     // Refresh the source list.\r
295     dasSources = null;\r
296     getDASSource();\r
297 \r
298     init();\r
299 \r
300     setParentGuiEnabled(true);\r
301     loadingDasSources = false;\r
302 \r
303   }\r
304 \r
305   private void setParentGuiEnabled(boolean b)\r
306   {\r
307     if (fs != null)\r
308     {\r
309       fs.fetchDAS.setEnabled(b);\r
310       fs.saveDAS.setEnabled(b);\r
311     }\r
312   }\r
313 \r
314   public Vector getSelectedSources()\r
315   {\r
316     // wait around if we're still loading.\r
317     while (dasSources == null)\r
318     {\r
319       if (!loadingDasSources)\r
320       {\r
321         new Thread(this).start();\r
322         try\r
323         {\r
324           Thread.sleep(5);\r
325         } catch (Exception e)\r
326         {\r
327         }\r
328         ;\r
329         while (loadingDasSources)\r
330         {\r
331           try\r
332           {\r
333             Thread.sleep(5);\r
334           } catch (Exception e)\r
335           {\r
336           }\r
337           ;\r
338         }\r
339         ;\r
340       }\r
341     }\r
342 \r
343     Vector selected = new Vector();\r
344     for (int r = 0; r < selectedSources.size(); r++)\r
345     {\r
346       for (int i = 0; i < dasSources.length; i++)\r
347       {\r
348         if (dasSources[i].getNickname()\r
349                 .equals(selectedSources.elementAt(r)))\r
350         {\r
351           selected.addElement(dasSources[i]);\r
352           break;\r
353         }\r
354       }\r
355     }\r
356 \r
357     return selected;\r
358   }\r
359 \r
360   /**\r
361    * retrieve das sources from registry and add local source list\r
362    * \r
363    * @return\r
364    */\r
365   public DasSource[] getDASSource()\r
366   {\r
367     if (dasSources == null)\r
368     {\r
369       dasSources = jalview.ws.DasSequenceFeatureFetcher.getDASSources();\r
370       appendLocalSources();\r
371     }\r
372 \r
373     return dasSources;\r
374   }\r
375 \r
376   public void refresh_actionPerformed(ActionEvent e)\r
377   {\r
378     saveProperties(jalview.bin.Cache.applicationProperties);\r
379 \r
380     Thread worker = new Thread(this);\r
381     worker.start();\r
382   }\r
383 \r
384   private boolean isLaterThan(String ref, String newer)\r
385   {\r
386     Date refdate=null,newdate=null;\r
387     try {\r
388       refdate=DasTimeFormat.fromDASString(ref);\r
389       \r
390     }\r
391     catch (ParseException x)\r
392     {\r
393       return false;\r
394     }\r
395     try {\r
396       newdate = DasTimeFormat.fromDASString(newer);\r
397     }\r
398     catch (ParseException e) {\r
399       // TODO: handle exception\r
400     }\r
401     if (refdate!=null)\r
402     {\r
403       if (newdate!=null)\r
404       {\r
405         return refdate.before(newdate);\r
406       }\r
407       return false;\r
408     }\r
409     if (newdate!=null)\r
410     {\r
411       return true;\r
412     }\r
413     // assume first instance of source is newest in list. - TODO: check if natural ordering of source versions is newest first or oldest first\r
414     return false;\r
415   }\r
416   private void setCapabilities(SOURCE[] sources)\r
417   {\r
418     Vector<String> authority = new Vector<String>();\r
419     Vector<String> type = new Vector<String>();\r
420     Vector<String> label = new Vector<String>();\r
421     Vector<String> taxIds=new Vector<String>();\r
422     authority.add("Any");\r
423     type.add("Any");\r
424     label.add("Any");\r
425     \r
426 \r
427     for (int i = 0; i < sources.length; i++)\r
428     {\r
429       SOURCE ds = sources[i];\r
430       VERSION latest=null;\r
431       for (VERSION v:ds.getVERSION()) {\r
432         if (latest==null || isLaterThan(latest.getCreated(),v.getCreated()))\r
433         {\r
434           // TODO: das 1.6 - should just get the first version - ignore other versions since not specified how to construct URL from version's URI + source URI\r
435           latest=v;\r
436         }\r
437       }\r
438       \r
439       for (COORDINATES cs: latest.getCOORDINATES())\r
440       {\r
441         if (!type.contains(cs.getSource()))\r
442         {\r
443           type.add(cs.getSource()); // source==category\r
444         }\r
445 \r
446         if (!authority.contains(cs.getAuthority()))\r
447         {\r
448           authority.add(cs.getAuthority());\r
449         }\r
450       }\r
451 \r
452       for (PROP slabel:latest.getPROP())\r
453       {\r
454         if (slabel.getName().equalsIgnoreCase("LABEL") && !label.contains(slabel.getValue()))\r
455         {\r
456           label.add(slabel.getValue());\r
457         }\r
458       }\r
459 \r
460     }\r
461 \r
462     filter1.setListData(authority);\r
463     filter2.setListData(type);\r
464     filter3.setListData(label);\r
465     // filter4 taxIds\r
466 \r
467     javax.swing.SwingUtilities.invokeLater(new Runnable()\r
468     {\r
469       public void run()\r
470       {\r
471         filter1.setSelectedIndex(0);\r
472         filter2.setSelectedIndex(0);\r
473         filter3.setSelectedIndex(0);\r
474       }\r
475     });\r
476   }\r
477 \r
478   public void amendLocal(boolean newSource)\r
479   {\r
480     String url = "http://localhost:8080/", nickname = "";\r
481     boolean seqsrc = false;\r
482     if (!newSource)\r
483     {\r
484       int selectedRow = table.getSelectionModel().getMinSelectionIndex();\r
485       nickname = table.getValueAt(selectedRow, 0).toString();\r
486       url = ((SOURCE) localSources.get(nickname)).getUri();\r
487       seqsrc = ((SOURCE) localSources.get(nickname)).getVERSION().get(0).getCAPABILITY().contains(Capabilities.SEQUENCE);\r
488     }\r
489 \r
490     JTextField nametf = new JTextField(nickname, 40);\r
491     JTextField urltf = new JTextField(url, 40);\r
492     JCheckBox seqs = new JCheckBox("Sequence Source");\r
493     seqs.setSelected(seqsrc);\r
494     JPanel panel = new JPanel(new BorderLayout());\r
495     JPanel pane12 = new JPanel(new BorderLayout());\r
496     pane12.add(new JLabel("Nickname: "), BorderLayout.CENTER);\r
497     pane12.add(nametf, BorderLayout.EAST);\r
498     panel.add(pane12, BorderLayout.NORTH);\r
499     pane12 = new JPanel(new BorderLayout());\r
500     pane12.add(new JLabel("URL: "), BorderLayout.NORTH);\r
501     pane12.add(seqs, BorderLayout.SOUTH);\r
502     pane12.add(urltf, BorderLayout.EAST);\r
503     panel.add(pane12, BorderLayout.SOUTH);\r
504 \r
505     int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,\r
506             panel, "Enter Nickname & URL of Local DAS Source",\r
507             JOptionPane.OK_CANCEL_OPTION);\r
508 \r
509     if (reply != JOptionPane.OK_OPTION)\r
510     {\r
511       return;\r
512     }\r
513 \r
514     if (!urltf.getText().endsWith("/"))\r
515     {\r
516       urltf.setText(urltf.getText() + "/");\r
517     }\r
518 \r
519     // build using pattern from test: sourcesclientImplTest\r
520     {\r
521       SOURCE source = new SOURCE();\r
522       String uri = "http://das.sanger.ac.uk/das/dummysource";\r
523       source.setUri("http://das.sanger.ac.uk/das/dummysource");\r
524       source.setDescription("Dummy Test Source, should not be in a working registry sources doc");\r
525       VERSION version = new VERSION();\r
526       version.setUri(uri);\r
527       COORDINATES coord = new COORDINATES();\r
528       coord.setAuthority("NCBI");\r
529       coord.setSource("Chromosome");\r
530       coord.setTaxid("9606");\r
531       coord.setVersion("35");\r
532       version.getCOORDINATES().add(coord);\r
533       CAPABILITY cap = new CAPABILITY();\r
534       cap.setQueryUri(uri + "features");\r
535       cap.setType("das1:" + Capabilities.FEATURES.getName());\r
536       version.getCAPABILITY().add(cap);\r
537       source.getVERSION().add(version);\r
538       MAINTAINER m = new MAINTAINER();\r
539       m.setEmail("jw12@sanger.ac.uk");\r
540       source.setMAINTAINER(m);\r
541       source.setTitle("dummy title");\r
542 \r
543     }\r
544     SOURCE local = new Das1Source();\r
545 \r
546     local.setUrl(urltf.getText());\r
547     local.setNickname(nametf.getText());\r
548     if (seqs.isSelected())\r
549     {\r
550       local.setCapabilities(new String[]\r
551       { "features", "sequence" });\r
552     }\r
553     if (localSources == null)\r
554     {\r
555       localSources = new Hashtable();\r
556     }\r
557 \r
558     localSources.put(local.getNickname(), local);\r
559 \r
560     if (!newSource && !nickname.equals(nametf.getText()))\r
561     {\r
562       localSources.remove(nickname);\r
563     }\r
564 \r
565     int size = dasSources.length;\r
566     int adjust = newSource ? 1 : 0;\r
567 \r
568     Object[][] data = new Object[size + adjust][2];\r
569     for (int i = 0; i < size; i++)\r
570     {\r
571       if (!newSource && dasSources[i].getNickname().equals(nickname))\r
572       {\r
573         ((DasSource) dasSources[i]).setNickname(local.getNickname());\r
574         ((DasSource) dasSources[i]).setUrl(local.getUrl());\r
575         data[i][0] = local.getNickname();\r
576         data[i][1] = new Boolean(true);\r
577       }\r
578       else\r
579       {\r
580         data[i][0] = dasSources[i].getNickname();\r
581         data[i][1] = new Boolean(selectedSources.contains(dasSources[i]\r
582                 .getNickname()));\r
583       }\r
584     }\r
585 \r
586     if (newSource)\r
587     {\r
588       data[size][0] = local.getNickname();\r
589       data[size][1] = new Boolean(true);\r
590       selectedSources.add(local.getNickname());\r
591     }\r
592 \r
593     DasSource[] tmp = new DasSource[size + adjust];\r
594 \r
595     System.arraycopy(dasSources, 0, tmp, 0, size);\r
596 \r
597     if (newSource)\r
598     {\r
599       tmp[size] = local;\r
600     }\r
601 \r
602     dasSources = tmp;\r
603 \r
604     refreshTableData(data);\r
605 \r
606     SwingUtilities.invokeLater(new Runnable()\r
607     {\r
608       public void run()\r
609       {\r
610         scrollPane.getVerticalScrollBar().setValue(\r
611                 scrollPane.getVerticalScrollBar().getMaximum());\r
612       }\r
613     });\r
614 \r
615     displayFullDetails(local.getNickname());\r
616   }\r
617 \r
618   public void editRemoveLocalSource(MouseEvent evt)\r
619   {\r
620     int selectedRow = table.getSelectionModel().getMinSelectionIndex();\r
621     if (selectedRow == -1)\r
622     {\r
623       return;\r
624     }\r
625 \r
626     String nickname = table.getValueAt(selectedRow, 0).toString();\r
627 \r
628     if (!localSources.containsKey(nickname))\r
629     {\r
630       JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
631               "You can only edit or remove local DAS Sources!",\r
632               "Public DAS source - not editable",\r
633               JOptionPane.WARNING_MESSAGE);\r
634       return;\r
635     }\r
636 \r
637     Object[] options =\r
638     { "Edit", "Remove", "Cancel" };\r
639     int choice = JOptionPane.showInternalOptionDialog(Desktop.desktop,\r
640             "Do you want to edit or remove " + nickname + "?",\r
641             "Edit / Remove Local DAS Source",\r
642             JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE,\r
643             null, options, options[2]);\r
644 \r
645     switch (choice)\r
646     {\r
647     case 0:\r
648       amendLocal(false);\r
649       break;\r
650     case 1:\r
651       localSources.remove(nickname);\r
652       selectedSources.remove(nickname);\r
653       Object[][] data = new Object[dasSources.length - 1][2];\r
654       DasSource[] tmp = new DasSource[dasSources.length - 1];\r
655       int index = 0;\r
656       for (int i = 0; i < dasSources.length; i++)\r
657       {\r
658         if (dasSources[i].getNickname().equals(nickname))\r
659         {\r
660           continue;\r
661         }\r
662         else\r
663         {\r
664           tmp[index] = dasSources[i];\r
665           data[index][0] = dasSources[i].getNickname();\r
666           data[index][1] = new Boolean(\r
667                   selectedSources.contains(dasSources[i].getNickname()));\r
668           index++;\r
669         }\r
670       }\r
671       dasSources = tmp;\r
672       refreshTableData(data);\r
673       SwingUtilities.invokeLater(new Runnable()\r
674       {\r
675         public void run()\r
676         {\r
677           scrollPane.getVerticalScrollBar().setValue(\r
678                   scrollPane.getVerticalScrollBar().getMaximum());\r
679         }\r
680       });\r
681 \r
682       break;\r
683     }\r
684   }\r
685 \r
686   void appendLocalSources()\r
687   {\r
688     if (localSources == null)\r
689     {\r
690       return;\r
691     }\r
692     // note - we add all das sources to list so they can be filtered for the\r
693     // standard fetchDbRefs function\r
694     int size = dasSources != null ? dasSources.length : 0;\r
695     int lsize = localSources.size();\r
696 \r
697     Object[][] data = new Object[size + lsize][2];\r
698     for (int i = 0; i < size; i++)\r
699     {\r
700       data[i][0] = dasSources[i].getNickname();\r
701       data[i][1] = new Boolean(selectedSources.contains(dasSources[i]\r
702               .getNickname()));\r
703     }\r
704 \r
705     DasSource[] tmp = new DasSource[size + lsize];\r
706     if (dasSources != null)\r
707     {\r
708       System.arraycopy(dasSources, 0, tmp, 0, size);\r
709     }\r
710 \r
711     Enumeration en = localSources.keys();\r
712     int index = size;\r
713     while (en.hasMoreElements())\r
714     {\r
715       String key = en.nextElement().toString();\r
716       data[index][0] = key;\r
717       data[index][1] = new Boolean(false);\r
718       tmp[index] = new Das1Source();\r
719       tmp[index].setNickname(key);\r
720       tmp[index].setUrl(((DasSource) localSources.get(key)).getUrl());\r
721 \r
722       index++;\r
723     }\r
724 \r
725     dasSources = tmp;\r
726 \r
727     refreshTableData(data);\r
728   }\r
729 \r
730   public void valueChanged(ListSelectionEvent evt)\r
731   {\r
732     // Called when the MainTable selection changes\r
733     if (evt.getValueIsAdjusting())\r
734     {\r
735       return;\r
736     }\r
737 \r
738     displayFullDetails(null);\r
739 \r
740     // Filter the displayed data sources\r
741     int dSize = dasSources.length;\r
742 \r
743     ArrayList names = new ArrayList();\r
744     ArrayList selected = new ArrayList();\r
745     DasSource ds;\r
746 \r
747     // The features filter is not visible, but we must still\r
748     // filter the das source list here.\r
749     // July 2006 - only 6 sources fo not serve features\r
750     Object[] dummyFeatureList = new Object[]\r
751     { "features" };\r
752 \r
753     for (int i = 0; i < dSize; i++)\r
754     {\r
755       ds = dasSources[i];\r
756       DasCoordinateSystem[] dcs = ds.getCoordinateSystem();\r
757 \r
758       if (dcs.length == 0 && ds.getCapabilities().length == 0\r
759               && filter1.getSelectedIndex() == 0\r
760               && filter2.getSelectedIndex() == 0\r
761               && filter3.getSelectedIndex() == 0)\r
762       {\r
763         // THIS IS A FIX FOR LOCAL SOURCES WHICH DO NOT\r
764         // HAVE COORDINATE SYSTEMS, INFO WHICH AT PRESENT\r
765         // IS ADDED FROM THE REGISTRY\r
766         names.add(ds.getNickname());\r
767         selected.add(new Boolean(selectedSources.contains(ds.getNickname())));\r
768         continue;\r
769       }\r
770 \r
771       if (!selectedInList(dummyFeatureList, ds.getCapabilities())\r
772               || !selectedInList(filter3.getSelectedValues(),\r
773                       ds.getLabels()))\r
774       {\r
775         continue;\r
776       }\r
777 \r
778       for (int j = 0; j < dcs.length; j++)\r
779       {\r
780         if (selectedInList(filter1.getSelectedValues(), new String[]\r
781         { dcs[j].getName() })\r
782                 && selectedInList(filter2.getSelectedValues(), new String[]\r
783                 { dcs[j].getCategory() }))\r
784         {\r
785           names.add(ds.getNickname());\r
786           selected.add(new Boolean(selectedSources.contains(ds\r
787                   .getNickname())));\r
788           break;\r
789         }\r
790       }\r
791     }\r
792 \r
793     dSize = names.size();\r
794     Object[][] data = new Object[dSize][2];\r
795     for (int d = 0; d < dSize; d++)\r
796     {\r
797       data[d][0] = names.get(d);\r
798       data[d][1] = selected.get(d);\r
799     }\r
800 \r
801     refreshTableData(data);\r
802   }\r
803 \r
804   boolean selectedInList(Object[] selection, String[] items)\r
805   {\r
806     for (int i = 0; i < selection.length; i++)\r
807     {\r
808       if (selection[i].equals("Any"))\r
809       {\r
810         return true;\r
811       }\r
812 \r
813       for (int j = 0; j < items.length; j++)\r
814       {\r
815         if (selection[i].equals(items[j]))\r
816         {\r
817           return true;\r
818         }\r
819       }\r
820     }\r
821 \r
822     return false;\r
823   }\r
824 \r
825   void setSelectedFromProperties()\r
826   {\r
827     String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE",\r
828             "uniprot");\r
829     StringTokenizer st = new StringTokenizer(active, "\t");\r
830     selectedSources = new Vector();\r
831     while (st.hasMoreTokens())\r
832     {\r
833       selectedSources.addElement(st.nextToken());\r
834     }\r
835 \r
836     Vector _localSources = jalview.bin.Cache.getLocalDasSources();\r
837     if (_localSources != null)\r
838     {\r
839       if (localSources == null)\r
840       {\r
841         localSources = new Hashtable();\r
842       }\r
843       Enumeration sources = _localSources.elements();\r
844       while (sources.hasMoreElements())\r
845       {\r
846         Das1Source source = (Das1Source) sources.nextElement();\r
847         localSources.put(source.getNickname(), source);\r
848       }\r
849     }\r
850   }\r
851 \r
852   public void reset_actionPerformed(ActionEvent e)\r
853   {\r
854     registryURL.setText(DEFAULT_REGISTRY);\r
855   }\r
856 \r
857   /**\r
858    * set the DAS source settings in the given jalview properties.\r
859    * \r
860    * @param properties\r
861    */\r
862   public void saveProperties(Properties properties)\r
863   {\r
864     if (registryURL.getText() == null || registryURL.getText().length() < 1)\r
865     {\r
866       properties.remove(jalview.bin.Cache.DAS_REGISTRY_URL);\r
867     }\r
868     else\r
869     {\r
870       properties.setProperty(jalview.bin.Cache.DAS_REGISTRY_URL,\r
871               registryURL.getText());\r
872     }\r
873 \r
874     StringBuffer sb = new StringBuffer();\r
875     for (int r = 0; r < table.getModel().getRowCount(); r++)\r
876     {\r
877       if (((Boolean) table.getValueAt(r, 1)).booleanValue())\r
878       {\r
879         sb.append(table.getValueAt(r, 0) + "\t");\r
880       }\r
881     }\r
882 \r
883     properties.setProperty(jalview.bin.Cache.DAS_ACTIVE_SOURCE,\r
884             sb.toString());\r
885 \r
886     if (localSources != null)\r
887     {\r
888       sb = new StringBuffer();\r
889       Enumeration en = localSources.keys();\r
890       while (en.hasMoreElements())\r
891       {\r
892         String token = en.nextElement().toString();\r
893         sb.append(token\r
894                 + "|"\r
895                 + (((DasSource) localSources.get(token))\r
896                         .hasCapability("sequence") ? "sequence:" : "")\r
897                 + ((DasSource) localSources.get(token)).getUrl() + "\t");\r
898       }\r
899 \r
900       properties.setProperty(jalview.bin.Cache.DAS_LOCAL_SOURCE,\r
901               sb.toString());\r
902     }\r
903 \r
904   }\r
905 \r
906   class DASTableModel extends AbstractTableModel\r
907   {\r
908 \r
909     public DASTableModel(Object[][] data)\r
910     {\r
911       this.data = data;\r
912     }\r
913 \r
914     private String[] columnNames = new String[]\r
915     { "Nickname", "Use Source" };\r
916 \r
917     private Object[][] data;\r
918 \r
919     public int getColumnCount()\r
920     {\r
921       return columnNames.length;\r
922     }\r
923 \r
924     public int getRowCount()\r
925     {\r
926       return data.length;\r
927     }\r
928 \r
929     public String getColumnName(int col)\r
930     {\r
931       return columnNames[col];\r
932     }\r
933 \r
934     public Object getValueAt(int row, int col)\r
935     {\r
936       return data[row][col];\r
937     }\r
938 \r
939     /*\r
940      * JTable uses this method to determine the default renderer/ editor for\r
941      * each cell. If we didn't implement this method, then the last column would\r
942      * contain text ("true"/"false"), rather than a check box.\r
943      */\r
944     public Class getColumnClass(int c)\r
945     {\r
946       return getValueAt(0, c).getClass();\r
947     }\r
948 \r
949     /*\r
950      * Don't need to implement this method unless your table's editable.\r
951      */\r
952     public boolean isCellEditable(int row, int col)\r
953     {\r
954       // Note that the data/cell address is constant,\r
955       // no matter where the cell appears onscreen.\r
956       return col == 1;\r
957 \r
958     }\r
959 \r
960     /*\r
961      * Don't need to implement this method unless your table's data can change.\r
962      */\r
963     public void setValueAt(Object value, int row, int col)\r
964     {\r
965       data[row][col] = value;\r
966       fireTableCellUpdated(row, col);\r
967 \r
968       String name = getValueAt(row, 0).toString();\r
969       boolean selected = ((Boolean) value).booleanValue();\r
970 \r
971       if (selectedSources.contains(name) && !selected)\r
972       {\r
973         selectedSources.remove(name);\r
974       }\r
975 \r
976       if (!selectedSources.contains(name) && selected)\r
977       {\r
978         selectedSources.add(name);\r
979       }\r
980     }\r
981   }\r
982 \r
983   public void initDasSources()\r
984   {\r
985 \r
986     Thread thr = new Thread(new Runnable()\r
987     {\r
988       public void run()\r
989       {\r
990         // this actually initialises the das source list\r
991         paintComponent(null); // yuk\r
992       }\r
993     });\r
994     thr.start();\r
995     while (loadingDasSources || dasSources == null)\r
996     {\r
997       try\r
998       {\r
999         Thread.sleep(10);\r
1000       } catch (Exception e)\r
1001       {\r
1002       }\r
1003       ;\r
1004     }\r
1005   }\r
1006 \r
1007   public Vector resolveSourceNicknames(Vector sources)\r
1008   {\r
1009 \r
1010     Vector resolved = new Vector();\r
1011     if (sources != null)\r
1012     {\r
1013       for (int i = 0; i < dasSources.length; i++)\r
1014       {\r
1015         if (sources.contains(dasSources[i].getNickname()))\r
1016         {\r
1017           if (!resolved.contains(dasSources[i]))\r
1018           {\r
1019             resolved.addElement(dasSources[i]);\r
1020           }\r
1021         }\r
1022       }\r
1023     }\r
1024     return resolved;\r
1025   }\r
1026 \r
1027   /**\r
1028    * disable or enable the buttons on the source browser\r
1029    * \r
1030    * @param b\r
1031    */\r
1032   public void setGuiEnabled(boolean b)\r
1033   {\r
1034     refresh.setEnabled(b);\r
1035     addLocal.setEnabled(b);\r
1036   }\r
1037 }\r