JAL-1517 fix copyright for 2.8.2
[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("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
188     public WsUrlTableModel(Object[][] tdat)
189     {
190       this.data = tdat;
191     }
192
193     @Override
194     public int getColumnCount()
195     {
196       return 2;
197     }
198
199     @Override
200     public String getColumnName(int column)
201     {
202       if (column == 1)
203       {
204         return "Status";
205       }
206       return "Service URL";
207     }
208
209     @Override
210     public int getRowCount()
211     {
212       if (data == null)
213       {
214         return 0;
215       }
216       return data.length;
217     }
218
219     @Override
220     public java.lang.Class<?> getColumnClass(int columnIndex)
221     {
222       return getValueAt(0, columnIndex).getClass();
223     };
224
225     @Override
226     public Object getValueAt(int rowIndex, int columnIndex)
227     {
228       return data[rowIndex][columnIndex];
229     }
230
231   }
232
233   private void updateRsbsList()
234   {
235     sbrsList.setListData(rsbsUrls);
236   }
237
238   private void updateServiceList()
239   {
240     jalview.ws.jws2.Jws2Discoverer.setServiceUrls(wsUrls);
241   }
242
243   private void updateRsbsServiceList()
244   {
245     jalview.ws.rest.RestClient.setRsbsServices(rsbsUrls);
246   }
247
248   /*
249    * (non-Javadoc)
250    * 
251    * @see
252    * jalview.jbgui.GWsPreferences#deleteWsUrl_actionPerformed(java.awt.event
253    * .ActionEvent)
254    */
255   @Override
256   protected void deleteWsUrl_actionPerformed(ActionEvent e)
257   {
258     int sel = wsList.getSelectedRow();
259     if (sel > -1)
260     {
261       wsUrls.removeElementAt(sel);
262       update++;
263       updateList();
264     }
265   }
266
267   /*
268    * (non-Javadoc)
269    * 
270    * @see jalview.jbgui.GWsPreferences#editWsUrl_actionPerformed(java.awt.event.
271    * ActionEvent)
272    */
273   @Override
274   protected void editWsUrl_actionPerformed(ActionEvent e)
275   {
276     int sel = wsList.getSelectedRow();
277     if (sel > -1)
278     {
279       String url = editUrl(wsUrls.elementAt(sel), "Edit JABAWS URL");
280       if (url != null)
281       {
282         int present = wsUrls.indexOf(url);
283         if (present == -1)
284         {
285           update++;
286           wsUrls.setElementAt(url, sel);
287           updateList();
288         }
289         else
290         {
291           if (present != sel)
292           {
293             wsUrls.removeElementAt(sel);
294             updateList();
295           }
296         }
297       }
298     }
299   }
300
301   @Override
302   protected void newSbrsUrl_actionPerformed(ActionEvent e)
303   {
304     RestServiceEditorPane rse = new RestServiceEditorPane();
305     rse.showDialog("Add a new Simple Bioinformatics Rest Service");
306     String rservice = rse.getEditedRestService();
307     if (rservice != null && !rsbsUrls.contains(rservice))
308     {
309       rsbsUrls.add(rservice);
310       update++;
311       updateRsbsList();
312     }
313   }
314
315   @Override
316   protected void editSbrsUrl_actionPerformed(ActionEvent e)
317   {
318     int sel = sbrsList.getSelectedIndex();
319     if (sel > -1)
320     {
321       RestServiceEditorPane rse = new RestServiceEditorPane(
322               new RestServiceDescription(rsbsUrls.elementAt(sel)));
323       rse.showDialog("Edit Simple Bioinformatics Rest Service entry");
324       String rservice = rse.getEditedRestService();
325       if (rservice != null)
326       {
327         int present = rsbsUrls.indexOf(rservice);
328         if (present == -1)
329         {
330           update++;
331           rsbsUrls.setElementAt(rservice, sel);
332           updateRsbsList();
333         }
334         else
335         {
336           if (present != sel)
337           {
338             rsbsUrls.removeElementAt(sel);
339             update++;
340             updateRsbsList();
341           }
342         }
343       }
344     }
345   }
346
347   void updateWsMenuConfig(boolean old)
348   {
349     if (old)
350     {
351       if (oldUrls != wsUrls
352               || (wsUrls != null && oldUrls != null && !wsUrls
353                       .equals(oldUrls)))
354       {
355         update++;
356       }
357       wsUrls = (oldUrls == null) ? null : new Vector(oldUrls);
358       if (oldRsbsUrls != rsbsUrls
359               || (rsbsUrls != null && oldRsbsUrls != null && !oldRsbsUrls
360                       .equals(rsbsUrls)))
361       {
362         update++;
363       }
364       oldRsbsUrls = (oldRsbsUrls == null) ? null : new Vector(oldRsbsUrls);
365     }
366     else
367     {
368
369     }
370     Cache.setProperty(
371             "SHOW_ENFIN_SERVICES",
372             Boolean.valueOf(
373                     old ? oldEnfin : enableEnfinServices.isSelected())
374                     .toString());
375     Cache.setProperty(
376             "SHOW_JWS2_SERVICES",
377             Boolean.valueOf(old ? oldJws2 : enableJws2Services.isSelected())
378                     .toString());
379     Cache.setProperty(
380             "WSMENU_BYHOST",
381             Boolean.valueOf(old ? oldIndexByHost : indexByHost.isSelected())
382                     .toString());
383     Cache.setProperty(
384             "WSMENU_BYTYPE",
385             Boolean.valueOf(old ? oldIndexByType : indexByType.isSelected())
386                     .toString());
387
388     Cache.setProperty(
389             "SHOW_WSDISCOVERY_ERRORS",
390             Boolean.valueOf(
391                     old ? oldWsWarning : displayWsWarning.isSelected())
392                     .toString());
393     updateServiceList();
394     updateRsbsServiceList();
395   }
396
397   /*
398    * (non-Javadoc)
399    * 
400    * @see
401    * jalview.jbgui.GWsPreferences#moveWsUrlDown_actionPerformed(java.awt.event
402    * .ActionEvent)
403    */
404   @Override
405   protected void moveWsUrlDown_actionPerformed(ActionEvent e)
406   {
407     int p = wsList.getSelectedRow();
408     if (p > -1 && p < wsUrls.size() - 1)
409     {
410       String t = wsUrls.get(p + 1);
411       wsUrls.setElementAt(wsUrls.elementAt(p), p + 1);
412       wsUrls.setElementAt(t, p);
413       updateList();
414       wsList.getSelectionModel().setSelectionInterval(p + 1, p + 1);
415       update++;
416     }
417   }
418
419   /*
420    * (non-Javadoc)
421    * 
422    * @see
423    * jalview.jbgui.GWsPreferences#moveWsUrlUp_actionPerformed(java.awt.event
424    * .ActionEvent)
425    */
426   @Override
427   protected void moveWsUrlUp_actionPerformed(ActionEvent e)
428   {
429     int p = wsList.getSelectedRow();
430     if (p > 0)
431     {
432       String t = wsUrls.get(p - 1);
433       wsUrls.setElementAt(wsUrls.elementAt(p), p - 1);
434       wsUrls.setElementAt(t, p);
435       updateList();
436       wsList.getSelectionModel().setSelectionInterval(p - 1, p - 1);
437       update++;
438     }
439   }
440
441   private String editUrl(String initUrl, String title)
442   {
443     String url = initUrl;
444     URL foo = null;
445     if (url == null)
446     {
447       url = "";
448     }
449     JTextField urltf = new JTextField(url, 40);
450     JPanel panel = new JPanel(new BorderLayout());
451     JPanel pane12 = new JPanel(new BorderLayout());
452     pane12.add(new JLabel(MessageManager.getString("label.url")), BorderLayout.CENTER);
453     pane12.add(urltf, BorderLayout.EAST);
454     panel.add(pane12, BorderLayout.NORTH);
455     boolean valid = false;
456     int resp = JOptionPane.CANCEL_OPTION;
457     while (!valid
458             && (resp = JOptionPane.showInternalConfirmDialog(
459                     Desktop.desktop, panel, title,
460                     JOptionPane.OK_CANCEL_OPTION)) == JOptionPane.OK_OPTION)
461     {
462       try
463       {
464         // TODO: do a better job of checking that the url is a valid discovery
465         // URL for web services.
466         String tx = urltf.getText().trim();
467         while (tx.length() > 0 && tx.lastIndexOf('/') == tx.length() - 1)
468         {
469           tx = tx.substring(0, tx.length() - 1);
470         }
471         foo = new URL(tx);
472         valid = true;
473         urltf.setText(tx);
474       } catch (Exception e)
475       {
476         valid = false;
477         JOptionPane.showInternalMessageDialog(Desktop.desktop,
478                 MessageManager.getString("label.invalid_url"));
479       }
480     }
481     if (valid && resp == JOptionPane.OK_OPTION)
482     {
483       int validate = JOptionPane
484               .showInternalConfirmDialog(
485                       Desktop.desktop,
486                       "Validate JabaWS Server ?\n(Look in console output for results)",
487                       "Test Server?", JOptionPane.YES_NO_OPTION);
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           JOptionPane
497                   .showInternalMessageDialog(
498                           Desktop.desktop,
499                           "Service did not pass validation.\nCheck the Jalview Console for more details.");
500         }
501       }
502       else
503       {
504         // just return the URL anyway
505         return foo.toString();
506       }
507     }
508     return initUrl;
509   }
510
511   /*
512    * (non-Javadoc)
513    * 
514    * @see jalview.jbgui.GWsPreferences#newWsUrl_actionPerformed(java.awt.event.
515    * ActionEvent)
516    */
517   @Override
518   protected void newWsUrl_actionPerformed(ActionEvent e)
519   {
520     String url = editUrl(null, "Add new JABAWS URL");
521     if (url != null)
522     {
523       if (!wsUrls.contains(url))
524       {
525         int selind = wsList.getSelectedRow();
526         if (selind > -1)
527         {
528           wsUrls.insertElementAt(url, selind);
529         }
530         else
531         {
532           wsUrls.addElement(url);
533         }
534         update++;
535         updateList();
536       }
537     }
538   }
539
540   /*
541    * (non-Javadoc)
542    * 
543    * @see jalview.jbgui.GWsPreferences#refreshWs_actionPerformed(java.awt.event.
544    * ActionEvent)
545    */
546   @Override
547   protected void refreshWs_actionPerformed(ActionEvent e)
548   {
549     new Thread(new Runnable()
550     {
551
552       public void run()
553       {
554         // force a refresh.
555         lastrefresh = update - 1;
556         updateWsMenuConfig(false);
557         refreshWsMenu(true);
558       }
559     }).start();
560
561   }
562
563   /**
564    * Refresh the web services menus - but only if there has been a change in the
565    * configuration (indicated by update!=lastrefresh)
566    * 
567    * @param showProgress
568    *          show progress in dialog or on desktop
569    */
570   protected void refreshWsMenu(boolean showProgress)
571   {
572     if (showProgress)
573     {
574       new Thread(new Runnable()
575       {
576
577         public void run()
578         {
579           progressBar.setVisible(true);
580           validate();
581           progressBar.setIndeterminate(true);
582           if (lastrefresh != update)
583           {
584             lastrefresh = update;
585             Desktop.instance.startServiceDiscovery(true); // wait around for all
586                                                           // threads to complete
587             updateList();
588
589           }
590           progressBar.setIndeterminate(false);
591           progressBar.setVisible(false);
592           validate();
593         }
594       }).start();
595
596     }
597     else
598     {
599       new Thread(new Runnable()
600       {
601
602         public void run()
603         {
604           long ct = System.currentTimeMillis();
605           Desktop.instance.setProgressBar("Refreshing Web Service Menus",
606                   ct);
607           if (lastrefresh != update)
608           {
609             lastrefresh = update;
610             Desktop.instance.startServiceDiscovery(true);
611             updateList();
612           }
613           Desktop.instance.setProgressBar(null, ct);
614         }
615
616       }).start();
617     }
618   }
619
620   /**
621    * state counters for ensuring that updates only happen if config has changed.
622    */
623   private long update = 0, lastrefresh = 0;
624
625   /*
626    * (non-Javadoc)
627    * 
628    * @see
629    * jalview.jbgui.GWsPreferences#resetWs_actionPerformed(java.awt.event.ActionEvent
630    * )
631    */
632   @Override
633   protected void resetWs_actionPerformed(ActionEvent e)
634   {
635     jalview.ws.jws2.Jws2Discoverer.setServiceUrls(null);
636     Vector nwsUrls = jalview.ws.jws2.Jws2Discoverer.getServiceUrls();
637     if (!wsUrls.equals(nwsUrls))
638     {
639       update++;
640     }
641     wsUrls = nwsUrls;
642     updateList();
643
644     updateAndRefreshWsMenuConfig(true);
645   }
646
647   protected void ok_ActionPerformed(ActionEvent e)
648   {
649     // update everything regardless.
650     updateAndRefreshWsMenuConfig(false);
651   }
652
653   public void updateAndRefreshWsMenuConfig(
654           final boolean showProgressInDialog)
655   {
656     new Thread(new Runnable()
657     {
658
659       public void run()
660       {
661         updateWsMenuConfig(false);
662         refreshWsMenu(showProgressInDialog);
663       }
664     }).start();
665
666   }
667 }