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