876d1570b994eb31611002d50d625148ef1c50a7
[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       if (validate == JOptionPane.OK_OPTION)
488       {
489         if (jalview.ws.jws2.Jws2Discoverer.testServiceUrl(foo))
490         {
491           return foo.toString();
492         }
493         else
494         {
495           JOptionPane
496                   .showInternalMessageDialog(
497                           Desktop.desktop,
498                           MessageManager.getString("warn.server_didnt_pass_validation"));
499         }
500       }
501       else
502       {
503         // just return the URL anyway
504         return foo.toString();
505       }
506     }
507     return initUrl;
508   }
509
510   /*
511    * (non-Javadoc)
512    * 
513    * @see jalview.jbgui.GWsPreferences#newWsUrl_actionPerformed(java.awt.event.
514    * ActionEvent)
515    */
516   @Override
517   protected void newWsUrl_actionPerformed(ActionEvent e)
518   {
519     String url = editUrl(null, MessageManager.getString("label.add_jabaws_url"));
520     if (url != null)
521     {
522       if (!wsUrls.contains(url))
523       {
524         int selind = wsList.getSelectedRow();
525         if (selind > -1)
526         {
527           wsUrls.insertElementAt(url, selind);
528         }
529         else
530         {
531           wsUrls.addElement(url);
532         }
533         update++;
534         updateList();
535       }
536     }
537   }
538
539   /*
540    * (non-Javadoc)
541    * 
542    * @see jalview.jbgui.GWsPreferences#refreshWs_actionPerformed(java.awt.event.
543    * ActionEvent)
544    */
545   @Override
546   protected void refreshWs_actionPerformed(ActionEvent e)
547   {
548     new Thread(new Runnable()
549     {
550
551       public void run()
552       {
553         // force a refresh.
554         lastrefresh = update - 1;
555         updateWsMenuConfig(false);
556         refreshWsMenu(true);
557       }
558     }).start();
559
560   }
561
562   /**
563    * Refresh the web services menus - but only if there has been a change in the
564    * configuration (indicated by update!=lastrefresh)
565    * 
566    * @param showProgress
567    *          show progress in dialog or on desktop
568    */
569   protected void refreshWsMenu(boolean showProgress)
570   {
571     if (showProgress)
572     {
573       new Thread(new Runnable()
574       {
575
576         public void run()
577         {
578           progressBar.setVisible(true);
579           validate();
580           progressBar.setIndeterminate(true);
581           if (lastrefresh != update)
582           {
583             lastrefresh = update;
584             Desktop.instance.startServiceDiscovery(true); // wait around for all
585                                                           // threads to complete
586             updateList();
587
588           }
589           progressBar.setIndeterminate(false);
590           progressBar.setVisible(false);
591           validate();
592         }
593       }).start();
594
595     }
596     else
597     {
598       new Thread(new Runnable()
599       {
600
601         public void run()
602         {
603           long ct = System.currentTimeMillis();
604           Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_web_service_menus"),
605                   ct);
606           if (lastrefresh != update)
607           {
608             lastrefresh = update;
609             Desktop.instance.startServiceDiscovery(true);
610             updateList();
611           }
612           Desktop.instance.setProgressBar(null, ct);
613         }
614
615       }).start();
616     }
617   }
618
619   /**
620    * state counters for ensuring that updates only happen if config has changed.
621    */
622   private long update = 0, lastrefresh = 0;
623
624   /*
625    * (non-Javadoc)
626    * 
627    * @see
628    * jalview.jbgui.GWsPreferences#resetWs_actionPerformed(java.awt.event.ActionEvent
629    * )
630    */
631   @Override
632   protected void resetWs_actionPerformed(ActionEvent e)
633   {
634     jalview.ws.jws2.Jws2Discoverer.setServiceUrls(null);
635     Vector nwsUrls = jalview.ws.jws2.Jws2Discoverer.getServiceUrls();
636     if (!wsUrls.equals(nwsUrls))
637     {
638       update++;
639     }
640     wsUrls = nwsUrls;
641     updateList();
642
643     updateAndRefreshWsMenuConfig(true);
644   }
645
646   protected void ok_ActionPerformed(ActionEvent e)
647   {
648     // update everything regardless.
649     updateAndRefreshWsMenuConfig(false);
650   }
651
652   public void updateAndRefreshWsMenuConfig(
653           final boolean showProgressInDialog)
654   {
655     new Thread(new Runnable()
656     {
657
658       public void run()
659       {
660         updateWsMenuConfig(false);
661         refreshWsMenu(showProgressInDialog);
662       }
663     }).start();
664
665   }
666 }