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