JAL-715 rsbs service editing
[jalview.git] / src / jalview / gui / WsPreferences.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
3  * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
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  */
18 package jalview.gui;
19
20 import java.awt.BorderLayout;
21 import java.awt.event.ActionEvent;
22 import java.awt.event.ActionListener;
23 import java.net.URL;
24 import java.util.Vector;
25
26 import javax.swing.JCheckBox;
27 import javax.swing.JLabel;
28 import javax.swing.JOptionPane;
29 import javax.swing.JPanel;
30 import javax.swing.JTextField;
31
32 import jalview.bin.Cache;
33 import jalview.jbgui.GWsPreferences;
34 import jalview.ws.rest.RestServiceDescription;
35
36 public class WsPreferences extends GWsPreferences
37 {
38
39   public WsPreferences()
40   {
41     super();
42     initFromPreferences();
43   }
44
45   Vector<String> wsUrls, oldUrls,rsbsUrls,oldRsbsUrls;
46
47   private boolean needWsMenuUpdate;
48
49   private boolean oldJws1, oldJws2, oldIndexByHost, oldIndexByType,
50           oldEnfin, oldWsWarning;
51
52   private void initFromPreferences()
53   {
54
55     wsUrls = jalview.ws.jws2.Jws2Discoverer.getServiceUrls();
56     if (wsUrls != null)
57     {
58       oldUrls = new Vector<String>(wsUrls);
59     }
60     else
61     {
62       oldUrls = null;
63       wsUrls = new Vector<String>();
64     }
65     updateList();
66     rsbsUrls = jalview.ws.rest.RestClient.getRsbsDescriptions();
67     if (rsbsUrls != null)
68     {
69       oldRsbsUrls = new Vector<String>(rsbsUrls);
70     }
71     else
72     {
73       oldRsbsUrls = null;
74       rsbsUrls = new Vector<String>();
75     }
76     updateRsbsList();
77     enableEnfinServices.setSelected(oldEnfin = Cache.getDefault(
78             "SHOW_ENFIN_SERVICES", true));
79     enableEnfinServices.addActionListener(updateAction);
80     enableJws1Services.setSelected(oldJws1 = Cache.getDefault(
81             "SHOW_JWS1_SERVICES", true));
82     enableJws1Services.addActionListener(updateAction);
83     enableJws2Services.setSelected(oldJws2 = Cache.getDefault(
84             "SHOW_JWS2_SERVICES", true));
85     enableJws2Services.addActionListener(updateAction);
86     indexByHost.setSelected(oldIndexByHost = Cache.getDefault(
87             "WSMENU_BYHOST", true));
88     indexByHost.addActionListener(updateAction);
89     indexByType.setSelected(oldIndexByType = Cache.getDefault(
90             "WSMENU_BYTYPE", true));
91     indexByType.addActionListener(updateAction);
92     displayWsWarning.setSelected(oldWsWarning = Cache.getDefault(
93             "SHOW_WSDISCOVERY_ERRORS", true));
94   }
95
96   ActionListener updateAction = new ActionListener()
97   {
98
99     @Override
100     public void actionPerformed(ActionEvent e)
101     {
102       update++;
103     }
104
105   };
106
107   private void updateList()
108   {
109     wsList.setListData(wsUrls);
110   }
111
112   private void updateRsbsList()
113   {
114     sbrsList.setListData(rsbsUrls);
115   }
116
117   private void updateServiceList()
118   {
119     jalview.ws.jws2.Jws2Discoverer.setServiceUrls(wsUrls);
120   }
121
122   private void updateRsbsServiceList()
123   {
124     jalview.ws.rest.RestClient.setRsbsServices(rsbsUrls);
125   }
126
127   /*
128    * (non-Javadoc)
129    * 
130    * @see
131    * jalview.jbgui.GWsPreferences#deleteWsUrl_actionPerformed(java.awt.event
132    * .ActionEvent)
133    */
134   @Override
135   protected void deleteWsUrl_actionPerformed(ActionEvent e)
136   {
137     int sel = wsList.getSelectedIndex();
138     if (sel > -1)
139     {
140       wsUrls.removeElementAt(sel);
141       update++;
142       updateList();
143     }
144   }
145
146   /*
147    * (non-Javadoc)
148    * 
149    * @see jalview.jbgui.GWsPreferences#editWsUrl_actionPerformed(java.awt.event.
150    * ActionEvent)
151    */
152   @Override
153   protected void editWsUrl_actionPerformed(ActionEvent e)
154   {
155     int sel = wsList.getSelectedIndex();
156     if (sel > -1)
157     {
158       String url = editUrl(wsUrls.elementAt(sel), "Edit JABAWS URL");
159       if (url != null)
160       {
161         int present = wsUrls.indexOf(url);
162         if (present == -1)
163         {
164           update++;
165           wsUrls.setElementAt(url, sel);
166           updateList();
167         }
168         else
169         {
170           if (present != sel)
171           {
172             wsUrls.removeElementAt(sel);
173             updateList();
174           }
175         }
176       }
177     }
178   }
179   @Override
180   protected void newSbrsUrl_actionPerformed(ActionEvent e)
181   {
182     RestServiceEditorPane rse = new RestServiceEditorPane();
183     rse.showDialog("Add a new Simple Bioinformatics Rest Service");
184     String rservice = rse.getEditedRestService();
185     if (rservice!=null && !rsbsUrls.contains(rservice))
186     {
187       rsbsUrls.add(rservice);
188       update++;
189       updateRsbsList();
190     }
191   }
192   @Override
193   protected void editSbrsUrl_actionPerformed(ActionEvent e)
194   {
195     int sel = sbrsList.getSelectedIndex();
196     if (sel > -1)
197     {
198       RestServiceEditorPane rse = new RestServiceEditorPane(new RestServiceDescription(rsbsUrls.elementAt(sel)));
199       rse.showDialog("Edit Simple Bioinformatics Rest Service entry");
200       String rservice = rse.getEditedRestService();
201       if (rservice!=null)
202       {
203         int present = rsbsUrls.indexOf(rservice);
204         if (present==-1) {
205           update++;
206           rsbsUrls.setElementAt(rservice,sel);
207           updateRsbsList();
208         } else {
209           if (present!=sel) {
210             rsbsUrls.removeElementAt(sel);
211             update++;
212             updateRsbsList();
213           }
214         }
215       }
216     }
217   }
218   
219   void updateWsMenuConfig(boolean old)
220   {
221     if (old)
222     {
223       if (oldUrls!=wsUrls || (wsUrls!=null && oldUrls!=null && !wsUrls.equals(oldUrls)))
224       {
225         update++;
226       }
227       wsUrls = (oldUrls == null) ? null : new Vector(oldUrls);
228       if (oldRsbsUrls!=rsbsUrls || (rsbsUrls!=null && oldRsbsUrls!=null && !oldRsbsUrls.equals(rsbsUrls)))
229       {
230         update++;
231       }
232       oldRsbsUrls = (oldRsbsUrls == null) ? null : new Vector(oldRsbsUrls);
233     }
234     else
235     {
236
237     }
238     Cache.setProperty(
239             "SHOW_ENFIN_SERVICES",
240             Boolean.valueOf(
241                     old ? oldEnfin : enableEnfinServices.isSelected())
242                     .toString());
243     Cache.setProperty(
244             "SHOW_JWS1_SERVICES",
245             Boolean.valueOf(old ? oldJws1 : enableJws1Services.isSelected())
246                     .toString());
247     Cache.setProperty(
248             "SHOW_JWS2_SERVICES",
249             Boolean.valueOf(old ? oldJws2 : enableJws2Services.isSelected())
250                     .toString());
251     Cache.setProperty(
252             "WSMENU_BYHOST",
253             Boolean.valueOf(old ? oldIndexByHost : indexByHost.isSelected())
254                     .toString());
255     Cache.setProperty(
256             "WSMENU_BYTYPE",
257             Boolean.valueOf(old ? oldIndexByType : indexByType.isSelected())
258                     .toString());
259     
260     Cache.setProperty("SHOW_WSDISCOVERY_ERRORS",
261             Boolean.valueOf(old ? oldWsWarning : displayWsWarning.isSelected()).toString());
262     updateServiceList();
263     updateRsbsServiceList();
264   }
265
266   /*
267    * (non-Javadoc)
268    * 
269    * @see
270    * jalview.jbgui.GWsPreferences#moveWsUrlDown_actionPerformed(java.awt.event
271    * .ActionEvent)
272    */
273   @Override
274   protected void moveWsUrlDown_actionPerformed(ActionEvent e)
275   {
276     int p = wsList.getSelectedIndex();
277     if (p > -1 && p < wsUrls.size() - 1)
278     {
279       String t = wsUrls.get(p + 1);
280       wsUrls.setElementAt(wsUrls.elementAt(p), p + 1);
281       wsUrls.setElementAt(t, p);
282       updateList();
283       wsList.setSelectedIndex(p + 1);
284       update++;
285     }
286   }
287
288   /*
289    * (non-Javadoc)
290    * 
291    * @see
292    * jalview.jbgui.GWsPreferences#moveWsUrlUp_actionPerformed(java.awt.event
293    * .ActionEvent)
294    */
295   @Override
296   protected void moveWsUrlUp_actionPerformed(ActionEvent e)
297   {
298     int p = wsList.getSelectedIndex();
299     if (p > 0)
300     {
301       String t = wsUrls.get(p - 1);
302       wsUrls.setElementAt(wsUrls.elementAt(p), p - 1);
303       wsUrls.setElementAt(t, p);
304       updateList();
305       wsList.setSelectedIndex(p - 1);
306       update++;
307     }
308   }
309
310   private String editUrl(String initUrl, String title)
311   {
312     String url = initUrl;
313     URL foo = null;
314     if (url == null)
315     {
316       url = "";
317     }
318     JTextField urltf = new JTextField(url, 40);
319     JPanel panel = new JPanel(new BorderLayout());
320     JPanel pane12 = new JPanel(new BorderLayout());
321     pane12.add(new JLabel("URL: "), BorderLayout.CENTER);
322     pane12.add(urltf, BorderLayout.EAST);
323     panel.add(pane12, BorderLayout.NORTH);
324     boolean valid = false;
325     int resp = JOptionPane.CANCEL_OPTION;
326     while (!valid
327             && (resp = JOptionPane.showInternalConfirmDialog(
328                     Desktop.desktop, panel, title,
329                     JOptionPane.OK_CANCEL_OPTION)) == JOptionPane.OK_OPTION)
330     {
331       try
332       {
333         // TODO: do a better job of checking that the url is a valid discovery
334         // URL for web services.
335         String tx = urltf.getText().trim();
336         while (tx.length()>0 && tx.lastIndexOf('/')==tx.length()-1)
337         {
338           tx = tx.substring(0, tx.length()-1);
339         }
340         foo = new URL(tx);
341         valid = true;
342         urltf.setText(tx);
343       } catch (Exception e)
344       {
345         valid = false;
346         JOptionPane.showInternalMessageDialog(Desktop.desktop,
347                 "Invalid URL !");
348       }
349     }
350     if (valid && resp == JOptionPane.OK_OPTION)
351     {
352       int validate = JOptionPane
353               .showInternalConfirmDialog(
354                       Desktop.desktop,
355                       "Validate JabaWS Server ?\n(Look in console output for results)",
356                       "Test Server?", JOptionPane.YES_NO_OPTION);
357       if (validate == JOptionPane.OK_OPTION)
358       {
359         if (jalview.ws.jws2.Jws2Discoverer.testServiceUrl(foo))
360         {
361           return foo.toString();
362         }
363         else
364         {
365           JOptionPane
366                   .showInternalMessageDialog(
367                           Desktop.desktop,
368                           "Service did not pass validation.\nCheck the Jalview Console for more details.");
369         }
370       }
371       else
372       {
373         // just return the URL anyway
374         return foo.toString();
375       }
376     }
377     return initUrl;
378   }
379
380   /*
381    * (non-Javadoc)
382    * 
383    * @see jalview.jbgui.GWsPreferences#newWsUrl_actionPerformed(java.awt.event.
384    * ActionEvent)
385    */
386   @Override
387   protected void newWsUrl_actionPerformed(ActionEvent e)
388   {
389     String url = editUrl(null, "Add new JABAWS URL");
390     if (url != null)
391     {
392       if (!wsUrls.contains(url))
393       {
394         int selind = wsList.getSelectedIndex();
395         if (selind > -1)
396         {
397           wsUrls.insertElementAt(url, selind);
398         }
399         else
400         {
401           wsUrls.addElement(url);
402         }
403         update++;
404         updateList();
405       }
406     }
407   }
408
409   /*
410    * (non-Javadoc)
411    * 
412    * @see jalview.jbgui.GWsPreferences#refreshWs_actionPerformed(java.awt.event.
413    * ActionEvent)
414    */
415   @Override
416   protected void refreshWs_actionPerformed(ActionEvent e)
417   {
418     new Thread(new Runnable()
419     {
420
421       public void run()
422       {
423         // force a refresh.
424         lastrefresh = update - 1;
425         updateWsMenuConfig(false);
426         refreshWsMenu(true);
427       }
428     }).start();
429
430   }
431
432   /**
433    * Refresh the web services menus - but only if there has been a change in the
434    * configuration (indicated by update!=lastrefresh)
435    * 
436    * @param showProgress
437    *          show progress in dialog or on desktop
438    */
439   protected void refreshWsMenu(boolean showProgress)
440   {
441     if (showProgress)
442     {
443       new Thread(new Runnable()
444       {
445
446         public void run()
447         {
448           progressBar.setVisible(true);
449           validate();
450           progressBar.setIndeterminate(true);
451           if (lastrefresh != update)
452           {
453             lastrefresh = update;
454             Desktop.instance.startServiceDiscovery(true); // wait around for all
455                                                           // threads to complete
456           }
457           progressBar.setIndeterminate(false);
458           progressBar.setVisible(false);
459           validate();
460         }
461       }).start();
462
463     }
464     else
465     {
466       new Thread(new Runnable()
467       {
468
469         public void run()
470         {
471           long ct = System.currentTimeMillis();
472           Desktop.instance.setProgressBar("Refreshing Web Service Menus",
473                   ct);
474           if (lastrefresh != update)
475           {
476             lastrefresh = update;
477             Desktop.instance.startServiceDiscovery(true);
478           }
479           Desktop.instance.setProgressBar(null, ct);
480         }
481
482       }).start();
483     }
484   }
485
486   /**
487    * state counters for ensuring that updates only happen if config has changed.
488    */
489   private long update = 0, lastrefresh = 0;
490
491   /*
492    * (non-Javadoc)
493    * 
494    * @see
495    * jalview.jbgui.GWsPreferences#resetWs_actionPerformed(java.awt.event.ActionEvent
496    * )
497    */
498   @Override
499   protected void resetWs_actionPerformed(ActionEvent e)
500   {
501     jalview.ws.jws2.Jws2Discoverer.setServiceUrls(null);
502     Vector nwsUrls = jalview.ws.jws2.Jws2Discoverer.getServiceUrls();
503     if (!wsUrls.equals(nwsUrls)) {
504       update++;
505     }
506     wsUrls=nwsUrls;
507     updateList();
508     
509     updateAndRefreshWsMenuConfig(true);
510   }
511
512   protected void ok_ActionPerformed(ActionEvent e)
513   {
514     // update everything regardless.
515     updateAndRefreshWsMenuConfig(false);
516   }
517
518   public void updateAndRefreshWsMenuConfig(
519           final boolean showProgressInDialog)
520   {
521     new Thread(new Runnable()
522     {
523
524       public void run()
525       {
526         updateWsMenuConfig(false);
527         refreshWsMenu(showProgressInDialog);
528       }
529     }).start();
530
531   }
532 }