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