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