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