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