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