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