39117d06994e9fc8cb808063976f6a31a062ce66
[jalview.git] / src / jalview / gui / WsPreferences.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import jalview.bin.Cache;
24 import jalview.jbgui.GWsPreferences;
25 import jalview.util.MessageManager;
26 import jalview.ws.jws2.Jws2Discoverer;
27 import jalview.ws.rest.RestClient;
28 import jalview.ws.rest.RestServiceDescription;
29
30 import java.awt.BorderLayout;
31 import java.awt.Color;
32 import java.awt.Component;
33 import java.awt.Dimension;
34 import java.awt.event.ActionEvent;
35 import java.awt.event.ActionListener;
36 import java.net.URL;
37 import java.util.List;
38 import java.util.Vector;
39
40 import javax.swing.JLabel;
41 import javax.swing.JOptionPane;
42 import javax.swing.JPanel;
43 import javax.swing.JTable;
44 import javax.swing.JTextField;
45 import javax.swing.table.AbstractTableModel;
46 import javax.swing.table.TableCellRenderer;
47
48 public class WsPreferences extends GWsPreferences
49 {
50
51   public WsPreferences()
52   {
53     super();
54     initFromPreferences();
55   }
56
57   List<String> wsUrls;
58
59   Vector<String> oldUrls, rsbsUrls, oldRsbsUrls;
60
61   private boolean needWsMenuUpdate;
62
63   private boolean oldJws1, oldJws2, oldIndexByHost, oldIndexByType,
64           oldEnfin, oldWsWarning;
65
66   private void initFromPreferences()
67   {
68
69     wsUrls = Jws2Discoverer.getDiscoverer().getServiceUrls();
70     if (!wsUrls.isEmpty())
71     {
72       oldUrls = new Vector<String>(wsUrls);
73     }
74     else
75     {
76       oldUrls = null;
77       wsUrls = new Vector<String>();
78     }
79     wsList.setDefaultRenderer(Integer.class, new JabaWSStatusRenderer());
80     wsList.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
81     updateList();
82     rsbsUrls = RestClient.getRsbsDescriptions();
83     if (rsbsUrls != null)
84     {
85       oldRsbsUrls = new Vector<String>(rsbsUrls);
86     }
87     else
88     {
89       oldRsbsUrls = null;
90       rsbsUrls = new Vector<String>();
91     }
92     updateRsbsList();
93     enableEnfinServices.setSelected(oldEnfin = Cache.getDefault(
94             "SHOW_ENFIN_SERVICES", true));
95     enableEnfinServices.addActionListener(updateAction);
96     enableJws2Services.setSelected(oldJws2 = Cache.getDefault(
97             "SHOW_JWS2_SERVICES", true));
98     enableJws2Services.addActionListener(updateAction);
99     indexByHost.setSelected(oldIndexByHost = Cache.getDefault(
100             "WSMENU_BYHOST", false));
101     indexByHost.addActionListener(updateAction);
102     indexByType.setSelected(oldIndexByType = Cache.getDefault(
103             "WSMENU_BYTYPE", false));
104     indexByType.addActionListener(updateAction);
105     displayWsWarning.setSelected(oldWsWarning = Cache.getDefault(
106             "SHOW_WSDISCOVERY_ERRORS", true));
107   }
108
109   ActionListener updateAction = new ActionListener()
110   {
111
112     @Override
113     public void actionPerformed(ActionEvent e)
114     {
115       update++;
116     }
117
118   };
119
120   private void updateList()
121   {
122     Object tdat[][] = new Object[wsUrls.size()][2];
123     int r = 0;
124     for (String url : wsUrls)
125     {
126       int status = Jws2Discoverer.getDiscoverer().getServerStatusFor(url);
127       tdat[r][1] = new Integer(status);
128       tdat[r++][0] = url;
129     }
130
131     wsList.setModel(new WsUrlTableModel(tdat));
132     wsList.getColumn(MessageManager.getString("label.status")).setMinWidth(10);
133   }
134
135   private class JabaWSStatusRenderer extends JPanel implements
136           TableCellRenderer
137   {
138     public JabaWSStatusRenderer()
139     {
140       setOpaque(true);
141       setMinimumSize(new Dimension(10, 10));
142       // setText(" ");
143
144     }
145
146     /**
147      * render an Integer reflecting service status as a colour and symbol
148      */
149
150     @Override
151     public Component getTableCellRendererComponent(JTable arg0,
152             Object status, boolean isSelected, boolean hasFocus, int row,
153             int column)
154     {
155       Color c;
156       String t = new String("");
157       switch (((Integer) status).intValue())
158       {
159       case 1:
160         // cb.setSelected(true);
161         // cb.setBackground(
162         c = Color.green;
163         break;
164       case 0:
165         // cb.setSelected(true);
166         // cb.setBackground(
167         c = Color.lightGray;
168         break;
169       case -1:
170         // cb.setSelected(false);
171         // cb.setBackground(
172         c = Color.red;
173         break;
174       default:
175         // cb.setSelected(false);
176         // cb.setBackground(
177         c = Color.orange;
178       }
179       setBackground(c);
180       // setText(t);
181       return this;
182
183     }
184
185   }
186
187   private class WsUrlTableModel extends AbstractTableModel
188   {
189
190     private Object[][] data;
191     private String[] columnNames = new String[]
192     { MessageManager.getString("label.service_url"), MessageManager.getString("label.status") };
193
194     public WsUrlTableModel(Object[][] tdat)
195     {
196       this.data = tdat;
197     }
198
199     @Override
200     public int getColumnCount()
201     {
202       return 2;
203     }
204
205     @Override
206     public String getColumnName(int column)
207     {
208         return columnNames[column];
209     }
210
211     @Override
212     public int getRowCount()
213     {
214       if (data == null)
215       {
216         return 0;
217       }
218       return data.length;
219     }
220
221     @Override
222     public java.lang.Class<?> getColumnClass(int columnIndex)
223     {
224       return getValueAt(0, columnIndex).getClass();
225     };
226
227     @Override
228     public Object getValueAt(int rowIndex, int columnIndex)
229     {
230       return data[rowIndex][columnIndex];
231     }
232
233   }
234
235   private void updateRsbsList()
236   {
237     sbrsList.setListData(rsbsUrls);
238   }
239
240   private void updateServiceList()
241   {
242     Jws2Discoverer.getDiscoverer().setServiceUrls(wsUrls);
243   }
244
245   private void updateRsbsServiceList()
246   {
247     RestClient.setRsbsServices(rsbsUrls);
248   }
249
250   /*
251    * (non-Javadoc)
252    * 
253    * @see
254    * jalview.jbgui.GWsPreferences#deleteWsUrl_actionPerformed(java.awt.event
255    * .ActionEvent)
256    */
257   @Override
258   protected void deleteWsUrl_actionPerformed(ActionEvent e)
259   {
260     int sel = wsList.getSelectedRow();
261     if (sel > -1)
262     {
263       wsUrls.remove(sel);
264       update++;
265       updateList();
266     }
267   }
268
269   /*
270    * (non-Javadoc)
271    * 
272    * @see jalview.jbgui.GWsPreferences#editWsUrl_actionPerformed(java.awt.event.
273    * ActionEvent)
274    */
275   @Override
276   protected void editWsUrl_actionPerformed(ActionEvent e)
277   {
278     int sel = wsList.getSelectedRow();
279     if (sel > -1)
280     {
281       String url = editUrl(wsUrls.get(sel),
282               MessageManager.getString("label.edit_jabaws_url"));
283       if (url != null)
284       {
285         int present = wsUrls.indexOf(url);
286         if (present == -1)
287         {
288           update++;
289           wsUrls.set(sel, url);
290           updateList();
291         }
292         else
293         {
294           if (present != sel)
295           {
296             wsUrls.remove(sel);
297             updateList();
298           }
299         }
300       }
301     }
302   }
303
304   @Override
305   protected void newSbrsUrl_actionPerformed(ActionEvent e)
306   {
307     RestServiceEditorPane rse = new RestServiceEditorPane();
308     rse.showDialog(MessageManager.getString("label.add_new_sbrs_service"));
309     String rservice = rse.getEditedRestService();
310     if (rservice != null && !rsbsUrls.contains(rservice))
311     {
312       rsbsUrls.add(rservice);
313       update++;
314       updateRsbsList();
315     }
316   }
317
318   @Override
319   protected void editSbrsUrl_actionPerformed(ActionEvent e)
320   {
321     int sel = sbrsList.getSelectedIndex();
322     if (sel > -1)
323     {
324       RestServiceEditorPane rse = new RestServiceEditorPane(
325               new RestServiceDescription(rsbsUrls.elementAt(sel)));
326       rse.showDialog(MessageManager.getString("label.edit_sbrs_entry"));
327       String rservice = rse.getEditedRestService();
328       if (rservice != null)
329       {
330         int present = rsbsUrls.indexOf(rservice);
331         if (present == -1)
332         {
333           update++;
334           rsbsUrls.setElementAt(rservice, sel);
335           updateRsbsList();
336         }
337         else
338         {
339           if (present != sel)
340           {
341             rsbsUrls.removeElementAt(sel);
342             update++;
343             updateRsbsList();
344           }
345         }
346       }
347     }
348   }
349
350   void updateWsMenuConfig(boolean old)
351   {
352     if (old)
353     {
354       if (oldUrls != wsUrls
355               || (wsUrls != null && oldUrls != null && !wsUrls
356                       .equals(oldUrls)))
357       {
358         update++;
359       }
360       wsUrls = (oldUrls == null) ? null : new Vector(oldUrls);
361       if (oldRsbsUrls != rsbsUrls
362               || (rsbsUrls != null && oldRsbsUrls != null && !oldRsbsUrls
363                       .equals(rsbsUrls)))
364       {
365         update++;
366       }
367       oldRsbsUrls = (oldRsbsUrls == null) ? null : new Vector(oldRsbsUrls);
368     }
369     else
370     {
371
372     }
373     Cache.setProperty(
374             "SHOW_ENFIN_SERVICES",
375             Boolean.valueOf(
376                     old ? oldEnfin : enableEnfinServices.isSelected())
377                     .toString());
378     Cache.setProperty(
379             "SHOW_JWS2_SERVICES",
380             Boolean.valueOf(old ? oldJws2 : enableJws2Services.isSelected())
381                     .toString());
382     Cache.setProperty(
383             "WSMENU_BYHOST",
384             Boolean.valueOf(old ? oldIndexByHost : indexByHost.isSelected())
385                     .toString());
386     Cache.setProperty(
387             "WSMENU_BYTYPE",
388             Boolean.valueOf(old ? oldIndexByType : indexByType.isSelected())
389                     .toString());
390
391     Cache.setProperty(
392             "SHOW_WSDISCOVERY_ERRORS",
393             Boolean.valueOf(
394                     old ? oldWsWarning : displayWsWarning.isSelected())
395                     .toString());
396     updateServiceList();
397     updateRsbsServiceList();
398   }
399
400   /*
401    * (non-Javadoc)
402    * 
403    * @see
404    * jalview.jbgui.GWsPreferences#moveWsUrlDown_actionPerformed(java.awt.event
405    * .ActionEvent)
406    */
407   @Override
408   protected void moveWsUrlDown_actionPerformed(ActionEvent e)
409   {
410     int p = wsList.getSelectedRow();
411     if (p > -1 && p < wsUrls.size() - 1)
412     {
413       String t = wsUrls.get(p + 1);
414       wsUrls.set(p + 1, wsUrls.get(p));
415       wsUrls.set(p, t);
416       updateList();
417       wsList.getSelectionModel().setSelectionInterval(p + 1, p + 1);
418       update++;
419     }
420   }
421
422   /*
423    * (non-Javadoc)
424    * 
425    * @see
426    * jalview.jbgui.GWsPreferences#moveWsUrlUp_actionPerformed(java.awt.event
427    * .ActionEvent)
428    */
429   @Override
430   protected void moveWsUrlUp_actionPerformed(ActionEvent e)
431   {
432     int p = wsList.getSelectedRow();
433     if (p > 0)
434     {
435       String t = wsUrls.get(p - 1);
436       wsUrls.set(p - 1, wsUrls.get(p));
437       wsUrls.set(p, t);
438       updateList();
439       wsList.getSelectionModel().setSelectionInterval(p - 1, p - 1);
440       update++;
441     }
442   }
443
444   private String editUrl(String initUrl, String title)
445   {
446     String url = initUrl;
447     URL foo = null;
448     if (url == null)
449     {
450       url = "";
451     }
452     JTextField urltf = new JTextField(url, 40);
453     JPanel panel = new JPanel(new BorderLayout());
454     JPanel pane12 = new JPanel(new BorderLayout());
455     pane12.add(new JLabel(MessageManager.getString("label.url")),
456             BorderLayout.CENTER);
457     pane12.add(urltf, BorderLayout.EAST);
458     panel.add(pane12, BorderLayout.NORTH);
459     boolean valid = false;
460     int resp = JOptionPane.CANCEL_OPTION;
461     while (!valid
462             && (resp = JOptionPane.showInternalConfirmDialog(
463                     Desktop.desktop, panel, title,
464                     JOptionPane.OK_CANCEL_OPTION)) == JOptionPane.OK_OPTION)
465     {
466       try
467       {
468         // TODO: do a better job of checking that the url is a valid discovery
469         // URL for web services.
470         String tx = urltf.getText().trim();
471         while (tx.length() > 0 && tx.lastIndexOf('/') == tx.length() - 1)
472         {
473           tx = tx.substring(0, tx.length() - 1);
474         }
475         foo = new URL(tx);
476         valid = true;
477         urltf.setText(tx);
478       } catch (Exception e)
479       {
480         valid = false;
481         JOptionPane.showInternalMessageDialog(Desktop.desktop,
482                 MessageManager.getString("label.invalid_url"));
483       }
484     }
485     if (valid && resp == JOptionPane.OK_OPTION)
486     {
487       int validate = JOptionPane
488               .showInternalConfirmDialog(
489                       Desktop.desktop,
490                       MessageManager.getString("info.validate_jabaws_server"),
491                       MessageManager.getString("label.test_server"), JOptionPane.YES_NO_OPTION);
492
493       if (validate == JOptionPane.OK_OPTION)
494       {
495         if (Jws2Discoverer.testServiceUrl(foo))
496         {
497           return foo.toString();
498         }
499         else
500         {
501           int opt = JOptionPane
502                   .showInternalOptionDialog(
503                           Desktop.desktop,
504                           "The Server  '"
505                                   + foo.toString()
506                                   + "' failed validation,\ndo you want to add it anyway? ",
507                           "Server Validation Failed",
508                           JOptionPane.YES_NO_OPTION,
509                           JOptionPane.INFORMATION_MESSAGE, null, null, null);
510           if (opt == JOptionPane.YES_OPTION)
511           {
512             return foo.toString();
513           }
514           else
515           {
516             JOptionPane
517                     .showInternalMessageDialog(
518                             Desktop.desktop,
519                             MessageManager
520                                     .getString("warn.server_didnt_pass_validation"));
521           }
522
523
524         }
525       }
526       else
527       {
528         // just return the URL anyway
529         return foo.toString();
530       }
531     }
532     return initUrl;
533   }
534
535   /*
536    * (non-Javadoc)
537    * 
538    * @see jalview.jbgui.GWsPreferences#newWsUrl_actionPerformed(java.awt.event.
539    * ActionEvent)
540    */
541   @Override
542   protected void newWsUrl_actionPerformed(ActionEvent e)
543   {
544     String url = editUrl(null, MessageManager.getString("label.add_jabaws_url"));
545     if (url != null)
546     {
547       if (!wsUrls.contains(url))
548       {
549         int selind = wsList.getSelectedRow();
550         if (selind > -1)
551         {
552           wsUrls.add(selind, url);
553         }
554         else
555         {
556           wsUrls.add(url);
557         }
558         update++;
559         updateList();
560       }
561     }
562   }
563
564   /*
565    * (non-Javadoc)
566    * 
567    * @see jalview.jbgui.GWsPreferences#refreshWs_actionPerformed(java.awt.event.
568    * ActionEvent)
569    */
570   @Override
571   protected void refreshWs_actionPerformed(ActionEvent e)
572   {
573     new Thread(new Runnable()
574     {
575
576       public void run()
577       {
578         // force a refresh.
579         lastrefresh = update - 1;
580         updateWsMenuConfig(false);
581         refreshWsMenu(true);
582       }
583     }).start();
584
585   }
586
587   /**
588    * Refresh the web services menus - but only if there has been a change in the
589    * configuration (indicated by update!=lastrefresh)
590    * 
591    * @param showProgress
592    *          show progress in dialog or on desktop
593    */
594   protected void refreshWsMenu(boolean showProgress)
595   {
596     if (showProgress)
597     {
598       new Thread(new Runnable()
599       {
600
601         public void run()
602         {
603           progressBar.setVisible(true);
604           validate();
605           progressBar.setIndeterminate(true);
606           if (lastrefresh != update)
607           {
608             lastrefresh = update;
609             Desktop.instance.startServiceDiscovery(true); // wait around for all
610                                                           // threads to complete
611             updateList();
612
613           }
614           progressBar.setIndeterminate(false);
615           progressBar.setVisible(false);
616           validate();
617         }
618       }).start();
619
620     }
621     else
622     {
623       new Thread(new Runnable()
624       {
625
626         public void run()
627         {
628           long ct = System.currentTimeMillis();
629           Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_web_service_menus"),
630                   ct);
631           if (lastrefresh != update)
632           {
633             lastrefresh = update;
634             Desktop.instance.startServiceDiscovery(true);
635             updateList();
636           }
637           Desktop.instance.setProgressBar(null, ct);
638         }
639
640       }).start();
641     }
642   }
643
644   /**
645    * state counters for ensuring that updates only happen if config has changed.
646    */
647   private long update = 0, lastrefresh = 0;
648
649   /*
650    * (non-Javadoc)
651    * 
652    * @see
653    * jalview.jbgui.GWsPreferences#resetWs_actionPerformed(java.awt.event.ActionEvent
654    * )
655    */
656   @Override
657   protected void resetWs_actionPerformed(ActionEvent e)
658   {
659     Jws2Discoverer.getDiscoverer().setServiceUrls(null);
660     List<String> nwsUrls = Jws2Discoverer.getDiscoverer().getServiceUrls();
661     if (!wsUrls.equals(nwsUrls))
662     {
663       update++;
664     }
665     wsUrls = nwsUrls;
666     updateList();
667
668     updateAndRefreshWsMenuConfig(true);
669   }
670
671   protected void ok_ActionPerformed(ActionEvent e)
672   {
673     // update everything regardless.
674     updateAndRefreshWsMenuConfig(false);
675   }
676
677   public void updateAndRefreshWsMenuConfig(
678           final boolean showProgressInDialog)
679   {
680     new Thread(new Runnable()
681     {
682
683       public void run()
684       {
685         updateWsMenuConfig(false);
686         refreshWsMenu(showProgressInDialog);
687       }
688     }).start();
689
690   }
691 }