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