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